2024-12-25 14:46:40 +00:00
|
|
|
package one
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2024-12-26 13:12:48 +00:00
|
|
|
"sort"
|
2024-12-25 14:46:40 +00:00
|
|
|
"strconv"
|
|
|
|
"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
|
|
|
|
|
|
|
var binStr strings.Builder
|
|
|
|
for _, zWire := range zWires {
|
2024-12-26 13:12:48 +00:00
|
|
|
binStr.WriteString(strconv.Itoa(zWire.value))
|
2024-12-25 14:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
}
|