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 }