-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday5.rb
executable file
·78 lines (70 loc) · 2.16 KB
/
day5.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#!/usr/bin/env ruby
# frozen_string_literal: true
input = File.read('day5.txt').split(',').map(&:to_i)
def process(program, input, ip=0)
opcode, modes = process_instruction(program[ip])
case opcode
when 1
param1 = process_parameter(program, program[ip += 1], modes[0])
param2 = process_parameter(program, program[ip += 1], modes[1])
write_addr = program[ip += 1]
program[write_addr] = param1 + param2
when 2
param1 = process_parameter(program, program[ip += 1], modes[0])
param2 = process_parameter(program, program[ip += 1], modes[1])
write_addr = program[ip += 1]
program[write_addr] = param1 * param2
when 3
write_addr = program[ip += 1]
program[write_addr] = input
when 4
param1 = process_parameter(program, program[ip += 1], modes[0])
puts param1
when 5
param1 = process_parameter(program, program[ip += 1], modes[0])
param2 = process_parameter(program, program[ip += 1], modes[1])
ip = param2 - 1 unless param1.zero?
when 6
param1 = process_parameter(program, program[ip += 1], modes[0])
param2 = process_parameter(program, program[ip += 1], modes[1])
ip = param2 - 1 if param1.zero?
when 7
param1 = process_parameter(program, program[ip += 1], modes[0])
param2 = process_parameter(program, program[ip += 1], modes[1])
write_addr = program[ip += 1]
program[write_addr] = param1 < param2 ? 1 : 0
when 8
param1 = process_parameter(program, program[ip += 1], modes[0])
param2 = process_parameter(program, program[ip += 1], modes[1])
write_addr = program[ip += 1]
program[write_addr] = param1 == param2 ? 1 : 0
when 99
puts 'Halt!'
return
else
raise "Unknown opcode #{opcode} at address #{ip}"
end
process(program, input, ip + 1)
end
def process_instruction(value)
s = format('%<value>05d', value: value)
opcode = s[-2..-1].to_i
modes = s[0..2].chars.reverse.map(&:to_i)
[opcode, modes]
end
def process_parameter(program, value, mode)
case mode
when 0
program[value]
when 1
value
else
raise "Unknown parameter mode #{mode}"
end
end
# Part 1
program = input.dup
process(program, 1)
# Part 2
program = input.dup
process(program, 5)