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

91 lines
1.5 KiB
Go

package one
import (
"bufio"
"io"
"strconv"
"strings"
)
const (
left = iota * 2
right
target
)
func parseLines(r io.Reader) (map[string]int, []expression, error) {
initial := make(map[string]int)
wires := make(map[string]int)
expressions := []expression{}
var inGates bool
scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := scanner.Text()
if line == "" {
inGates = true
continue
}
if inGates {
parts := strings.Split(line, " ")
wires[parts[left]] = noValue
wires[parts[right]] = noValue
wires[parts[target]] = noValue
var op rune
switch parts[1] {
case "AND":
op = AND
case "OR":
op = OR
case "XOR":
op = XOR
}
expressions = append(expressions, newExpression(parts[left], parts[right], parts[target], op))
} else {
parts := strings.Split(line, ": ")
initial[parts[0]] = mustConv(parts[1])
}
}
if err := scanner.Err(); err != nil {
return nil, nil, err
}
for k, v := range initial {
wires[k] = v
}
return wires, expressions, nil
}
func mustConv(s string) int {
n, err := strconv.Atoi(s)
if err != nil {
panic(err)
}
return n
}
func anyNegative(wires map[string]int) bool {
for _, v := range wires {
if v == -1 {
return true
}
}
return false
}
func filter(wires map[string]int, fn func(string) bool) []zWire {
var filtered []zWire
for name, value := range wires {
if fn(name) {
filtered = append(filtered, zWire{name, value})
}
}
return filtered
}