From 46859764ad4073da2c910ebd321320e1edb9b8c6 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Tue, 24 Dec 2024 23:57:15 +0100 Subject: Fucking day 24 --- day24/main.go | 256 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 day24/main.go (limited to 'day24/main.go') diff --git a/day24/main.go b/day24/main.go new file mode 100644 index 0000000..3d5e89a --- /dev/null +++ b/day24/main.go @@ -0,0 +1,256 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "sort" + "strings" +) + +func main() { + fmt.Println(part1(readData("example_simple.txt")), 4) + fmt.Println(part1(readData("example.txt")), 2024) + fmt.Println(part1(readData("data.txt")), 49574189473968) + // fmt.Println(part2(readData("data.txt").gates)) + fmt.Println(part2(readData("data-2.txt").gates)) + +} + +const ( + AND = "AND" + OR = "OR" + XOR = "XOR" +) + +type Gate struct { + op string + a, b string +} + +type Circuit struct { + values map[string]bool + gates map[string]Gate +} + +func part1(input Circuit) (result uint64) { + queue := []string{} + for output := range input.gates { + queue = append(queue, output) + } + + for len(queue) > 0 { + output := queue[len(queue)-1] + if _, alreadyComputed := input.values[output]; alreadyComputed { + queue = queue[:len(queue)-1] + continue + } + + gate := input.gates[output] + valueA, okA := input.values[gate.a] + valueB, okB := input.values[gate.b] + + if !okA || !okB { + if !okA { + queue = append(queue, gate.a) + } + if !okB { + queue = append(queue, gate.b) + } + } else { + input.values[output] = evaluate(gate.op, valueA, valueB) + queue = queue[:len(queue)-1] + } + } + + zWires := []string{} + for wire := range input.values { + if wire[0] == 'z' { + zWires = append(zWires, wire) + } + } + + sort.Sort(sort.Reverse(sort.StringSlice(zWires))) + + for _, w := range zWires { + if input.values[w] { + result = result<<1 | 1 + } else { + result = result << 1 + } + } + + return +} + +func evaluate(op string, a, b bool) bool { + switch op { + case AND: + return a && b + case OR: + return a || b + case XOR: + return a != b + default: + panic("unknown operator") + } +} + +func name(prefix byte, num int) string { + a := byte(num%10 + '0') + b := byte(num/10 + '0') + return string([]byte{prefix, b, a}) +} + +func evaluateAdder(gates map[string]Gate, a, b uint64) uint64 { + circuit := Circuit{gates: gates, values: make(map[string]bool)} + for i := range 50 { + x := a&(uint64(1)<", tmpz0) + // z := findGate(Gate{XOR, tmpz0, carry[i-1]}) + // if z[0] == 'z' { + // fmt.Println("z", i, tmpz0, carry[i-1], "->", z) + // } else { + // fmt.Println("oh no") + // } + // } else if tmpz0 := findGate(Gate{XOR, name('x', i), carry[i-1]}); tmpz0 != "" { + // fmt.Println("tmpz0", i, name('x', i), carry[i-1], "->", tmpz0) + // } else if tmpz0 := findGate(Gate{XOR, name('y', i), carry[i-1]}); tmpz0 != "" { + // fmt.Println("tmpz0", i, name('y', i), carry[i-1], "->", tmpz0) + // } + // } + + // // for output, g := range gates { + + // // } + + return "" +} + +func readData(fileName string) (data Circuit) { + data = Circuit{ + values: make(map[string]bool), + gates: make(map[string]Gate), + } + + fp, _ := os.Open(fileName) + scanner := bufio.NewScanner(fp) + + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if len(line) == 0 { + break + } + + wire := line[0:3] + value := line[5] == '1' + + data.values[wire] = value + } + + for scanner.Scan() { + line := strings.Split(strings.TrimSpace(scanner.Text()), " ") + data.gates[line[4]] = Gate{line[1], line[0], line[2]} + } + + return +} -- cgit