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) }