2024 Day 24 complete
Part 2 solved manually, working on a programmatic solution
This commit is contained in:
192
2024/day24/main.go
Normal file
192
2024/day24/main.go
Normal file
@@ -0,0 +1,192 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToStringSlice()
|
||||
part1(inp)
|
||||
fmt.Println()
|
||||
part2(inp)
|
||||
}
|
||||
|
||||
func part1(inp []string) {
|
||||
fmt.Println("# Part 1")
|
||||
dev, gates := parseInput1(inp)
|
||||
// Perform all logic
|
||||
gateDone := make(map[int]bool)
|
||||
for len(gateDone) != len(gates)-1 {
|
||||
for i := range gates {
|
||||
if _, ok := gateDone[i]; !ok {
|
||||
pts := strings.Split(gates[i], " ")
|
||||
var w1, w2, ok bool
|
||||
if w1, ok = dev[pts[0]]; ok {
|
||||
if w2, ok = dev[pts[2]]; ok {
|
||||
switch pts[1] {
|
||||
case "AND":
|
||||
dev[pts[4]] = w1 && w2
|
||||
case "OR":
|
||||
dev[pts[4]] = w1 || w2
|
||||
case "XOR":
|
||||
dev[pts[4]] = w1 != w2
|
||||
}
|
||||
gateDone[i] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println(findValueOf(dev, "z"))
|
||||
}
|
||||
|
||||
// Not fully working yet... I solved this part manually.
|
||||
func part2(inp []string) {
|
||||
fmt.Println("# Part 2")
|
||||
gates := parseInput2(inp)[1]
|
||||
|
||||
var swapped []string
|
||||
var c0 string
|
||||
|
||||
for i := 0; i < 45; i++ {
|
||||
n := fmt.Sprintf("%02d", i)
|
||||
var m1, n1, r1, z1, c1 string
|
||||
|
||||
m1 = find("x"+n, "y"+n, "XOR", gates)
|
||||
n1 = find("x"+n, "y"+n, "AND", gates)
|
||||
|
||||
if c0 != "" {
|
||||
r1 = find(c0, m1, "AND", gates)
|
||||
if r1 == "" {
|
||||
m1, n1 = n1, m1
|
||||
swapped = append(swapped, m1, n1)
|
||||
r1 = find(c0, m1, "AND", gates)
|
||||
}
|
||||
|
||||
z1 = find(c0, m1, "XOR", gates)
|
||||
|
||||
if strings.HasPrefix(m1, "z") {
|
||||
m1, z1 = z1, m1
|
||||
swapped = append(swapped, m1, z1)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(n1, "z") {
|
||||
n1, z1 = z1, n1
|
||||
swapped = append(swapped, n1, z1)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(r1, "z") {
|
||||
r1, z1 = z1, r1
|
||||
swapped = append(swapped, r1, z1)
|
||||
}
|
||||
|
||||
c1 = find(r1, n1, "OR", gates)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(c1, "z") && c1 != "z45" {
|
||||
c1, z1 = z1, c1
|
||||
swapped = append(swapped, c1, z1)
|
||||
}
|
||||
|
||||
if c0 == "" {
|
||||
c0 = n1
|
||||
} else {
|
||||
c0 = c1
|
||||
}
|
||||
}
|
||||
|
||||
// Sort and join swapped wires
|
||||
sort.Strings(swapped)
|
||||
fmt.Println(strings.Join(swapped, ","))
|
||||
}
|
||||
|
||||
func parseInput1(inp []string) (map[string]bool, []string) {
|
||||
dev := make(map[string]bool)
|
||||
var gates []string
|
||||
var inGates bool
|
||||
for i := range inp {
|
||||
if len(inp[i]) == 0 {
|
||||
inGates = true
|
||||
}
|
||||
if !inGates {
|
||||
if inp[i][3] == ':' {
|
||||
wire := inp[i][:3]
|
||||
v := inp[i][5] == '1'
|
||||
dev[wire] = v
|
||||
}
|
||||
} else {
|
||||
gates = append(gates, inp[i])
|
||||
}
|
||||
}
|
||||
return dev, gates
|
||||
}
|
||||
|
||||
func parseInput2(inp []string) [][]string {
|
||||
var parts [][]string
|
||||
var currPt []string
|
||||
for _, line := range inp {
|
||||
if line == "" {
|
||||
if len(currPt) > 0 {
|
||||
parts = append(parts, currPt)
|
||||
currPt = []string{}
|
||||
}
|
||||
} else {
|
||||
currPt = append(currPt, line)
|
||||
}
|
||||
}
|
||||
if len(currPt) > 0 {
|
||||
parts = append(parts, currPt)
|
||||
}
|
||||
return parts
|
||||
}
|
||||
|
||||
func findHighestReg(dev map[string]bool) int {
|
||||
var highest string
|
||||
for i := range dev {
|
||||
if i > highest {
|
||||
highest = i
|
||||
}
|
||||
}
|
||||
ret, _ := strconv.Atoi(highest[1:])
|
||||
return ret
|
||||
}
|
||||
|
||||
func findValueOf(dev map[string]bool, register string) int64 {
|
||||
var highest string
|
||||
for i := range dev {
|
||||
if i > highest {
|
||||
highest = i
|
||||
}
|
||||
}
|
||||
get, _ := strconv.Atoi(highest[1:])
|
||||
var val int64
|
||||
for i := get; ; i-- {
|
||||
key := fmt.Sprintf("%s%02d", register, i)
|
||||
v, ok := dev[key]
|
||||
if !ok {
|
||||
break
|
||||
} else {
|
||||
val = val << 1
|
||||
if v {
|
||||
val += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func find(w1, w2, op string, gates []string) string {
|
||||
for _, gate := range gates {
|
||||
if strings.HasPrefix(gate, fmt.Sprintf("%s %s %s", w1, op, w2)) ||
|
||||
strings.HasPrefix(gate, fmt.Sprintf("%s %s %s", w2, op, w2)) {
|
||||
parts := strings.Split(gate, " -> ")
|
||||
return parts[len(parts)-1]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
Reference in New Issue
Block a user