field = {} for line in io.lines(arg[1]) do row = {} for char in line:gmatch(".") do table.insert(row, char) end table.insert(field, row) end function hash(field) local res = 0 for y, row in ipairs(field) do for x, cell in ipairs(row) do local data = 0 if cell == "#" then data = 2 ^ ((y - 1) * #row + (x - 1)) end res = res + data end end return res end function next_field(field) local new = {} for y, row in ipairs(field) do local new_row = {} for x, cell in ipairs(row) do local adjacent = 0 if field[y - 1] and field[y - 1][x] == "#" then adjacent = adjacent + 1 end if field[y + 1] and field[y + 1][x] == "#" then adjacent = adjacent + 1 end if field[y][x - 1] == "#" then adjacent = adjacent + 1 end if field[y][x + 1] == "#" then adjacent = adjacent + 1 end if cell == "#" then if adjacent ~= 1 then cell = "." end else if adjacent == 1 or adjacent == 2 then cell = "#" end end table.insert(new_row, cell) end table.insert(new, new_row) end return new end field_orig = {table.unpack(field)} hashes = {} while true do cur_hash = hash(field) if hashes[cur_hash] then break end hashes[cur_hash] = true field = next_field(field) end for _, row in ipairs(field) do for _, cell in ipairs(row) do io.stdout:write(cell) end io.stdout:write("\n") end print("Part 1:", hash(field)) field = field_orig