mid-kid
5 years ago
2 changed files with 194 additions and 0 deletions
@ -0,0 +1,193 @@ |
|||
function get_arg(mem, pos, arg) |
|||
local param_mode = mem[pos] // (10 ^ (arg + 1)) % 10 |
|||
if #mem < pos + arg then |
|||
print(string.format("Error: Opcode too short at end of memory: %d", pos)) |
|||
os.exit(false) |
|||
end |
|||
local arg = mem[pos + arg] |
|||
if param_mode == 0 then |
|||
arg = arg + 1 |
|||
if #mem < arg then |
|||
print(string.format("Error: Memory offset out of bounds: %d", arg)) |
|||
os.exit(false) |
|||
end |
|||
end |
|||
return arg |
|||
end |
|||
|
|||
function get_param(mem, pos, arg) |
|||
local param_mode = mem[pos] // (10 ^ (arg + 1)) % 10 |
|||
local arg = get_arg(mem, pos, arg) |
|||
if param_mode == 0 then |
|||
return mem[arg] |
|||
end |
|||
return arg |
|||
end |
|||
|
|||
function interpret(mem, state, input_func, output_func) |
|||
if not state.pos then |
|||
state.pos = 1 |
|||
end |
|||
|
|||
local pos = state.pos |
|||
while true do |
|||
if #mem < pos then |
|||
print(string.format("Instruction pointer ran off of memory")) |
|||
os.exit(false) |
|||
end |
|||
|
|||
local opcode = mem[pos] % 100 |
|||
|
|||
if opcode == 1 then |
|||
mem[get_arg(mem, pos, 3)] = get_param(mem, pos, 1) + get_param(mem, pos, 2) |
|||
pos = pos + 4 |
|||
elseif opcode == 2 then |
|||
mem[get_arg(mem, pos, 3)] = get_param(mem, pos, 1) * get_param(mem, pos, 2) |
|||
pos = pos + 4 |
|||
elseif opcode == 3 then |
|||
local val = input_func() |
|||
if not val then |
|||
state.pos = pos |
|||
return true |
|||
end |
|||
mem[get_arg(mem, pos, 1)] = val |
|||
pos = pos + 2 |
|||
elseif opcode == 4 then |
|||
output_func(get_param(mem, pos, 1)) |
|||
pos = pos + 2 |
|||
elseif opcode == 5 then |
|||
if get_param(mem, pos, 1) ~= 0 then |
|||
pos = get_param(mem, pos, 2) + 1 |
|||
else |
|||
pos = pos + 3 |
|||
end |
|||
elseif opcode == 6 then |
|||
if get_param(mem, pos, 1) == 0 then |
|||
pos = get_param(mem, pos, 2) + 1 |
|||
else |
|||
pos = pos + 3 |
|||
end |
|||
elseif opcode == 7 then |
|||
mem[get_arg(mem, pos, 3)] = get_param(mem, pos, 1) < get_param(mem, pos, 2) and 1 or 0 |
|||
pos = pos + 4 |
|||
elseif opcode == 8 then |
|||
mem[get_arg(mem, pos, 3)] = get_param(mem, pos, 1) == get_param(mem, pos, 2) and 1 or 0 |
|||
pos = pos + 4 |
|||
elseif opcode == 99 then |
|||
state.pos = pos |
|||
return false |
|||
else |
|||
print(string.format("Error: Invalid opcode %d at %d", opcode, pos - 1)) |
|||
os.exit(false) |
|||
end |
|||
end |
|||
end |
|||
|
|||
function input_stdin() |
|||
io.stdout:write("> ") |
|||
return io.stdin:read("n") |
|||
end |
|||
|
|||
function output_stdout(val) |
|||
io.stdout:write(val) |
|||
io.stdout:write("\n") |
|||
end |
|||
|
|||
function input_array(array) |
|||
function inner() |
|||
return table.remove(array, 1) |
|||
end |
|||
return inner |
|||
end |
|||
|
|||
function output_array(array) |
|||
function inner(val) |
|||
table.insert(array, val) |
|||
end |
|||
return inner |
|||
end |
|||
|
|||
file = io.open(arg[1]) |
|||
program = {} |
|||
for num in string.gmatch(file:read(), "(-?%d+),?") do |
|||
table.insert(program, tonumber(num)) |
|||
end |
|||
file:close() |
|||
|
|||
function get_signal(phase) |
|||
signal = 0 |
|||
for i = 1, 5 do |
|||
memory = {table.unpack(program)} |
|||
output = {} |
|||
interpret(memory, {}, input_array({phase[i], signal}), output_array(output)) |
|||
signal = output[1] |
|||
end |
|||
return signal |
|||
end |
|||
|
|||
function get_signal_p2(phase) |
|||
machines = {} |
|||
for i = 1, 5 do |
|||
if i == 1 then |
|||
input = {} |
|||
else |
|||
input = machines[i - 1].output |
|||
end |
|||
table.insert(input, phase[i] + 5) |
|||
machines[i] = {mem={table.unpack(program)}, input=input, output={}} |
|||
end |
|||
machines[5].output = machines[1].input |
|||
table.insert(machines[1].input, 0) |
|||
|
|||
while true do |
|||
done = true |
|||
for i = 1, 5 do |
|||
if interpret(machines[i].mem, machines[i], input_array(machines[i].input), output_array(machines[i].output)) then |
|||
done = false |
|||
end |
|||
end |
|||
if done then |
|||
break |
|||
end |
|||
end |
|||
return machines[5].output[1] |
|||
end |
|||
|
|||
biggest = 0 |
|||
biggest_p2 = 0 |
|||
for i = 0, (5 ^ 5) - 1 do |
|||
phase = { |
|||
i // (5 ^ 4) % 5, |
|||
i // (5 ^ 3) % 5, |
|||
i // (5 ^ 2) % 5, |
|||
i // (5 ^ 1) % 5, |
|||
i // (5 ^ 0) % 5 |
|||
} |
|||
count = {} |
|||
for _, x in ipairs(phase) do |
|||
if not count[x] then |
|||
count[x] = 0 |
|||
end |
|||
count[x] = count[x] + 1 |
|||
end |
|||
double = false |
|||
for _, x in pairs(count) do |
|||
if x > 1 then |
|||
double = true |
|||
end |
|||
end |
|||
|
|||
if not double then |
|||
signal = get_signal(phase) |
|||
if signal > biggest then |
|||
biggest = signal |
|||
end |
|||
signal = get_signal_p2(phase) |
|||
if signal > biggest_p2 then |
|||
biggest_p2 = signal |
|||
end |
|||
end |
|||
end |
|||
|
|||
print("Part 1:", biggest) |
|||
print("Part 2:", biggest_p2) |
@ -0,0 +1 @@ |
|||
3,8,1001,8,10,8,105,1,0,0,21,46,55,72,85,110,191,272,353,434,99999,3,9,1002,9,5,9,1001,9,2,9,102,3,9,9,101,2,9,9,102,4,9,9,4,9,99,3,9,102,5,9,9,4,9,99,3,9,1002,9,2,9,101,2,9,9,1002,9,2,9,4,9,99,3,9,1002,9,4,9,101,3,9,9,4,9,99,3,9,1002,9,3,9,101,5,9,9,1002,9,3,9,101,3,9,9,1002,9,5,9,4,9,99,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,99,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,99,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,99 |
Loading…
Reference in new issue