Skip to content

Commit bd357de

Browse files
committed
Day 17 - Puzzle 2
1 parent 272864c commit bd357de

File tree

3 files changed

+51
-9
lines changed

3 files changed

+51
-9
lines changed

β€Žlib/solutions/day_17.rbβ€Ž

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,48 @@ def part_one(input)
88

99
cpu = Cpu.new(ra, rb, rc, instructions)
1010
output = cpu.run
11-
12-
output
11+
12+
output.map(&:to_s).join(',')
1313
end
1414

1515
def part_two(input)
16-
0
16+
lines = input.split("\n")
17+
ra = lines[0].scan(/Register A: (\d+)/).first.first.to_i
18+
rb = lines[1].scan(/Register B: (\d+)/).first.first.to_i
19+
rc = lines[2].scan(/Register C: (\d+)/).first.first.to_i
20+
instructions = lines[4].split(":").last.split(",").map(&:to_i)
21+
22+
target = instructions.dup
23+
24+
# Instead of bruteforcing the full solution at once, we want
25+
# to create partial solutions and work towards a full one.
26+
#
27+
# Since the "Cpu" will output 3-bit chunks, we can work backwards
28+
# with a minimal A for outputting the last output chunk correctly.
29+
#
30+
# Given the example 0,3,5,4,3,0 we try to figure out which
31+
# minimal value of A results in the right most 0 in the output.
32+
33+
# Given an empty output, A is 0 (that is when the program ends.)
34+
results = [0]
35+
36+
# Incrementally find more chunks, right to left
37+
target.size.times do |i|
38+
# Use the results from the previous iteration to find the next
39+
results = results.flat_map do |n|
40+
# Bit-shift n by 3 to the left, and add a number between 0 and 7
41+
# For these values of A, see which are valid candidates
42+
(0..7).map do |a|
43+
candidate = n * 8 + a
44+
output = Cpu.new(candidate, rb, rc, target).run
45+
candidate if target[-i - 1..] == output
46+
end.compact
47+
end
48+
end
49+
50+
# results now has, probably, one or more values for A, so pick
51+
# the first, and smallest, one.
52+
results.first
1753
end
1854
end
1955

@@ -59,7 +95,7 @@ def run
5995
step
6096
# puts to_s
6197
end
62-
@output.map(&:to_s).join(',')
98+
output
6399
end
64100

65101
# Single CPU cycle

β€Žspec/input/day_17b_test.txtβ€Ž

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Register A: 2024
2+
Register B: 0
3+
Register C: 0
4+
5+
Program: 0,3,5,4,3,0

β€Žspec/solutions/day_17_spec.rbβ€Ž

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
require "solutions/day_17"
33

44
RSpec.describe Day17 do
5-
let(:input) { File.read(File.join(__dir__, '..', '..', 'spec', 'input', 'day_17_test.txt')).strip }
65

76
describe '#part_one' do
7+
let(:input) { File.read(File.join(__dir__, '..', '..', 'spec', 'input', 'day_17_test.txt')).strip }
8+
89
it 'test 1' do
910
cpu = Cpu.new(0, 0, 9, [2,6])
1011
cpu.run
@@ -56,10 +57,10 @@
5657
end
5758

5859
describe '#part_two' do
59-
xit 'calculates the correct solutions for part two' do
60-
cpu = Cpu.new(2024, 0, 0, [0,3,5,4,3,0])
61-
result = cpu.run
62-
expect(result).not_to eql(117440)
60+
let(:input) { File.read(File.join(__dir__, '..', '..', 'spec', 'input', 'day_17b_test.txt')).strip }
61+
62+
it 'calculates the correct solutions for part two' do
63+
expect(subject.part_two(input)).to eq(117440)
6364
end
6465
end
6566
end

0 commit comments

Comments
Β (0)