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
|
||||
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 |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
|
||||
break
|
||||
end
|
||||
|
51
day5.cr
51
day5.cr
@ -1,49 +1,4 @@
|
||||
require "./intcode.cr"
|
||||
lines = File.read("day5.txt").chomp.split(",").map(&.to_i32)
|
||||
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 "aahhh #{str}"
|
||||
end
|
||||
end
|
||||
{output, lines}
|
||||
end
|
||||
puts run(lines, [5])
|
||||
puts run(lines.clone, [1])
|
||||
puts run(lines.clone, [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