Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local grid = {}
- local elves = {}
- local y = 1
- local minx, miny, maxx, maxy = math.huge, math.huge, 0, 0
- for line in io.lines(arg[1]) do
- local row = {}
- local x = 1
- for c in line:gmatch(".") do
- table.insert(row, c == "#" and true or false)
- if c == "#" then
- table.insert(elves, {x, y, nil, nil})
- maxx = math.max(maxx, x)
- maxy = math.max(maxy, y)
- minx = math.min(minx, x)
- miny = math.min(miny, y)
- end
- x = x + 1
- end
- table.insert(grid, row)
- y = y + 1
- end
- local prio = {
- {{{0,-1}, {1,-1}, {-1,-1}}, 0, -1},
- {{{0,1}, {1,1}, {-1,1}}, 0, 1},
- {{{-1,0}, {-1,1}, {-1,-1}}, -1, 0},
- {{{1,0}, {1,1}, {1,-1}}, 1, 0},
- }
- local function isAlone(x, y)
- for dy = -1, 1 do
- for dx = -1, 1 do
- if not (dy == 0 and dx == 0) then
- grid[y+dy] = grid[y+dy] or {}
- if grid[y+dy][x+dx] then return false end
- end
- end
- end
- return true
- end
- local function move(x, y)
- for _, dir in ipairs(prio) do
- local valid = true
- for _, v in ipairs(dir[1]) do
- grid[y+v[2]] = grid[y+v[2]] or {}
- if grid[y+v[2]][x+v[1]] then valid = false break end
- end
- if valid then return x+dir[2], y+dir[3] end
- end
- return x, y
- end
- local function step(elves)
- local moved = false
- local newElves = {}
- local chosen = {}
- for i, elf in ipairs(elves) do
- if not isAlone(elf[1], elf[2]) then
- local newx, newy = move(elf[1], elf[2])
- chosen[newy] = chosen[newy] or {}
- chosen[newy][newx] = (chosen[newy][newx] or 0) + 1
- elves[i][3] = newx
- elves[i][4] = newy
- end
- end
- for _, elf in ipairs(elves) do
- if (not elf[3]) or chosen[elf[4]][elf[3]] > 1 then
- table.insert(newElves, {elf[1], elf[2], nil, nil})
- elseif chosen[elf[4]][elf[3]] == 1 then
- moved = true
- grid[elf[2]][elf[1]] = false
- grid[elf[4]][elf[3]] = true
- minx = math.min(minx, elf[3])
- miny = math.min(miny, elf[4])
- maxx = math.max(maxx, elf[3])
- maxy = math.max(maxy, elf[4])
- table.insert(newElves, {elf[3], elf[4], nil, nil})
- end
- end
- table.insert(prio, table.remove(prio,1))
- return newElves, moved
- end
- local moved
- for _ = 1, 100000 do
- elves, moved = step(elves)
- if _ == 10 then
- local count = 0
- for y = miny, maxy do
- for x = minx, maxx do
- if not grid[y][x] then count = count + 1 end
- end
- end
- print(count)
- end
- if not moved then print(_) break end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement