package common import ( "bufio" "strconv" ) type Packet interface { Compare(Packet) int ToList() ListPacket IsSeparator() bool } type IntPacket int func (packet IntPacket) Compare(other Packet) int { if otherInt, ok := other.(IntPacket); ok { if packet < otherInt { return -1 } else if packet > otherInt { return 1 } else { return 0 } } else { otherList, _ := other.(ListPacket) return packet.ToList().Compare(otherList) } } func (packet IntPacket) ToList() ListPacket { return ListPacket{[]Packet{packet}, false} } func (packet IntPacket) IsSeparator() bool { return false } type ListPacket struct { content []Packet separator bool } func (packet ListPacket) Compare(other Packet) int { otherList := other.ToList() comparisonRes := 0 for i := 0; comparisonRes == 0; i++ { if i == len(packet.content) && i == len(otherList.content) { break } else if i == len(packet.content) { comparisonRes = -1 } else if i == len(otherList.content) { comparisonRes = 1 } else { comparisonRes = packet.content[i].Compare(otherList.content[i]) } } return comparisonRes } func (packet ListPacket) ToList() ListPacket { return packet } func (packet ListPacket) IsSeparator() bool { return packet.separator } type Pair struct { first Packet second Packet } func (pair Pair) CheckOrder() bool { return pair.first.Compare(pair.second) < 0 } func ParseListPacket(listString string) ListPacket { packet := ListPacket{[]Packet{}, false} currI := 1 for i := 1; i < len(listString); i++ { if listString[i] == ',' || listString[i] == ']' { if listString[currI] >= '0' && listString[currI] <= '9' { convertedInt, _ := strconv.Atoi(listString[currI:i]) packet.content = append(packet.content, IntPacket(convertedInt)) } else if listString[currI] == '[' { depth := 1 var j int for j = currI + 1; depth != 0; j++ { if listString[j] == '[' { depth++ } else if listString[j] == ']' { depth-- } } packet.content = append(packet.content, ParseListPacket(listString[currI:j])) i = j } currI = i + 1 } } return packet } func ParsePairs(scanner bufio.Scanner) []Pair { pairs := []Pair{} current := make([]Packet, 0, 2) for scanner.Scan() { line := scanner.Text() if line == "" { pairs = append(pairs, Pair{current[0], current[1]}) current = make([]Packet, 0, 2) } else { current = append(current, ParseListPacket(line)) } } return append(pairs, Pair{current[0], current[1]}) } func ParsePackets(scanner bufio.Scanner, separators []string) []Packet { packets := []Packet{} for scanner.Scan() { line := scanner.Text() if line != "" { packets = append(packets, ParseListPacket(line)) } } for _, separator := range separators { separatorPacket := ParseListPacket(separator) separatorPacket.separator = true packets = append(packets, separatorPacket) } return packets }