Skip to content

Commit 64bd779

Browse files
committed
solve day_17 part two
1 parent d32c4b3 commit 64bd779

File tree

2 files changed

+57
-12
lines changed

2 files changed

+57
-12
lines changed

day_17/input.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Register A: 64012472
1+
Register A: 265652340990875
22
Register B: 0
33
Register C: 0
44

day_17/main.go

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package main
33
import (
44
"fmt"
55
"log"
6-
"math"
76
"regexp"
7+
"slices"
88
"strconv"
99
"strings"
1010

@@ -22,6 +22,17 @@ type Computer struct {
2222
Out []int
2323
}
2424

25+
func (c *Computer) String() string {
26+
return fmt.Sprintf("Register A: %b\nRegister B: %b\nRegister C: %b", c.A, c.B, c.C)
27+
}
28+
29+
func (c *Computer) Run(program []int) {
30+
for c.IP >= 0 && c.IP < len(program) {
31+
opcode, operand := program[c.IP], program[c.IP+1]
32+
exec(opcode, operand, c)
33+
}
34+
}
35+
2536
func parseInput(input string) (Computer, []int, error) {
2637
var comp Computer
2738
var registers, program []int
@@ -61,23 +72,57 @@ func main() {
6172
}
6273

6374
fmt.Println("solution to part one: ", PartOne(computer, program))
75+
fmt.Println("solution to part two: ", PartTwo(computer, program))
6476
}
6577

66-
func PartOne(computer Computer, program []int) string {
67-
curr := computer
68-
for curr.IP >= 0 && curr.IP < len(program) {
69-
opcode, operand := program[curr.IP], program[curr.IP+1]
70-
exec(opcode, operand, &curr)
71-
}
78+
func PartOne(comp Computer, program []int) string {
79+
comp.Run(program)
7280

7381
var res []string
74-
for _, out := range curr.Out {
82+
for _, out := range comp.Out {
7583
res = append(res, strconv.Itoa(out))
7684
}
7785

7886
return strings.Join(res, ",")
7987
}
8088

89+
func PartTwo(computer Computer, program []int) int {
90+
// Note: you'll need to walkthrough your program to know how many bits each segment should
91+
// be.
92+
93+
// we reverse engineer the segments of the A register 3-bits at a time,
94+
// the first 3 bits of the A register are responsible for producing
95+
// the last output — in my case, 0. Then we expand by an extra 3 bits, searching through
96+
// values 0 (0b000) to 7 (0b111), noting values that produce the last 2 outputs and so on...
97+
98+
// from hacking around, 0b111 or 7 is known to produce the last output 0
99+
// at least, based on my given input
100+
knownSegments := []int{0b111}
101+
102+
// we try to find the remaining segments of the output, we skip the last output 0, since
103+
// we already know that
104+
for i := 2; i <= len(program); i++ {
105+
var expandedSegments []int
106+
expectedOutput := program[len(program)-i:]
107+
108+
for _, f := range knownSegments {
109+
for i := 0b000; i <= 0b111; i++ {
110+
regA := f<<3 + i
111+
comp := Computer{A: regA}
112+
comp.Run(program)
113+
114+
if slices.Equal(comp.Out, expectedOutput) {
115+
expandedSegments = append(expandedSegments, regA)
116+
}
117+
}
118+
}
119+
120+
knownSegments = expandedSegments
121+
}
122+
123+
return slices.Min(knownSegments)
124+
}
125+
81126
func combo(operand int, computer *Computer) int {
82127
switch operand {
83128
case 4:
@@ -98,7 +143,7 @@ func exec(opCode, operand int, computer *Computer) {
98143
case 0:
99144
numerator := computer.A
100145
comboOp := combo(operand, computer)
101-
computer.A = numerator / int(math.Pow(2, float64(comboOp)))
146+
computer.A = numerator / (1 << comboOp)
102147
case 1:
103148
computer.B = computer.B ^ operand
104149
case 2:
@@ -116,11 +161,11 @@ func exec(opCode, operand int, computer *Computer) {
116161
case 6:
117162
numerator := computer.A
118163
comboOp := combo(operand, computer)
119-
computer.B = numerator / int(math.Pow(2, float64(comboOp)))
164+
computer.B = numerator / (1 << comboOp)
120165
case 7:
121166
numerator := computer.A
122167
comboOp := combo(operand, computer)
123-
computer.C = numerator / int(math.Pow(2, float64(comboOp)))
168+
computer.C = numerator / (1 << comboOp)
124169
}
125170

126171
if !jumped {

0 commit comments

Comments
 (0)