aoc2024/day-24/internal/one/solve.go

51 lines
1.1 KiB
Go
Raw Normal View History

2024-12-25 14:46:40 +00:00
package one
import (
"bytes"
2024-12-26 13:27:58 +00:00
"math"
2024-12-26 13:12:48 +00:00
"sort"
2024-12-25 14:46:40 +00:00
"strings"
)
func Solve(buf []byte) (int, error) {
r := bytes.NewReader(buf)
2024-12-26 13:12:48 +00:00
wires, expressions, err := parseLines(r)
2024-12-25 14:46:40 +00:00
if err != nil {
return 0, err
}
wires = calculateWire(expressions, wires)
2024-12-26 13:12:48 +00:00
zWires := filter(wires, func(name string) bool {
return strings.HasPrefix(name, "z")
2024-12-25 14:46:40 +00:00
})
2024-12-26 13:12:48 +00:00
sort.Sort(byName(zWires))
2024-12-25 14:46:40 +00:00
2024-12-26 13:27:58 +00:00
var decimal int
for i, zWire := range zWires {
decimal += zWire.value * int(math.Pow(float64(2), float64(i)))
2024-12-25 14:46:40 +00:00
}
2024-12-26 13:27:58 +00:00
return decimal, nil
2024-12-25 14:46:40 +00:00
}
func calculateWire(expressions []expression, wires map[string]int) map[string]int {
if !anyNegative(wires) {
return wires
}
for _, expression := range expressions {
if wires[expression.left] != noValue && wires[expression.right] != noValue {
switch expression.op {
case AND:
wires[expression.target] = wires[expression.left] & wires[expression.right]
case OR:
wires[expression.target] = wires[expression.left] | wires[expression.right]
case XOR:
wires[expression.target] = wires[expression.left] ^ wires[expression.right]
}
}
}
return calculateWire(expressions, wires)
}