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 /24/1_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 '24/1_1.lua')
| -rw-r--r-- | 24/1_1.lua | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/24/1_1.lua b/24/1_1.lua new file mode 100644 index 0000000..586835a --- /dev/null +++ b/24/1_1.lua @@ -0,0 +1,192 @@ +require "ext" +local directions = { + right = {0,1}, + down = {1,0}, + left = {0,-1}, + up = {-1,0}, + wait = {0,0}, +} +local tiles = { + wall = {rep="#"}, + lbliz = {rep="<",move=directions.left}, + rbliz = {rep=">",move=directions.right}, + ubliz = {rep="^",move=directions.up}, + dbliz = {rep="v",move=directions.down}, + empty = {rep="."} +} +local map = {} +local row,col = 0,0 +local start,finish +local function place(map,row,col,ent) + map[row] = map[row] or {} + map[row][col] = map[row][col] or {} + table.insert(map[row][col],ent) +end +for line in io.lines() do + map[#map+1] = {} + row = row + 1 + col = 0 + for char in line:gmatch("(.)") do + col = col + 1 + if char == "." then + if row == 1 then + start = col + else + finish = col + end + end + for name,tile in pairs(tiles) do + if char == tile.rep and name ~= "empty" then + place(map,row,col,{r=row,c=col,t=tile}) + break + end + end + end +end +local w,h = col,row +local function print_puzzle(map,flood) + for row = 1,h do + for col = 1,w do + if map[row] and map[row][col] then + local elist = map[row][col] + if #elist == 1 then + io.write(elist[1].t.rep .. " ") + else + io.write("* ") + end + else + if flood and flood[row] and flood[row][col] then + io.write(string.format("%-2d",flood[row][col])) + else + io.write(" ") + end + end + end + io.write("\n") + end +end + +local h,w = #map, #map[1] +local min_walk = math.abs(finish - start) + h + +print_puzzle(map) + +local function step_map(map) + local newmap = {} + for row = 1,h do + for col = 1,w do + if map[row] and map[row][col] then + for _, ent in pairs(map[row][col]) do + if ent.t.move then + local dir = ent.t.move + ent.r = ent.r + dir[1] + ent.c = ent.c + dir[2] + --loop + if ent.r == 1 then + ent.r = h-1 + elseif ent.r == h then + ent.r = 2 + elseif ent.c == 1 then + ent.c = w-1 + elseif ent.c == w then + ent.c = 2 + end + place(newmap,ent.r,ent.c,ent) + else + place(newmap,ent.r,ent.c,ent) + end + end + end + end + end + return newmap +end +local function could_move(map,row,col) + local ret = ( + row >= 1 and + col > 1 and + row <= h and + col < w and + (map[row] == nil or + map[row][col] == nil or + map[row][col].t ~= tiles.wall) + ) + --print(ret) + return ret +end + +--map doesn't change, no matter what we do, we can store the blizzard simulation +local map_mem, mapat = {}, {[0] = map} +setmetatable(mapat,{__index=function(self,key) + if map_mem[key] then return map_mem[key] end + map_mem[key] = step_map(mapat[key-1]) + return map_mem[key] +end}) + +local state = { + location = {1,start}, + minute = 0, + speculative_goal = min_walk +} +local function copy_state(state) + return { + location = {state.location[1],state.location[2]}, + minute = state.minute, + speculative_goal = state.speculative_goal + } +end +local spec_tbl = { + [directions.right] = -1, + [directions.down] = -1, + [directions.left] = 2, + [directions.up] = 2, + [directions.wait] = 0 +} +local flood = {} +for row = 1,h do + flood[row] = {} +end +flood[1][2] = 0 +local min = 0 +while flood[h][w-1] == nil do + min = min + 1 + print("Min",min) + local nmap = mapat[min-1] + local toins = {} + --[[ + print("Before flooding 1:") + print_puzzle(nmap,flood) + ]] + --flood outward + for rn,row in pairs(flood) do + for cn,col in pairs(row) do + if flood[rn][cn] then + for name, direction in pairs(directions) do + --print("Flooding",rn,cn,name) + local trow = rn + direction[1] + local tcol = cn + direction[2] + if could_move(nmap,trow,tcol) and flood[trow][tcol] == nil then + table.insert(toins,{trow,tcol}) + end + end + end + end + end + for _,v in pairs(toins) do + flood[v[1]][v[2]] = min + end + --[[ + print("After flooding 1:") + print_puzzle(nmap,flood) + ]] + nmap = mapat[min] + --clean up where blizzards pass + for rn,row in pairs(nmap) do + for cn, col in pairs(row) do + flood[rn][cn] = nil + end + end + print("After cleaning:") + print_puzzle(nmap,flood) +end +print(flood[h][w-1]) |
