diff options
| author | Alex Pickering <alex@cogarr.net> | 2025-02-07 12:49:48 -0600 |
|---|---|---|
| committer | Alex Pickering <alex@cogarr.net> | 2025-02-07 12:49:48 -0600 |
| commit | 3555be54c2abb8d5ece008a60dbdfbde0ffbddd7 (patch) | |
| tree | 278876284d07118ecdea5c48cb6453f3122887f0 /22/1.lua | |
| download | advent_of_code_2022-master.tar.gz advent_of_code_2022-master.tar.bz2 advent_of_code_2022-master.zip | |
Diffstat (limited to '22/1.lua')
| -rw-r--r-- | 22/1.lua | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/22/1.lua b/22/1.lua new file mode 100644 index 0000000..fd946bb --- /dev/null +++ b/22/1.lua @@ -0,0 +1,144 @@ +require "ext" +local parse_map = true +local map = {} +local row,col = 0,0 +local start +local commands = {} +local face_size = +for line in io.lines() do + row = row + 1 + if line ~= "" and parse_map then + col = 0 + for char in line:gmatch("(.)") do + col = col + 1 + local locf = string.format("%d,%d",row,col) + if char == "." then + if start == nil then + start = locf + end + map[locf] = true + elseif char == "#" then + map[locf] = false + end --else, it's nil + end + elseif line == "" and parse_map then + parse_map = false + elseif not parse_map then + local ccursor = line + while ccursor ~= "" do + if ccursor:find("^%d") then + table.insert(commands,{type="walk",n=ccursor:match("^(%d+)")}) + ccursor = ccursor:gsub("^(%d+)","") + elseif ccursor:find("^[LR]") then + table.insert(commands,{type="turn",n=ccursor:match("^([LR])")}) + ccursor = ccursor:gsub("^[LR]","") + end + end + end +end + +local directions = { + up = {-1, 0}, + down = {1,0}, + left = {0,-1}, + right = {0,1} +} +local dirmap = { + [0] = { + name = "right", + R = 1, + L = 3 + }, + [1] = { + name = "down", + R = 2, + L = 0 + }, + [2] = { + name = "left", + R = 3, + L = 1 + }, + [3] = { + name = "up", + R = 0, + L = 2 + } +} + +local mem_loop = {} +local function find_loop_loc(sloc, direction) + print("Finding loop location from",sloc,"dir",direction) + if mem_loop[sloc] and mem_loop[sloc][direction] then + return mem_loop[sloc][direction] + end + local srow, scol = sloc:match("(%d+),(%d+)") + local radd, cadd = -direction[1], -direction[2] + while map[string.format("%d,%d",srow,scol)] ~= nil do + print("Examining",string.format("%d,%d",srow,scol),"was not nil") + srow, scol = srow + radd, scol + cadd + end + print("Examining",string.format("%d,%d",srow,scol),"was nil") + local ret = string.format("%d,%d",srow + direction[1],scol + direction[2]) + mem_loop[ret] = mem_loop[ret] or {} + mem_loop[ret][direction] = ret + print("Returning",ret) + return ret +end +print("map",map) +print("commands",commands) +local state = { + location = start, + direction = 0 +} +print("Starting state:",state) + +local function open(location,direction) + local crow, ccol = state.location:match("(%d+),(%d+)") + local rrow, rcol = crow + direction[1], ccol + direction[2] + local rloc = string.format("%d,%d",rrow,rcol) + if map[rloc] then + return true, rloc + elseif map[rloc] == false then + return false + else + local loop_loc = find_loop_loc(location,direction) + assert(map[loop_loc] ~= nil) + if map[loop_loc] then + return true, loop_loc + else + return false + end + end +end + +local function run(state, instructions) + local function walk(state,n) + for i = 1, n do + local dir = directions[dirmap[state.direction].name] + local isopen, newloc = open(state.location,dir) + if isopen then + print("Walked to",newloc) + state.location = newloc + else + break + end + end + end + local function turn(state,dir) + state.direction = dirmap[state.direction][dir] + end + while #instructions > 0 do + local ins = table.remove(instructions,1) + if ins.type == "walk" then + walk(state,ins.n) + elseif ins.type == "turn" then + turn(state,ins.n) + end + end +end + +run(state,commands) +print(state) +local row, col = state.location:match("(%d+),(%d+)") +print((row*1000) + (col * 4) + state.direction) |
