diff options
Diffstat (limited to 'day5/main.go')
-rw-r--r-- | day5/main.go | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/day5/main.go b/day5/main.go new file mode 100644 index 0000000..1dd1672 --- /dev/null +++ b/day5/main.go @@ -0,0 +1,113 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "slices" + "sort" + "strconv" + "strings" +) + +func main() { + fmt.Println(doTheThing("example.txt")) + fmt.Println(doTheThing("data.txt")) +} + +func fill[T any](s []T, value T) { + for i := range s { + s[i] = value + } +} + +func doTheThing(fileName string) (resultPart1, resultPart2 int) { + fp, err := os.Open(fileName) + if err != nil { + panic(err) + } + + scanner := bufio.NewScanner(fp) + forbiddenAfter := readForbiddenAfter(scanner) + seen := make([]bool, 100) + forbidden := make([]bool, 100) + + for scanner.Scan() { + seq := readLine(strings.TrimSpace(scanner.Text())) + fill(seen, false) + fill(forbidden, false) + + ok := true + + for _, n := range seq { + if seen[n] { + continue + } + + if forbidden[n] { + ok = false + break + } + + for _, f := range forbiddenAfter[n] { + forbidden[f] = true + } + + seen[n] = true + } + + if ok { + resultPart1 += seq[len(seq)/2] + } else { + sort.Slice(seq, func(i, j int) bool { + return slices.Index(forbiddenAfter[seq[j]], seq[i]) != -1 + }) + resultPart2 += seq[len(seq)/2] + } + } + + return +} + +func readLine(s string) (line []int) { + split := strings.Split(s, ",") + line = make([]int, len(split)) + for i, num := range split { + n, err := strconv.Atoi(num) + if err != nil { + panic(err) + } + line[i] = n + } + return +} + +func readForbiddenAfter(scanner *bufio.Scanner) (forbiddenAfter map[int][]int) { + forbiddenAfter = make(map[int][]int) + + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if len(line) == 0 { + return + } + + split := strings.Split(line, "|") + if len(split) != 2 { + panic("Not enough data for ordering") + } + + a, err := strconv.Atoi(split[0]) + if err != nil { + panic(err) + } + + b, err := strconv.Atoi(split[1]) + if err != nil { + panic(err) + } + + forbiddenAfter[b] = append(forbiddenAfter[b], a) + } + + return +} |