2022-12-13 20:45:45 +01:00
package main
import (
"AOC2022/helper"
"fmt"
2022-12-14 01:18:45 +01:00
"reflect"
"sort"
2022-12-13 20:45:45 +01:00
"strconv"
)
2022-12-14 01:18:45 +01:00
type Packet struct {
value int
values [ ] Packet
}
2022-12-13 20:45:45 +01:00
func main ( ) {
//args := os.Args[1:]
2022-12-13 21:38:24 +01:00
lines := helper . ReadTextFile ( "day13/input" )
2022-12-14 01:18:45 +01:00
//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 ) {
2022-12-13 20:45:45 +01:00
index := 1
2022-12-14 01:18:45 +01:00
result := 0
2022-12-13 21:38:24 +01:00
for i := 0 ; i < len ( lines ) ; i += 3 {
2022-12-14 01:18:45 +01:00
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 )
2022-12-13 20:45:45 +01:00
result += index
}
index ++
}
fmt . Println ( result )
2022-12-14 01:18:45 +01:00
}
// 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 { } } } } )
2022-12-13 20:45:45 +01:00
2022-12-14 01:18:45 +01:00
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
2022-12-13 20:45:45 +01:00
}
2022-12-13 21:38:24 +01:00
// 0 Right Order
2022-12-14 01:18:45 +01:00
//-1 Left Value too high
2022-12-13 21:38:24 +01:00
//-2 Right had no values left
func comparePair ( left string , right string ) int {
2022-12-13 21:57:48 +01:00
lefIndex := 0
rightIndex := 0
2022-12-13 20:45:45 +01:00
currentElemLeft := 0
currentElemRight := 0
2022-12-13 21:38:24 +01:00
leftElementType := 0
rightElementType := 0
2022-12-13 20:45:45 +01:00
for lefIndex < len ( left ) - 1 {
2022-12-13 21:38:24 +01:00
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 )
2022-12-13 21:57:48 +01:00
if leftElementType == - 1 || leftElementType == - 3 {
2022-12-13 21:38:24 +01:00
return - 2
}
}
2022-12-13 20:45:45 +01:00
}
2022-12-13 21:38:24 +01:00
}
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
}
2022-12-13 20:45:45 +01:00
}
currentElemLeft , lefIndex = readElement ( left , lefIndex )
currentElemRight , rightIndex = readElement ( right , rightIndex )
if currentElemLeft > currentElemRight {
2022-12-13 21:38:24 +01:00
return - 1
2022-12-13 20:45:45 +01:00
}
if currentElemLeft < currentElemRight {
2022-12-13 21:38:24 +01:00
return 0
2022-12-13 20:45:45 +01:00
}
}
}
2022-12-13 21:38:24 +01:00
return 0
2022-12-13 20:45:45 +01:00
}
// 0 Element
//-1 End Packet
//-2 Start Array
//-3 End Array
2022-12-13 21:57:48 +01:00
//-4 Seperator
2022-12-13 20:45:45 +01:00
func getNextElement ( packet string , currentIndex int ) ( int , int ) {
2022-12-13 21:38:24 +01:00
index := currentIndex + 1
2022-12-13 20:45:45 +01:00
for index < len ( packet ) {
switch packet [ index ] {
case ',' :
2022-12-14 01:18:45 +01:00
return index , - 4
2022-12-13 20:45:45 +01:00
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
2022-12-13 21:38:24 +01:00
openedArrays := 1
for openedArrays > 0 && index < len ( packet ) {
switch packet [ index ] {
case ']' :
openedArrays --
case '[' :
openedArrays ++
2022-12-13 20:45:45 +01:00
}
index ++
}
2022-12-13 21:38:24 +01:00
if openedArrays == 0 {
return index
} else {
return - 1
}
2022-12-13 20:45:45 +01:00
}
2022-12-14 01:18:45 +01:00
func getEndofCurrentValue ( packet string , currentIndex int ) int {
index := currentIndex
for index < len ( packet ) {
if packet [ index ] == ',' {
return index
}
index ++
}
return index
}
2022-12-13 20:45:45 +01:00
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 ++
}
}
2022-12-13 21:38:24 +01:00
return helper . RemoveError ( strconv . Atoi ( packet [ currentIndex : newIndex ] ) ) , newIndex - 1
2022-12-13 20:45:45 +01:00
}