Day - 13
Part 1 - Code
package main
import (
"bufio"
"fmt"
"log"
"os"
"sort"
"strconv"
"strings"
)
var year = 2022
var day = 13
var path = os.Getenv("ADVENT_HOME")
const (
_ = iota
RIGHT_ORDER
WRONG_ORDER
CONTINUE
)
func printEnum(i int) string {
if i == RIGHT_ORDER {
return "RIGHT_ORDER"
}
if i == WRONG_ORDER {
return "WRONG_ORDER"
}
return "CONTINUE"
}
func splitList(str string) []string {
count := 0
commas := []int{}
for i, r := range str {
if string(r) == "[" {
count += 1
}
if string(r) == "]" {
count -= 1
}
if string(r) == "," {
if count == 0 {
commas = append(commas, i)
}
}
}
output := []string{}
i := 0
for _, indexOfComma := range commas {
sub := str[i:indexOfComma]
output = append(output, sub)
i = indexOfComma + 1
}
output = append(output, str[i:])
return output
}
func getValues(str string) []string {
val := strings.TrimPrefix(str, "[")
val = strings.TrimSuffix(val, "]")
vals := splitList(val)
out := []string{}
for _, v := range vals {
if len(strings.TrimSpace(v)) > 0 {
out = append(out, v)
}
}
return out
}
func isList(str string) bool {
return len(str) >= 2 && strings.HasPrefix(str, "[") && strings.HasSuffix(str, "]")
}
func isNumber(str string) bool {
_, err := strconv.Atoi(str)
return err == nil
}
func wrapAsList(str string) string {
return "[" + str + "]"
}
func compareValues(left string, right string) int {
if isNumber(left) && isNumber(right) {
lVal, _ := strconv.Atoi(left)
rVal, _ := strconv.Atoi(right)
if lVal < rVal {
return RIGHT_ORDER
} else if lVal > rVal {
return WRONG_ORDER
} else {
return CONTINUE
}
} else if isList(left) && isList(right) {
return compareList(left, right)
} else {
nLeft, nRight := left, right
if isNumber(nLeft) {
nLeft = wrapAsList(nLeft)
}
if isNumber(nRight) {
nRight = wrapAsList(nRight)
}
return compareList(nLeft, nRight)
}
}
func compareList(left string, right string) int {
leftVals := getValues(left)
rightVals := getValues(right)
l := len(leftVals)
r := len(rightVals)
// fmt.Printf("compareList %s ||| %s\n", leftVals, rightVals)
i := 0
if l == 0 && r > 0 {
return RIGHT_ORDER
}
if l > 0 && r == 0 {
return WRONG_ORDER
}
for i < l && i < r {
val := compareValues(leftVals[i], rightVals[i])
if val == RIGHT_ORDER || val == WRONG_ORDER {
return val
}
i++
}
if i == l && i == r {
return CONTINUE
}
if i == l && i < r {
return RIGHT_ORDER
}
return WRONG_ORDER
}
func isRightOrder(left string, right string) (bool, int) {
output := compareList(left, right)
return output == RIGHT_ORDER, output
}
func main() {
dataPath := fmt.Sprintf("%s/%d/data/day%d/data.txt", path, year, day)
fmt.Println(dataPath)
file, err := os.Open(dataPath)
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
data := []string{}
for scanner.Scan() {
line := scanner.Text()
line = strings.TrimSpace(line)
if len(line) > 0 {
data = append(data, scanner.Text())
}
}
acc := 0
count := 1
for i := 0; i < len(data); i += 2 {
msg := data[i]
test := data[i+1]
ok, _ := isRightOrder(msg, test)
if ok {
acc += count
}
count += 1
}
fmt.Printf("sum = %d\n", acc)
// part 2
// add divider tokens
LEFT_DIV := "[[2]]"
RIGHT_DIV := "[[6]]"
data = append(data, LEFT_DIV)
data = append(data, RIGHT_DIV)
sort.Slice(data, func(i, j int) bool {
seqI := data[i]
seqJ := data[j]
ok, _ := isRightOrder(seqI, seqJ)
return ok
})
ld := 0
rd := 0
for i := 0; i < len(data); i++ {
if data[i] == LEFT_DIV {
ld = i
}
if data[i] == RIGHT_DIV {
rd = i
}
}
// shift for 1st based index
rd++
ld++
fmt.Printf("decoderKey (ld,rd)=(%d,%d) = %d\n", ld, rd, ld*rd)
}