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