Skip to content

Commit

Permalink
Day 17 - Puzzle 2
Browse files Browse the repository at this point in the history
  • Loading branch information
ariejan committed Dec 17, 2024
1 parent 272864c commit bd357de
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 9 deletions.
44 changes: 40 additions & 4 deletions lib/solutions/day_17.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,48 @@ def part_one(input)

cpu = Cpu.new(ra, rb, rc, instructions)
output = cpu.run

output
output.map(&:to_s).join(',')
end

def part_two(input)
0
lines = input.split("\n")
ra = lines[0].scan(/Register A: (\d+)/).first.first.to_i
rb = lines[1].scan(/Register B: (\d+)/).first.first.to_i
rc = lines[2].scan(/Register C: (\d+)/).first.first.to_i
instructions = lines[4].split(":").last.split(",").map(&:to_i)

target = instructions.dup

# Instead of bruteforcing the full solution at once, we want
# to create partial solutions and work towards a full one.
#
# Since the "Cpu" will output 3-bit chunks, we can work backwards
# with a minimal A for outputting the last output chunk correctly.
#
# Given the example 0,3,5,4,3,0 we try to figure out which
# minimal value of A results in the right most 0 in the output.

# Given an empty output, A is 0 (that is when the program ends.)
results = [0]

# Incrementally find more chunks, right to left
target.size.times do |i|
# Use the results from the previous iteration to find the next
results = results.flat_map do |n|
# Bit-shift n by 3 to the left, and add a number between 0 and 7
# For these values of A, see which are valid candidates
(0..7).map do |a|
candidate = n * 8 + a
output = Cpu.new(candidate, rb, rc, target).run
candidate if target[-i - 1..] == output
end.compact
end
end

# results now has, probably, one or more values for A, so pick
# the first, and smallest, one.
results.first
end
end

Expand Down Expand Up @@ -59,7 +95,7 @@ def run
step
# puts to_s
end
@output.map(&:to_s).join(',')
output
end

# Single CPU cycle
Expand Down
5 changes: 5 additions & 0 deletions spec/input/day_17b_test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Register A: 2024
Register B: 0
Register C: 0

Program: 0,3,5,4,3,0
11 changes: 6 additions & 5 deletions spec/solutions/day_17_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
require "solutions/day_17"

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

describe '#part_one' do
let(:input) { File.read(File.join(__dir__, '..', '..', 'spec', 'input', 'day_17_test.txt')).strip }

it 'test 1' do
cpu = Cpu.new(0, 0, 9, [2,6])
cpu.run
Expand Down Expand Up @@ -56,10 +57,10 @@
end

describe '#part_two' do
xit 'calculates the correct solutions for part two' do
cpu = Cpu.new(2024, 0, 0, [0,3,5,4,3,0])
result = cpu.run
expect(result).not_to eql(117440)
let(:input) { File.read(File.join(__dir__, '..', '..', 'spec', 'input', 'day_17b_test.txt')).strip }

it 'calculates the correct solutions for part two' do
expect(subject.part_two(input)).to eq(117440)
end
end
end
Expand Down

0 comments on commit bd357de

Please sign in to comment.