-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f4e6a61
commit d79660d
Showing
5 changed files
with
171 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
cpy a b | ||
dec b | ||
cpy a d | ||
cpy 0 a | ||
cpy b c | ||
inc a | ||
dec c | ||
jnz c -2 | ||
dec d | ||
jnz d -5 | ||
dec b | ||
cpy b c | ||
cpy c d | ||
dec d | ||
inc c | ||
jnz d -2 | ||
tgl c | ||
cpy -16 c | ||
jnz 1 c | ||
cpy 96 c | ||
jnz 91 d | ||
inc a | ||
inc d | ||
jnz d -2 | ||
inc c | ||
jnz c -5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
require 'year_2016/day_23' | ||
|
||
describe Year2016::Day23 do | ||
context 'when Part 1' do | ||
subject(:sample_one) do | ||
sample_data = <<~HEREDOC | ||
cpy 2 a | ||
tgl a | ||
tgl a | ||
tgl a | ||
cpy 1 a | ||
dec a | ||
dec a | ||
HEREDOC | ||
described_class.new(sample_data).program | ||
end | ||
|
||
it 'gives a final result' do | ||
sample_one.execute | ||
expect(sample_one.registers['a']).to eq(3) | ||
end | ||
end | ||
|
||
context 'when Results' do | ||
subject(:input_data) do | ||
File.read('spec/year_2016/day_23_input') | ||
end | ||
|
||
it 'correctly answers part 1' do | ||
expect(described_class.new(input_data).part_one).to eq(13_776) | ||
end | ||
|
||
it 'correctly answers part 2', skip: 'Test is too slow for CI' do | ||
expect(described_class.new(input_data).part_two).to eq(479_010_336) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
class Year2016 | ||
class Day23 | ||
attr_accessor :program | ||
|
||
class Program | ||
attr_accessor :instructions, :pc, :registers | ||
|
||
def initialize(input_instructions) | ||
@instructions = input_instructions.map do |instruction| | ||
[instruction, compile(instruction)] | ||
end | ||
end | ||
|
||
def inc(register) | ||
@pc += 1 | ||
@registers[register] += 1 | ||
end | ||
|
||
def dec(register) | ||
@pc += 1 | ||
@registers[register] -= 1 | ||
end | ||
|
||
def cpy(from, to) | ||
@pc += 1 | ||
return unless @registers[to] | ||
|
||
@registers[to] = @registers[from] || from.to_i | ||
end | ||
|
||
def jnz(value, jmp) | ||
return @pc += 1 if (@registers[value] || value.to_i).zero? | ||
|
||
@pc += @registers[jmp] || jmp.to_i | ||
end | ||
|
||
# rubocop:disable Metrics/MethodLength | ||
def tgl(register) | ||
jump = @registers[register] || jump.to_i | ||
code, tgl_instruction = @instructions[@pc + jump] | ||
return @pc += 1 unless tgl_instruction | ||
|
||
case tgl_instruction.length | ||
when 2 | ||
tgl_instruction[0] = tgl_instruction[0] == :inc ? :dec : :inc | ||
when 3 | ||
tgl_instruction[0] = tgl_instruction[0] == :jnz ? :cpy : :jnz | ||
end | ||
@instructions[@pc + jump] = [code, tgl_instruction] | ||
|
||
@pc += 1 | ||
end | ||
|
||
def compile(instruction) | ||
case instruction | ||
when /^cpy (-?\d+|[abcd]) ([abcd])$/ | ||
[:cpy, $1, $2] | ||
when /^inc ([abcd])$/ | ||
[:inc, $1] | ||
when /^dec ([abcd])$/ | ||
[:dec, $1] | ||
when /^jnz (-?\d+|[abcd]) (-?\d+|[abcd])$/ | ||
[:jnz, $1, $2] | ||
when /^tgl ([abcd])$/ | ||
[:tgl, $1] | ||
else | ||
raise "Invalid code: #{instruction}" | ||
end | ||
end | ||
# rubocop:enable Metrics/MethodLength | ||
|
||
def execute(init_registers = { 'a' => 0, 'b' => 0, 'c' => 0, 'd' => 0 }) | ||
@pc = 0 | ||
@registers = init_registers | ||
send(*instructions[@pc].last) while instructions[@pc] | ||
end | ||
end | ||
|
||
def initialize(input_data) | ||
@program = Program.new(input_data.chomp.split("\n")) | ||
end | ||
|
||
def part_one | ||
@program.execute('a' => 7, 'b' => 0, 'c' => 0, 'd' => 0) | ||
@program.registers['a'] | ||
end | ||
|
||
def part_two | ||
@program.execute('a' => 12, 'b' => 0, 'c' => 0, 'd' => 0) | ||
@program.registers['a'] | ||
end | ||
end | ||
end |