mirror of
https://github.com/Threnklyn/advent-of-code-go.git
synced 2026-05-19 03:23:27 +02:00
76 lines
1.9 KiB
Go
76 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"math"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/alexchao26/advent-of-code-go/cast"
|
|
"github.com/alexchao26/advent-of-code-go/util"
|
|
)
|
|
|
|
func main() {
|
|
var part int
|
|
flag.IntVar(&part, "part", 1, "part 1 or 2")
|
|
flag.Parse()
|
|
fmt.Println("Running part", part)
|
|
|
|
ans := someAssemblyRequired(util.ReadFile("./input.txt"), part)
|
|
fmt.Println("Output:", ans)
|
|
}
|
|
|
|
func someAssemblyRequired(input string, part int) int {
|
|
wireToRule := map[string]string{}
|
|
|
|
// generate graph of wires to their source rule
|
|
for _, inst := range strings.Split(input, "\n") {
|
|
parts := strings.Split(inst, " -> ")
|
|
wireToRule[parts[1]] = parts[0]
|
|
}
|
|
|
|
aSignal := memoDFS(wireToRule, "a", map[string]int{})
|
|
if part == 1 {
|
|
return aSignal
|
|
}
|
|
|
|
// for part 2, override the value sent to wire b, then get output to a again
|
|
wireToRule["b"] = cast.ToString(aSignal)
|
|
return memoDFS(wireToRule, "a", map[string]int{})
|
|
}
|
|
|
|
func memoDFS(graph map[string]string, entry string, memo map[string]int) int {
|
|
if memoVal, ok := memo[entry]; ok {
|
|
return memoVal
|
|
}
|
|
|
|
// if it's a number, return the casted value
|
|
if regexp.MustCompile("[0-9]").MatchString(entry) {
|
|
return cast.ToInt(entry)
|
|
}
|
|
|
|
sourceRule := graph[entry]
|
|
parts := strings.Split(sourceRule, " ")
|
|
|
|
var result int
|
|
switch {
|
|
case len(parts) == 1:
|
|
result = memoDFS(graph, parts[0], memo)
|
|
case parts[0] == "NOT":
|
|
start := memoDFS(graph, parts[1], memo)
|
|
result = (math.MaxUint16) ^ start
|
|
case parts[1] == "AND":
|
|
result = memoDFS(graph, parts[0], memo) & memoDFS(graph, parts[2], memo)
|
|
case parts[1] == "OR":
|
|
result = memoDFS(graph, parts[0], memo) | memoDFS(graph, parts[2], memo)
|
|
case parts[1] == "LSHIFT":
|
|
result = memoDFS(graph, parts[0], memo) << memoDFS(graph, parts[2], memo)
|
|
case parts[1] == "RSHIFT":
|
|
result = memoDFS(graph, parts[0], memo) >> memoDFS(graph, parts[2], memo)
|
|
}
|
|
|
|
memo[entry] = result
|
|
return result
|
|
}
|