Advertisement
Guest User

Untitled

a guest
Dec 22nd, 2022
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.45 KB | None | 0 0
  1. local file = io.open(arg[1])
  2. local grid = {}
  3. while true do
  4.     local line = file:read("*l")
  5.     if line == "" then break end
  6.     local row = {}
  7.     for c in line:gmatch(".") do table.insert(row, c) end
  8.     table.insert(grid, row)
  9. end
  10. local route = file:read("*l")
  11.  
  12. local dirs = {["R"] = {1,0}, ["L"] = {-1,0}, ["U"] = {0,-1}, ["D"] = {0,1}}
  13. local turnR = {["R"] = "D", ["D"] = "L", ["L"] = "U", ["U"] = "R"}
  14. local turnL = {["D"] = "R", ["L"] = "D", ["U"] = "L", ["R"] = "U"}
  15. local score = {["R"] = 0, ["D"] = 1, ["L"] = 2, ["U"] = 3}
  16.  
  17. local function warp(dir, x, y)
  18.     if dir == "R" then
  19.         for i, c in ipairs(grid[y]) do
  20.             if c == "#" then return false end
  21.             if c == "." then return i, y end
  22.         end
  23.     elseif dir == "L" then
  24.         for i = #grid[y], 1, -1 do
  25.             if grid[y][i] == "#" then return false end
  26.             if grid[y][i] == "." then return i, y end
  27.         end
  28.     elseif dir == "U" then
  29.         for i = #grid, 1, -1 do
  30.             if grid[i][x] == "#" then return false end
  31.             if grid[i][x] == "." then return x, i end
  32.         end
  33.     elseif dir == "D" then
  34.         for i, row in ipairs(grid) do
  35.             if row[x] == "#" then return false end
  36.             if row[x] == "." then return x, i end
  37.         end
  38.     end
  39. end
  40.  
  41. local function getSquare(x, y)
  42.     if x > 50 and x <= 100 and y >= 1 and y <= 50 then return 1 end
  43.     if x > 100 and x <= 150 and y >= 1 and y <= 50 then return 2 end
  44.     if x > 50 and x <= 100 and y > 50 and y <= 100 then return 3 end
  45.     if x > 50 and x <= 100 and y > 100 and y <= 150 then return 4 end
  46.     if x >= 1 and x <= 50 and y > 100 and y <= 150 then return 5 end
  47.     if x >= 1 and x <= 50 and y > 150 and y <= 200 then return 6 end
  48.     return nil
  49. end
  50.  
  51. local function warp2(zone, face, x, y)
  52.     if zone == 1 then
  53.         if face == "L" then
  54.             if grid[151-y][1] == "#" then
  55.                 return false
  56.             else
  57.                 return "R", 1, 151-y
  58.             end
  59.         elseif face == "U" then
  60.             if grid[x+100][1] == "#" then
  61.                 return false
  62.             else
  63.                 return "R", 1, x+100
  64.             end
  65.         end
  66.     elseif zone == 2 then
  67.         if face == "U" then
  68.             if grid[200][x-100] == "#" then
  69.                 return false
  70.             else
  71.                 return "U", x-100, 200
  72.             end
  73.         elseif face == "R" then
  74.             if grid[151-y][100] == "#" then
  75.                 return false
  76.             else
  77.                 return "L", 100, 151-y
  78.             end
  79.         elseif face == "D" then
  80.             if grid[x-50][100] == "#" then
  81.                 return false
  82.             else
  83.                 return "L", 100, x-50
  84.             end
  85.         end
  86.     elseif zone == 3 then
  87.         if face == "R" then
  88.             if grid[50][y+50] == "#" then
  89.                 return false
  90.             else
  91.                 return "U", y+50, 50
  92.             end
  93.         elseif face == "L" then
  94.             if grid[101][y-50] == "#" then
  95.                 return false
  96.             else
  97.                 return "D", y-50, 101
  98.             end
  99.         end
  100.     elseif zone == 4 then
  101.         if face == "R" then
  102.             if grid[151-y][150] == "#" then
  103.                 return false
  104.             else
  105.                 return "L", 150, 151-y
  106.             end
  107.         elseif face == "D" then
  108.             if grid[x+100][50] == "#" then
  109.                 return false
  110.             else
  111.                 return "L", 50, x+100
  112.             end
  113.         end
  114.     elseif zone == 5 then
  115.         if face == "U" then
  116.             if grid[x+50][51] == "#" then
  117.                 return false
  118.             else
  119.                 return "R", 51, x+50
  120.             end
  121.         elseif face == "L" then
  122.             if grid[151-y][51] == "#" then
  123.                 return false
  124.             else
  125.                 return "R", 51, 151-y
  126.             end
  127.         end
  128.     elseif zone == 6 then
  129.         if face == "L" then
  130.             if grid[1][y-100] == "#" then
  131.                 return false
  132.             else
  133.                 return "D", y-100, 1
  134.             end
  135.         elseif face == "D" then
  136.             if grid[1][x+100] == "#" then
  137.                 return false
  138.             else
  139.                 return "D", x+100, 1
  140.             end
  141.         elseif face == "R" then
  142.             if grid[150][y-100] == "#" then
  143.                 return false
  144.             else
  145.                 return "U", y-100, 150
  146.             end
  147.         end
  148.     end
  149. end
  150.  
  151. local function solve(part2)
  152.     local y, x = 1
  153.     local face = "R"
  154.     for i, c in ipairs(grid[1]) do if c == "." then x = i break end end
  155.     for n, rotate in route:gmatch("(%d+)(%w?)") do
  156.         n = tonumber(n)
  157.         for _ = 1, n do
  158.             if (not grid[y+dirs[face][2]]) or (not grid[y+dirs[face][2]][x+dirs[face][1]]) or (grid[y+dirs[face][2]][x+dirs[face][1]] == " ") then
  159.                 if part2 then
  160.                     if warp2(getSquare(x,y), face, x, y) then
  161.                         face, x, y = warp2(getSquare(x,y), face, x, y)
  162.                     else
  163.                         break
  164.                     end
  165.                 else
  166.                     if warp(face, x, y) then
  167.                         x, y = warp(face, x, y)
  168.                     else
  169.                         break
  170.                     end
  171.                 end
  172.             elseif grid[y+dirs[face][2]][x+dirs[face][1]] == "#" then
  173.                 break
  174.             else
  175.                 x = x + dirs[face][1]
  176.                 y = y + dirs[face][2]
  177.             end
  178.         end
  179.         if rotate ~= "" then
  180.             if rotate == "L" then
  181.                 face = turnL[face]
  182.             else
  183.                 face = turnR[face]
  184.             end
  185.         end
  186.     end
  187.     return 1000*y + 4*x + score[face]
  188. end
  189.  
  190. print(solve())
  191. print(solve(true))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement