190 lines
4.0 KiB
Lua
190 lines
4.0 KiB
Lua
--io.input("test")
|
|
io.input("input")
|
|
--
|
|
--local target = 2022 -- part 1
|
|
local target = 1000000000000 -- part 2
|
|
|
|
local shapes = {
|
|
{ w = 4, h = 1, map = { {1, 1, 1, 1} } },
|
|
{ w = 3, h = 3, map = { {0, 1, 0}, {1, 1, 1}, {0, 1, 0} } },
|
|
{ w = 3, h = 3, map = { {1, 1, 1}, {0, 0, 1}, {0, 0, 1} } },
|
|
{ w = 1, h = 4, map = { {1}, {1}, {1}, {1} } },
|
|
{ w = 2, h = 2, map = { {1, 1}, {1, 1} } },
|
|
}
|
|
|
|
|
|
local f = io.read("a")
|
|
|
|
local jets = {}
|
|
for j in string.gmatch(f,"[<>]") do
|
|
table.insert( jets, j)
|
|
end
|
|
|
|
function emptiness()
|
|
return {0, 0, 0, 0, 0, 0, 0}
|
|
end
|
|
|
|
local tunnel = {}
|
|
|
|
function tunnel:print()
|
|
for i = #self, 1, -1 do
|
|
local s = ""
|
|
local row = self[i]
|
|
for _, c in ipairs(row) do
|
|
s = s .. (c == 1 and "@" or ( c==2 and "#" or "."))
|
|
end
|
|
print(s)
|
|
end
|
|
end
|
|
|
|
function tunnel:drawShape( shape, shX, shY, color)
|
|
local tunnel = self
|
|
local color = color or 1
|
|
for ly = 1, shape.h do
|
|
local y = ly + shY - 1
|
|
tunnel[y] = tunnel[y] or emptiness()
|
|
for lx = 1, shape.w do
|
|
local x = lx + shX - 1
|
|
tunnel[y][x] = shape.map[ly][lx]==1 and color or tunnel[y][x]
|
|
end
|
|
end
|
|
end
|
|
|
|
function tunnel:clearShape( shape, shX, shY )
|
|
self:drawShape( shape, shX, shY, 0 )
|
|
end
|
|
|
|
function equals( t1, t2 )
|
|
for i = 1, #t1 do
|
|
if t1[i] ~= t2[i] then return false end
|
|
end
|
|
return true
|
|
end
|
|
|
|
local shI = 1
|
|
local jeI = 1
|
|
local erasedRows = 0
|
|
local iFound, iPeriod
|
|
|
|
local i = 1
|
|
while i <= target do
|
|
local shape = shapes[shI]
|
|
local x = 3 -- left
|
|
local y = #tunnel + 4 -- bottom
|
|
for i = 1, 3 do
|
|
table.insert( tunnel, emptiness() )
|
|
end
|
|
|
|
repeat -- moving loop
|
|
tunnel:drawShape( shape, x, y )
|
|
|
|
-- jet
|
|
local jet = jets[jeI]
|
|
local inc = jet=="<" and -1 or 1
|
|
local canMove = false
|
|
if (inc == -1 and x > 1 ) or ( inc == 1 and x + shape.w - 1 < 7) then
|
|
canMove = true
|
|
for lx = 1, shape.w do
|
|
local shX = lx + x - 1
|
|
for ly = 1, shape.h do
|
|
local shY = ly + y - 1
|
|
if tunnel[shY][shX+inc] == 2 and shape.map[ly][lx]==1 then
|
|
canMove = false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if canMove then
|
|
tunnel:clearShape( shape, x, y )
|
|
x = x + inc
|
|
tunnel:drawShape( shape, x, y )
|
|
end
|
|
|
|
jeI = (jeI == #jets) and 1 or (jeI + 1)
|
|
|
|
-- down
|
|
canMove = (y > 1)
|
|
if canMove then
|
|
for lx = 1, shape.w do
|
|
local shX = lx + x - 1
|
|
for ly = 1, shape.h do
|
|
local shY = ly + y - 1
|
|
if tunnel[shY-1][shX] == 2 and shape.map[ly][lx]==1 then
|
|
canMove = false
|
|
break
|
|
end
|
|
end
|
|
if not canMove then break end
|
|
end
|
|
end
|
|
|
|
if canMove then
|
|
tunnel:clearShape( shape, x, y )
|
|
y = y - 1
|
|
tunnel:drawShape( shape, x, y )
|
|
end
|
|
until not canMove
|
|
|
|
-- stopped shape
|
|
tunnel:drawShape( shape, x, y, 2)
|
|
|
|
-- clean tunnel
|
|
repeat
|
|
local emptyRow = true
|
|
local ind = #tunnel
|
|
for _, c in ipairs( tunnel[ind] ) do
|
|
if c > 0 then
|
|
emptyRow = false
|
|
break
|
|
end
|
|
end
|
|
if emptyRow then
|
|
table.remove( tunnel )
|
|
end
|
|
until not emptyRow or #tunnel == 0
|
|
|
|
-- check for repetition
|
|
local period
|
|
for size = 10, #tunnel/2 do
|
|
local equal = true
|
|
for j = 1, size do
|
|
local tail = tunnel[ #tunnel - j + 1 ]
|
|
local tail2 = tunnel[ #tunnel - size - j + 1 ]
|
|
if not equals(tail, tail2) then
|
|
equal = false
|
|
break
|
|
end
|
|
end
|
|
if equal then
|
|
period = size
|
|
|
|
for i = 1,period do
|
|
table.remove(tunnel)
|
|
end
|
|
erasedRows = erasedRows + period
|
|
|
|
if not iFound then
|
|
iFound = i
|
|
elseif not iPeriod then
|
|
iPeriod = i - iFound
|
|
-- jump ahead!
|
|
local remaining = target - i
|
|
local advance = remaining // iPeriod
|
|
local outOfIPeriod = remaining % iPeriod
|
|
erasedRows = erasedRows + advance*period
|
|
i = target - outOfIPeriod
|
|
end
|
|
-- print(i, iFound, period, iPeriod, #tunnel )
|
|
|
|
break
|
|
end
|
|
end
|
|
|
|
shI = (shI == #shapes) and 1 or (shI + 1)
|
|
|
|
i = i + 1
|
|
end
|
|
|
|
print("result ", #tunnel + erasedRows)
|