mid-kid
5 years ago
2 changed files with 245 additions and 0 deletions
@ -0,0 +1,244 @@ |
|||||
|
function get_param(state, arg) |
||||
|
local param_mode = state.mem[state.pos] // (10 ^ (arg + 1)) % 10 |
||||
|
if #state.mem < state.pos + arg then |
||||
|
print(string.format("Error: Opcode too short at end of memory: %d", state.pos)) |
||||
|
os.exit(false) |
||||
|
end |
||||
|
local arg = state.mem[state.pos + arg] |
||||
|
if param_mode == 0 then |
||||
|
arg = arg + 1 |
||||
|
elseif param_mode == 2 then |
||||
|
arg = arg + state.relbase |
||||
|
end |
||||
|
return arg |
||||
|
end |
||||
|
|
||||
|
function read_mem(state, arg) |
||||
|
local param_mode = state.mem[state.pos] // (10 ^ (arg + 1)) % 10 |
||||
|
local arg = get_param(state, arg) |
||||
|
if param_mode == 1 then |
||||
|
return arg |
||||
|
end |
||||
|
arg = state.mem[arg] |
||||
|
if not arg then |
||||
|
return 0 |
||||
|
end |
||||
|
return arg |
||||
|
end |
||||
|
|
||||
|
function write_mem(state, arg, val) |
||||
|
local param_mode = state.mem[state.pos] // (10 ^ (arg + 1)) % 10 |
||||
|
local arg = get_param(state, arg) |
||||
|
if param_mode == 1 then |
||||
|
print(string.format("Error: Invalid inmediate write: %d", arg)) |
||||
|
end |
||||
|
state.mem[arg] = val |
||||
|
end |
||||
|
|
||||
|
function interpret(state) |
||||
|
if not state.mem then |
||||
|
state.mem = state |
||||
|
end |
||||
|
if not state.pos then |
||||
|
state.pos = 1 |
||||
|
state.relbase = 1 |
||||
|
end |
||||
|
if not state.input then |
||||
|
state.input = input_stdin |
||||
|
end |
||||
|
if not state.output then |
||||
|
state.output = output_stdout |
||||
|
end |
||||
|
|
||||
|
while true do |
||||
|
if #state.mem < state.pos then |
||||
|
print(string.format("Instruction pointer ran off of memory")) |
||||
|
os.exit(false) |
||||
|
end |
||||
|
|
||||
|
local opcode = state.mem[state.pos] % 100 |
||||
|
local instr_size = 1 |
||||
|
|
||||
|
if opcode == 1 then |
||||
|
write_mem(state, 3, read_mem(state, 1) + read_mem(state, 2)) |
||||
|
instr_size = 4 |
||||
|
elseif opcode == 2 then |
||||
|
write_mem(state, 3, read_mem(state, 1) * read_mem(state, 2)) |
||||
|
instr_size = 4 |
||||
|
elseif opcode == 3 then |
||||
|
local val = state.input() |
||||
|
if not val then return true end |
||||
|
write_mem(state, 1, val) |
||||
|
instr_size = 2 |
||||
|
elseif opcode == 4 then |
||||
|
state.output(read_mem(state, 1)) |
||||
|
instr_size = 2 |
||||
|
elseif opcode == 5 then |
||||
|
instr_size = 3 |
||||
|
if read_mem(state, 1) ~= 0 then |
||||
|
state.pos = read_mem(state, 2) + 1 |
||||
|
instr_size = 0 |
||||
|
end |
||||
|
elseif opcode == 6 then |
||||
|
instr_size = 3 |
||||
|
if read_mem(state, 1) == 0 then |
||||
|
state.pos = read_mem(state, 2) + 1 |
||||
|
instr_size = 0 |
||||
|
end |
||||
|
elseif opcode == 7 then |
||||
|
write_mem(state, 3, read_mem(state, 1) < read_mem(state, 2) and 1 or 0) |
||||
|
instr_size = 4 |
||||
|
elseif opcode == 8 then |
||||
|
write_mem(state, 3, read_mem(state, 1) == read_mem(state, 2) and 1 or 0) |
||||
|
instr_size = 4 |
||||
|
elseif opcode == 9 then |
||||
|
state.relbase = state.relbase + read_mem(state, 1) |
||||
|
instr_size = 2 |
||||
|
elseif opcode == 99 then |
||||
|
return false |
||||
|
else |
||||
|
print(string.format("Error: Invalid opcode %d at %d", opcode, state.pos - 1)) |
||||
|
os.exit(false) |
||||
|
end |
||||
|
|
||||
|
state.pos = state.pos + instr_size |
||||
|
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() |
||||
|
|
||||
|
--interpret(program) |
||||
|
|
||||
|
--file = {} |
||||
|
--for line in io.lines(arg[1]) do |
||||
|
--fline = {} |
||||
|
--for char in line:gmatch(".") do |
||||
|
--if char == "." then |
||||
|
--table.insert(fline, 0) |
||||
|
--else |
||||
|
--table.insert(fline, 1) |
||||
|
--end |
||||
|
--end |
||||
|
--table.insert(file, fline) |
||||
|
--end |
||||
|
|
||||
|
result_p1 = 0 |
||||
|
angles_low = {} |
||||
|
angles_high = {} |
||||
|
for y = 0, 49 do |
||||
|
--for y = 0, 34 do |
||||
|
current = 0 |
||||
|
for x = 0, 49 do |
||||
|
--for x = 0, 34 do |
||||
|
output = {} |
||||
|
interpret({mem={table.unpack(program)}, input=input_array({x, y}), output=output_array(output)}) |
||||
|
--output = {file[y + 1][x + 1]} |
||||
|
result_p1 = result_p1 + output[1] |
||||
|
if current ~= output[1] then |
||||
|
current = output[1] |
||||
|
if current == 1 then |
||||
|
table.insert(angles_low, math.atan(y + 0.5, x + 0.5)) |
||||
|
else |
||||
|
table.insert(angles_high, math.atan(y + 0.5, x + 0.5)) |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
print("Part 1:", result_p1) |
||||
|
|
||||
|
p1 = {x=1, y=1} |
||||
|
p2 = {x=1, y=1} |
||||
|
|
||||
|
while (p2.x - p1.x) < 99 or (p1.y - p2.y) < 99 do |
||||
|
if (p2.x - p1.x) < 99 then |
||||
|
p2.x = p1.x + 99 |
||||
|
while true do |
||||
|
output = {} |
||||
|
interpret({mem={table.unpack(program)}, input=input_array({p2.x, p2.y}), output=output_array(output)}) |
||||
|
if output[1] == 1 then |
||||
|
break |
||||
|
end |
||||
|
p2.y = p2.y + 1 |
||||
|
end |
||||
|
end |
||||
|
if (p1.y - p2.y) < 99 then |
||||
|
p1.y = p2.y + 99 |
||||
|
while true do |
||||
|
output = {} |
||||
|
interpret({mem={table.unpack(program)}, input=input_array({p1.x, p1.y}), output=output_array(output)}) |
||||
|
if output[1] == 1 then |
||||
|
break |
||||
|
end |
||||
|
p1.x = p1.x + 1 |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
print("Part 2:", p1.x * 10000 + p2.y) |
||||
|
|
||||
|
|
||||
|
-- I tried to do this using the law of cosines and it works for the example, but not for the "real" thing... |
||||
|
|
||||
|
function mean(table) |
||||
|
local sum = 0 |
||||
|
for _, x in ipairs(table) do |
||||
|
sum = sum + x |
||||
|
end |
||||
|
return sum / #table |
||||
|
end |
||||
|
|
||||
|
angle_low = mean(angles_low) |
||||
|
angle_high = mean(angles_high) |
||||
|
angle_rect = -math.pi * 1 / 4 |
||||
|
|
||||
|
print(angle_low, angle_high, angle_rect) |
||||
|
|
||||
|
angle_alpha = angle_low - angle_high |
||||
|
angle_beta = math.pi - (angle_low - angle_rect) |
||||
|
angle_gamma = angle_high - angle_rect |
||||
|
|
||||
|
print(angle_alpha, angle_beta, angle_gamma, (angle_alpha + angle_beta + angle_gamma) / math.pi) |
||||
|
|
||||
|
length_a = math.sqrt((99 ^ 2) + (99 ^ 2)) |
||||
|
--length_a = math.sqrt((9 ^ 2) + (9 ^ 2)) |
||||
|
length_b = length_a * math.sin(angle_beta) / math.sin(angle_alpha) |
||||
|
length_c = length_a * math.sin(angle_gamma) / math.sin(angle_alpha) |
||||
|
|
||||
|
pos_low = {x=math.cos(angle_low) * length_c, y=math.sin(angle_low) * length_c} |
||||
|
pos_high = {x=math.cos(angle_high) * length_b, y=math.sin(angle_high) * length_b} |
||||
|
print(pos_low.x, pos_low.y, pos_high.x, pos_high.y) |
||||
|
print(angle_rect + math.pi, math.atan(pos_low.y - pos_high.y, pos_low.x - pos_high.x)) |
||||
|
|
||||
|
pos_x = math.ceil(pos_low.x - 0.5) |
||||
|
pos_y = math.ceil(pos_high.y - 0.5) |
||||
|
|
||||
|
print("Part 2:", pos_x * 10000 + pos_y) |
@ -0,0 +1 @@ |
|||||
|
109,424,203,1,21102,11,1,0,1106,0,282,21102,18,1,0,1105,1,259,1202,1,1,221,203,1,21102,31,1,0,1106,0,282,21101,38,0,0,1106,0,259,21002,23,1,2,22102,1,1,3,21102,1,1,1,21102,1,57,0,1105,1,303,2101,0,1,222,21002,221,1,3,20101,0,221,2,21101,0,259,1,21102,1,80,0,1105,1,225,21102,1,8,2,21101,91,0,0,1106,0,303,1202,1,1,223,21002,222,1,4,21102,1,259,3,21101,225,0,2,21101,225,0,1,21101,0,118,0,1105,1,225,21001,222,0,3,21101,0,48,2,21102,133,1,0,1106,0,303,21202,1,-1,1,22001,223,1,1,21102,1,148,0,1105,1,259,1201,1,0,223,20101,0,221,4,21001,222,0,3,21101,0,6,2,1001,132,-2,224,1002,224,2,224,1001,224,3,224,1002,132,-1,132,1,224,132,224,21001,224,1,1,21102,1,195,0,105,1,108,20207,1,223,2,21001,23,0,1,21101,-1,0,3,21101,0,214,0,1105,1,303,22101,1,1,1,204,1,99,0,0,0,0,109,5,2101,0,-4,249,21201,-3,0,1,22102,1,-2,2,21202,-1,1,3,21102,1,250,0,1106,0,225,21201,1,0,-4,109,-5,2106,0,0,109,3,22107,0,-2,-1,21202,-1,2,-1,21201,-1,-1,-1,22202,-1,-2,-2,109,-3,2106,0,0,109,3,21207,-2,0,-1,1206,-1,294,104,0,99,22101,0,-2,-2,109,-3,2106,0,0,109,5,22207,-3,-4,-1,1206,-1,346,22201,-4,-3,-4,21202,-3,-1,-1,22201,-4,-1,2,21202,2,-1,-1,22201,-4,-1,1,22102,1,-2,3,21101,0,343,0,1105,1,303,1105,1,415,22207,-2,-3,-1,1206,-1,387,22201,-3,-2,-3,21202,-2,-1,-1,22201,-3,-1,3,21202,3,-1,-1,22201,-3,-1,2,22101,0,-4,1,21101,384,0,0,1106,0,303,1106,0,415,21202,-4,-1,-4,22201,-4,-3,-4,22202,-3,-2,-2,22202,-2,-4,-4,22202,-3,-2,-3,21202,-4,-1,-2,22201,-3,-2,1,21201,1,0,-4,109,-5,2106,0,0 |
Loading…
Reference in new issue