aoc2024/day-24/internal/one/solve.go
2024-12-25 14:46:40 +00:00

65 lines
1.4 KiB
Go

package one
import (
"bytes"
"cmp"
"slices"
"strconv"
"strings"
log "github.com/sirupsen/logrus"
)
func Solve(buf []byte) (int, error) {
r := bytes.NewReader(buf)
initial, wires, expressions, err := parseLines(r)
if err != nil {
return 0, err
}
for k, v := range initial {
wires[k] = v
}
wires = calculateWire(expressions, wires)
zWires := []zWire{}
for k, v := range wires {
if strings.HasPrefix(k, "z") {
zWires = append(zWires, zWire{k, v})
}
}
slices.SortFunc(zWires, func(a, b zWire) int {
return cmp.Compare(b.name, a.name)
})
var binStr strings.Builder
for _, zWire := range zWires {
binStr.WriteString(strconv.FormatInt(int64(zWire.value), 2))
}
log.Debug(binStr.String())
return mustConvBinToDec(binStr.String()), nil
}
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)
}