Abstract intocode into separate files.
This commit is contained in:
parent
e62a0067e7
commit
161ee6e244
24
day2.cr
24
day2.cr
@ -1,25 +1,11 @@
|
|||||||
|
require "./intcode.cr"
|
||||||
lines = File.read("day2.txt").lines.map(&.split(",").map(&.to_i32)).flatten
|
lines = File.read("day2.txt").lines.map(&.split(",").map(&.to_i32)).flatten
|
||||||
def run(lines, noun, verb)
|
|
||||||
lines[1] = noun
|
|
||||||
lines[2] = verb
|
|
||||||
pos = 0
|
|
||||||
loop do
|
|
||||||
case lines[pos]
|
|
||||||
when 1
|
|
||||||
lines[lines[pos+3]] = lines[lines[pos+1]] + lines[lines[pos+2]]
|
|
||||||
pos += 4
|
|
||||||
when 2
|
|
||||||
lines[lines[pos+3]] = lines[lines[pos+1]] * lines[lines[pos+2]]
|
|
||||||
pos += 4
|
|
||||||
when 99
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
lines[0]
|
|
||||||
end
|
|
||||||
100.times do |noun|
|
100.times do |noun|
|
||||||
100.times do |verb|
|
100.times do |verb|
|
||||||
if run(lines.dup, noun, verb) == 19690720
|
prog = lines.clone
|
||||||
|
prog[1] = noun
|
||||||
|
prog[2] = verb
|
||||||
|
if run(prog, [] of Int32)[1][0] == 19690720
|
||||||
puts 100*noun + verb
|
puts 100*noun + verb
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
51
day5.cr
51
day5.cr
@ -1,49 +1,4 @@
|
|||||||
|
require "./intcode.cr"
|
||||||
lines = File.read("day5.txt").chomp.split(",").map(&.to_i32)
|
lines = File.read("day5.txt").chomp.split(",").map(&.to_i32)
|
||||||
def run(lines, input)
|
puts run(lines.clone, [1])
|
||||||
output = [] of Int32
|
puts run(lines.clone, [5])
|
||||||
pos = 0
|
|
||||||
get = ->(x : Char, p : Int32) {
|
|
||||||
x == '0' ? lines[lines[pos+p]] : lines[pos+p]
|
|
||||||
}
|
|
||||||
loop do
|
|
||||||
str = "000" + lines[pos].to_s
|
|
||||||
case str
|
|
||||||
when .ends_with?("1")
|
|
||||||
lines[lines[pos+3]] = get.call(str[-3], 1) + get.call(str[-4], 2)
|
|
||||||
pos += 4
|
|
||||||
when .ends_with?("2")
|
|
||||||
lines[lines[pos+3]] = get.call(str[-3], 1) * get.call(str[-4], 2)
|
|
||||||
pos += 4
|
|
||||||
when .ends_with?("3")
|
|
||||||
lines[lines[pos+1]] = input.pop
|
|
||||||
pos += 2
|
|
||||||
when .ends_with?("4")
|
|
||||||
output << get.call(str[-3], 1)
|
|
||||||
pos += 2
|
|
||||||
when .ends_with?("5")
|
|
||||||
if get.call(str[-3], 1) != 0
|
|
||||||
pos = get.call(str[-4], 2)
|
|
||||||
else
|
|
||||||
pos += 3
|
|
||||||
end
|
|
||||||
when .ends_with?("6")
|
|
||||||
if get.call(str[-3], 1) == 0
|
|
||||||
pos = get.call(str[-4], 2)
|
|
||||||
else
|
|
||||||
pos += 3
|
|
||||||
end
|
|
||||||
when .ends_with?("7")
|
|
||||||
lines[lines[pos+3]] = (get.call(str[-3], 1) < get.call(str[-4], 2)) ? 1 : 0
|
|
||||||
pos += 4
|
|
||||||
when .ends_with?("8")
|
|
||||||
lines[lines[pos+3]] = (get.call(str[-3], 1) == get.call(str[-4], 2)) ? 1 : 0
|
|
||||||
pos += 4
|
|
||||||
when .ends_with?("99")
|
|
||||||
break
|
|
||||||
else
|
|
||||||
raise "aahhh #{str}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
{output, lines}
|
|
||||||
end
|
|
||||||
puts run(lines, [5])
|
|
||||||
|
35
day7.cr
Normal file
35
day7.cr
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
require "./intcode.cr"
|
||||||
|
require "./intcode_fibers.cr"
|
||||||
|
|
||||||
|
prog = File.read("day7.txt").chomp.split(",").map(&.to_i32)
|
||||||
|
|
||||||
|
def chain_amplifiers(prog, perm, loop = false)
|
||||||
|
chans = perm.map { |f| new_interpreter(f, prog) }
|
||||||
|
chans.zip perm do |amp, freq|
|
||||||
|
amp[0].send freq
|
||||||
|
end
|
||||||
|
|
||||||
|
chans[0][0].send 0
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
history = Array(Int32).new(chans.size, 0)
|
||||||
|
loop do
|
||||||
|
j = (i+1) % chans.size
|
||||||
|
break unless received = chans[i][1].receive
|
||||||
|
history[i] = received
|
||||||
|
chans[j][0].send received
|
||||||
|
i = j
|
||||||
|
break if i == 0 && !loop
|
||||||
|
end
|
||||||
|
|
||||||
|
history[4]
|
||||||
|
end
|
||||||
|
|
||||||
|
max_single = [0,1,2,3,4].permutations.max_of do |perm|
|
||||||
|
chain_amplifiers(prog.clone, perm)
|
||||||
|
end
|
||||||
|
puts max_single
|
||||||
|
max_cycled = [5,6,7,8,9].permutations.max_of do |perm|
|
||||||
|
chain_amplifiers(prog.clone, perm, loop=true)
|
||||||
|
end
|
||||||
|
puts max_cycled
|
47
intcode.cr
Normal file
47
intcode.cr
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
def run(lines, input)
|
||||||
|
output = [] of Int32
|
||||||
|
pos = 0
|
||||||
|
get = ->(x : Char, p : Int32) {
|
||||||
|
x == '0' ? lines[lines[pos+p]] : lines[pos+p]
|
||||||
|
}
|
||||||
|
loop do
|
||||||
|
str = "000" + lines[pos].to_s
|
||||||
|
case str
|
||||||
|
when .ends_with?("1")
|
||||||
|
lines[lines[pos+3]] = get.call(str[-3], 1) + get.call(str[-4], 2)
|
||||||
|
pos += 4
|
||||||
|
when .ends_with?("2")
|
||||||
|
lines[lines[pos+3]] = get.call(str[-3], 1) * get.call(str[-4], 2)
|
||||||
|
pos += 4
|
||||||
|
when .ends_with?("3")
|
||||||
|
lines[lines[pos+1]] = input.pop
|
||||||
|
pos += 2
|
||||||
|
when .ends_with?("4")
|
||||||
|
output << get.call(str[-3], 1)
|
||||||
|
pos += 2
|
||||||
|
when .ends_with?("5")
|
||||||
|
if get.call(str[-3], 1) != 0
|
||||||
|
pos = get.call(str[-4], 2)
|
||||||
|
else
|
||||||
|
pos += 3
|
||||||
|
end
|
||||||
|
when .ends_with?("6")
|
||||||
|
if get.call(str[-3], 1) == 0
|
||||||
|
pos = get.call(str[-4], 2)
|
||||||
|
else
|
||||||
|
pos += 3
|
||||||
|
end
|
||||||
|
when .ends_with?("7")
|
||||||
|
lines[lines[pos+3]] = (get.call(str[-3], 1) < get.call(str[-4], 2)) ? 1 : 0
|
||||||
|
pos += 4
|
||||||
|
when .ends_with?("8")
|
||||||
|
lines[lines[pos+3]] = (get.call(str[-3], 1) == get.call(str[-4], 2)) ? 1 : 0
|
||||||
|
pos += 4
|
||||||
|
when .ends_with?("99")
|
||||||
|
break
|
||||||
|
else
|
||||||
|
raise "Invalid instruction"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
{output, lines}
|
||||||
|
end
|
42
intcode_fibers.cr
Normal file
42
intcode_fibers.cr
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
def new_interpreter(f, prog)
|
||||||
|
prog = prog.clone
|
||||||
|
input = Channel(Int32).new
|
||||||
|
output = Channel(Int32?).new
|
||||||
|
spawn do
|
||||||
|
op = ""
|
||||||
|
pc = 0
|
||||||
|
arg = ->(i : Int32) { op[-(3+i)] == '0' ? prog[prog[pc+1+i]] : prog[pc+1+i] }
|
||||||
|
loop do
|
||||||
|
op = "0000" + prog[pc].to_s
|
||||||
|
case op
|
||||||
|
when .ends_with? "1"
|
||||||
|
prog[prog[pc+3]] = arg.call(0) + arg.call(1)
|
||||||
|
pc += 4
|
||||||
|
when .ends_with? "2"
|
||||||
|
prog[prog[pc+3]] = arg.call(0) * arg.call(1)
|
||||||
|
pc += 4
|
||||||
|
when .ends_with? "3"
|
||||||
|
prog[prog[pc+1]] = input.receive
|
||||||
|
pc += 2
|
||||||
|
when .ends_with? "4"
|
||||||
|
output.send(arg.call(0))
|
||||||
|
pc += 2
|
||||||
|
when .ends_with? "5"
|
||||||
|
pc = arg.call(0) != 0 ? arg.call(1) : pc + 3
|
||||||
|
when .ends_with? "6"
|
||||||
|
pc = arg.call(0) == 0 ? arg.call(1) : pc + 3
|
||||||
|
when .ends_with? "7"
|
||||||
|
prog[prog[pc+3]] = arg.call(0) < arg.call(1) ? 1 : 0
|
||||||
|
pc += 4
|
||||||
|
when .ends_with? "8"
|
||||||
|
prog[prog[pc+3]] = arg.call(0) == arg.call(1) ? 1 : 0
|
||||||
|
pc += 4
|
||||||
|
when .ends_with? "99"
|
||||||
|
input.receive
|
||||||
|
output.send(nil)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
{input, output}
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user