AOC2022/day13/day13.go
2022-12-14 01:18:45 +01:00

281 lines
5.6 KiB
Go

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
}