summaryrefslogtreecommitdiff
path: root/22/1.lua
diff options
context:
space:
mode:
authorAlex Pickering <alex@cogarr.net>2025-02-07 12:49:48 -0600
committerAlex Pickering <alex@cogarr.net>2025-02-07 12:49:48 -0600
commit3555be54c2abb8d5ece008a60dbdfbde0ffbddd7 (patch)
tree278876284d07118ecdea5c48cb6453f3122887f0 /22/1.lua
downloadadvent_of_code_2022-master.tar.gz
advent_of_code_2022-master.tar.bz2
advent_of_code_2022-master.zip
inital commitHEADmaster
Diffstat (limited to '22/1.lua')
-rw-r--r--22/1.lua144
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)