package main import ( "AOC2022/helper" "fmt" "reflect" "sort" "strconv" ) type Packet struct { value int values []Packet } func main() { //args := os.Args[1:] lines := helper.ReadTextFile("day13/input") //part1(lines) decodePacket2 := parse("[[2]]") decodePacket6 := parse("[[6]]") packets := []Packet{} for i := 0; i < len(lines); i += 3 { packets = append(packets, parse(lines[i])) packets = append(packets, parse(lines[i+1])) } packets = append(packets, decodePacket2) packets = append(packets, decodePacket6) sort.Slice(packets, func(i, j int) bool { result := compare(packets[i], packets[j]) if result == 0 { return true } return false }) result := 1 for i, packet := range packets { if reflect.DeepEqual(packet, decodePacket2) { result *= i + 1 fmt.Println(2) fmt.Println(i + 1) } if reflect.DeepEqual(packet, decodePacket6) { result *= i + 1 fmt.Println(6) fmt.Println(i + 1) } } fmt.Println(result) } func part1(lines []string) { index := 1 result := 0 for i := 0; i < len(lines); i += 3 { left := parse(lines[i][1 : len(lines[i])-1]) right := parse(lines[i+1][1 : len(lines[i+1])-1]) if compare(left, right) == 0 { fmt.Println(index) result += index } index++ } fmt.Println(result) } // 2 same // 1 left higher // 0 left lower func compare(left, right Packet) int { if left.value != -1 && right.value != -1 { if left.value < right.value { return 0 } if left.value > right.value { return 1 } if left.value == right.value { return 2 } } if left.value == -1 && right.value == -1 { for i := 0; i < len(left.values); i++ { if !(i < len(right.values)) { return 1 } result := compare(left.values[i], right.values[i]) if result == 0 { return 0 } if result == 1 { return 1 } } if len(right.values) > len(left.values) { return 0 } return 2 } if left.value != -1 { result := compare(Packet{value: -1, values: []Packet{{value: left.value, values: []Packet{}}}}, right) if result == 0 { return 0 } if result == 1 { return 1 } } if right.value != -1 { result := compare(left, Packet{value: -1, values: []Packet{{value: right.value, values: []Packet{}}}}) if result == 0 { return 0 } if result == 1 { return 1 } } return 2 } func parse(input string) Packet { packet := Packet{-1, []Packet{}} for i := 0; i < len(input); { switch input[i] { case '[': endOfCurrentArray := getEndofCurrentArray(input[1:], i) currentArray := input[i+1 : endOfCurrentArray] packet.values = append(packet.values, parse(currentArray)) i = endOfCurrentArray + 1 case ',': i++ default: endOfCurrentValue := getEndofCurrentValue(input, i) currentValue := helper.RemoveError(strconv.Atoi(input[i:endOfCurrentValue])) packet.values = append(packet.values, Packet{value: currentValue, values: []Packet{}}) i = endOfCurrentValue + 1 } } return packet } // 0 Right Order //-1 Left Value too high //-2 Right had no values left func comparePair(left string, right string) int { lefIndex := 0 rightIndex := 0 currentElemLeft := 0 currentElemRight := 0 leftElementType := 0 rightElementType := 0 for lefIndex < len(left)-1 { lefIndex, leftElementType = getNextElement(left, lefIndex) rightIndex, rightElementType = getNextElement(right, rightIndex) if leftElementType == -1 { return 0 } if leftElementType == -2 { for rightElementType != -2 && rightElementType != 0 { rightIndex, rightElementType = getNextElement(right, rightIndex) if rightElementType == -1 { return -2 } } if rightElementType == 0 { for leftElementType != 0 { lefIndex, leftElementType = getNextElement(left, lefIndex) if leftElementType == -1 || leftElementType == -3 { return -2 } } } } if leftElementType == -3 { rightIndex = getEndofCurrentArray(right, rightIndex) rightElementType = -3 } if leftElementType == 0 { for rightElementType != 0 { rightIndex, rightElementType = getNextElement(right, rightIndex) if rightElementType == -1 || rightElementType == -3 { return -2 } } currentElemLeft, lefIndex = readElement(left, lefIndex) currentElemRight, rightIndex = readElement(right, rightIndex) if currentElemLeft > currentElemRight { return -1 } if currentElemLeft < currentElemRight { return 0 } } } return 0 } // 0 Element //-1 End Packet //-2 Start Array //-3 End Array //-4 Seperator func getNextElement(packet string, currentIndex int) (int, int) { index := currentIndex + 1 for index < len(packet) { switch packet[index] { case ',': return index, -4 break case '[': return index, -2 break case ']': if index < len(packet)-1 { return index, -3 } else { index++ } break default: return index, 0 } } return index, -1 } func getEndofCurrentArray(packet string, currentIndex int) int { index := currentIndex openedArrays := 1 for openedArrays > 0 && index < len(packet) { switch packet[index] { case ']': openedArrays-- case '[': openedArrays++ } index++ } if openedArrays == 0 { return index } else { return -1 } } func getEndofCurrentValue(packet string, currentIndex int) int { index := currentIndex for index < len(packet) { if packet[index] == ',' { return index } index++ } return index } func readElement(packet string, currentIndex int) (element, newIndex int) { index := currentIndex newIndex = 0 for newIndex == 0 { switch packet[index] { case ',': newIndex = index break case ']': newIndex = index break default: index++ } } return helper.RemoveError(strconv.Atoi(packet[currentIndex:newIndex])), newIndex - 1 }