m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2020-12-25 15:48:06 +0100
committerMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2020-12-25 15:48:06 +0100
commitca0df3d74d675743b92d62207b0fe107af767d30 (patch)
treeca6ade7312f09dd24574593794c448cc73b54f83
parente2e8223c6bd35483a17fd803fc1622a1f09ef80c (diff)
Add day 20
-rw-r--r--20/a.lua95
-rw-r--r--20/b-combine.lua233
-rw-r--r--20/b-find.lua108
-rw-r--r--20/b.sh2
-rw-r--r--20/input.txt1728
5 files changed, 2166 insertions, 0 deletions
diff --git a/20/a.lua b/20/a.lua
new file mode 100644
index 0000000..ee469d1
--- /dev/null
+++ b/20/a.lua
@@ -0,0 +1,95 @@
+tiles = {}
+
+current_tile_number = nil
+current_tile = {}
+
+function border(tile, horizontal, index)
+ first_column = 0
+ first_row = 0
+ last_column = 0
+ last_row = 0
+ if horizontal then
+ first_column = 1
+ last_column = #tile[1]
+ first_row = index
+ last_row = index
+ else
+ first_column = index
+ last_column = index
+ first_row = 1
+ last_row = #tile
+ end
+
+ b = ''
+ for row = first_row, last_row do
+ for column = first_column, last_column do
+ b = b .. tile[row][column]
+ end
+ end
+
+ if (horizontal and index > 1) or (not horizontal and index == 1) then
+ b = b:reverse()
+ end
+
+ return b
+end
+
+function borders(tile)
+ return {
+ border(tile, true, 1),
+ border(tile, true, 10),
+ border(tile, false, 1),
+ border(tile, false, 10)
+ }
+end
+
+for line in io.lines('input.txt') do
+ if line == "" and current_tile_number then
+ tiles[current_tile_number] = current_tile
+ current_tile = {}
+ end
+
+ space_index = line:find(' ')
+
+ if space_index then
+ current_tile_number = line:sub(space_index+1, -2)
+ elseif #line > 0 then
+ row = {}
+ for i = 1, line:len() do
+ table.insert(row, line:sub(i, i))
+ end
+ table.insert(current_tile, row)
+ end
+end
+
+border_counts = {}
+for _, tile in pairs(tiles) do
+ for _, border in pairs(borders(tile)) do
+ if not border_counts[border] then
+ border_counts[border] = 0
+ end
+ border_counts[border] = border_counts[border] + 1
+ end
+end
+
+corners = {}
+for number,tile in pairs(tiles) do
+ count_neighboorless = 0
+ for _, border in pairs(borders(tile)) do
+ has_flipped_neighbor = border_counts[border] > 1
+ has_non_flipped_neighbor = border_counts[border:reverse()]
+ if not (has_flipped_neighbor or has_non_flipped_neighbor) then
+ count_neighboorless = count_neighboorless + 1
+ end
+ end
+ if count_neighboorless == 2 then
+ table.insert(corners, number)
+ end
+end
+
+product = 1
+for i,c in pairs(corners) do
+ product = product * c
+end
+
+print(product)
diff --git a/20/b-combine.lua b/20/b-combine.lua
new file mode 100644
index 0000000..f5d176c
--- /dev/null
+++ b/20/b-combine.lua
@@ -0,0 +1,233 @@
+Tile = {}
+Tile.__index = Tile
+
+Tile.__tostring = function(self)
+ string = ''
+ for i = 1, 10 do
+ for j = 1, 10 do
+ string = string .. self:get(i, j) .. ' '
+ end
+ string = string .. "\n"
+ end
+
+ return string
+end
+
+function id(x, y)
+ return x, y
+end
+
+function Tile:new(tile)
+ local object = {}
+ object.tile = tile
+ object.transform = id
+ return setmetatable(object, self)
+end
+
+function Tile:rotate()
+ local old_transform = self.transform
+ self.transform = function(x, y)
+ return old_transform(y, 10 - x + 1)
+ end
+end
+
+function Tile:flip()
+ local old_transform = self.transform
+ self.transform = function(x, y)
+ return old_transform(x, 10 - y + 1)
+ end
+end
+
+function Tile:get(x, y)
+ x, y = self.transform(x, y)
+ return self.tile[x][y]
+end
+
+function Tile:border(horizontal, index)
+ first_column = 0
+ first_row = 0
+ last_column = 0
+ last_row = 0
+ if horizontal then
+ first_column = 1
+ last_column = 10
+ first_row = index
+ last_row = index
+ else
+ first_column = index
+ last_column = index
+ first_row = 1
+ last_row = 10
+ end
+
+ b = ''
+ for row = first_row, last_row do
+ for column = first_column, last_column do
+ b = b .. self:get(row, column)
+ end
+ end
+
+ if (horizontal and index > 1) or (not horizontal and index == 1) then
+ b = b:reverse()
+ end
+
+ return b
+end
+
+function Tile:borders()
+ return {
+ self:border(true, 1),
+ self:border(true, 10),
+ self:border(false, 1),
+ self:border(false, 10)
+ }
+end
+
+Board = {}
+Board.__index = Board
+
+function Board:new(corner)
+ object = {}
+ object.board = {}
+ object.board[1] = {}
+ object.board[1][1] = corner
+ return setmetatable(object, self)
+end
+
+function Board:try_add(x, y, tile)
+ if not self.board[x] then self.board[x] = {} end
+ local reference_tile = self.board[x][y - 1]
+ below = false
+ if not reference_tile then
+ below = true
+ reference_tile = self.board[x - 1][y]
+ end
+
+ assert(reference_tile, "tried to insert tile at non-connected location")
+
+ orientation_matches = function() return false end
+ if below then
+ orientation_matches = function()
+ return reference_tile:border(true, 10) == tile:border(true, 1):reverse()
+ end
+ else
+ orientation_matches = function()
+ return reference_tile:border(false, 10) == tile:border(false, 1):reverse()
+ end
+ end
+
+ correctly_rotated = false
+ for i = 1, 4 do
+ if orientation_matches() then
+ correctly_rotated = true
+ break
+ end
+ tile:rotate()
+ end
+
+ if not correctly_rotated then
+ tile:flip()
+ for i = 1, 4 do
+ if orientation_matches() then
+ correctly_rotated = true
+ break
+ end
+ tile:rotate()
+ end
+ end
+
+ if correctly_rotated then
+ if not self.board[x] then
+ self.board[x] = {}
+ end
+ self.board[x][y] = tile
+ end
+
+ return correctly_rotated
+end
+
+tiles = {}
+current_tile_number = nil
+current_tile = {}
+
+for line in io.lines('input.txt') do
+ if line == "" and current_tile_number then
+ tiles[current_tile_number] = Tile:new(current_tile)
+ current_tile = {}
+ end
+
+ space_index = line:find(' ')
+
+ if space_index then
+ current_tile_number = line:sub(space_index+1, -2)
+ elseif #line > 0 then
+ row = {}
+ for i = 1, line:len() do
+ table.insert(row, line:sub(i, i))
+ end
+ table.insert(current_tile, row)
+ end
+end
+
+corner = '1327'
+corner_tile = tiles[corner]
+corner_tile:flip()
+
+board = Board:new(tiles[corner])
+
+handled = {}
+handled[corner] = true
+
+visited = {}
+visited[1] = {}
+visited[1][1] = true
+visited[2] = {}
+visited[2][1] = true
+visited[1][2] = true
+
+queue = {}
+table.insert(queue, {1, 2})
+table.insert(queue, {2, 1})
+while #queue ~= 0 do
+ current = table.remove(queue, 1)
+ x = current[1]
+ y = current[2]
+ inserted = false
+ for tile_id, tile in pairs(tiles) do
+ if not handled[tile_id] then
+ if board:try_add(x, y, tile) then
+ assert(board.board[x][y])
+ inserted = true
+ handled[tile_id] = true
+
+ if not visited[x] then visited[x] = {} end
+ if not visited[x + 1] then visited[x + 1] = {} end
+ if x < 12 and not visited[x + 1][y] then
+ table.insert(queue, {x + 1, y})
+ visited[x + 1][y] = true
+ end
+ if y < 12 and not visited[x][y + 1] then
+ table.insert(queue, {x, y + 1})
+ visited[x][y + 1] = true
+ end
+ break
+ end
+ end
+ end
+ if not inserted then
+ print('failed')
+ break
+ end
+end
+
+for i = 1, 12 do
+ for x = 2, 9 do
+ for j = 1, 12 do
+ local tile = board.board[i][j]
+ for y = 2, 9 do
+ io.write(tile:get(x, y))
+ end
+ end
+ print()
+ end
+end
diff --git a/20/b-find.lua b/20/b-find.lua
new file mode 100644
index 0000000..800fc6e
--- /dev/null
+++ b/20/b-find.lua
@@ -0,0 +1,108 @@
+function parse_row(line)
+ row = {}
+ for i = 1, #line do
+ table.insert(row, line:sub(i, i))
+ end
+ return row
+end
+Map = {}
+Map.__index = Map
+
+Map.__tostring = function(self)
+ string = ''
+ for i = 1, 96 do
+ for j = 1, 96 do
+ string = string .. self:get(i, j) .. ' '
+ end
+ string = string .. "\n"
+ end
+
+ return string
+end
+
+function Map:get(x, y)
+ x, y = self.transform(x, y)
+ return self.map[x][y]
+end
+
+function id(x, y)
+ return x, y
+end
+
+function Map:new(map)
+ local object = {}
+ object.map = map
+ object.transform = id
+ return setmetatable(object, self)
+end
+
+function Map:rotate()
+ local old_transform = self.transform
+ self.transform = function(x, y)
+ return old_transform(y, 96 - x + 1)
+ end
+end
+
+function Map:flip()
+ local old_transform = self.transform
+ self.transform = function(x, y)
+ return old_transform(x, 96 - y + 1)
+ end
+end
+
+function Map:has_monster(x, y)
+ if x + #monster > 96 then
+ print('x too large')
+ return false
+ end
+ if y + #monster[1] > 96 then
+ print('y too large')
+ return false
+ end
+ for i = 1, #monster do
+ for j = 1, #monster[1] do
+ if monster[i][j] == '#' and self:get(x+i, y+j) ~= '#' then
+ return false
+ end
+ end
+ end
+
+ return true
+end
+
+monster = {}
+monster[1] = parse_row(' # ')
+monster[2] = parse_row('# ## ## ###')
+monster[3] = parse_row(' # # # # # # ')
+
+map = {}
+for line in io.lines('combined') do
+ table.insert(map, parse_row(line))
+end
+
+map = Map:new(map)
+map:flip()
+map:rotate()
+map:rotate()
+map:rotate()
+
+count = 0
+for x = 1, 96 - #monster do
+ for y = 1, 96 - #monster[1] do
+ if map:has_monster(x, y) then
+ count = count + 1
+ end
+ end
+end
+
+hashes = 0
+for i = 1, 96 do
+ for j = 1, 96 do
+ if map.map[i][j] == '#' then
+ hashes = hashes + 1
+ end
+ end
+end
+
+result = hashes - count * 15
+print(result)
diff --git a/20/b.sh b/20/b.sh
new file mode 100644
index 0000000..b9411f1
--- /dev/null
+++ b/20/b.sh
@@ -0,0 +1,2 @@
+lua b-combine.lua > combined
+lua b-find.lua
diff --git a/20/input.txt b/20/input.txt
new file mode 100644
index 0000000..e2f04ac
--- /dev/null
+++ b/20/input.txt
@@ -0,0 +1,1728 @@
+Tile 1487:
+.##..#...#
+##.##.....
+...#....##
+##..#..#.#
+.####....#
+.#.#..#..#
+..##.....#
+..##....##
+#.....#..#
+...#..####
+
+Tile 3637:
+##...#....
+#.#..#...#
+....##...#
+#.........
+#......#.#
+##...#.#..
+#.........
+##.....###
+##.#......
+##.#.##..#
+
+Tile 3433:
+.....#..#.
+##..##...#
+....#.....
+.........#
+#........#
+#..##..###
+#..#..##..
+#...##.#..
+.#...#..#.
+#.##....#.
+
+Tile 3931:
+#....##..#
+...#..###.
+#...#..#.#
+.......#..
+#.......#.
+###......#
+###.#.#..#
+.##..#..#.
+...##..#.#
+..##..#.#.
+
+Tile 2213:
+.###...##.
+..##......
+..........
+.##...#...
+...##...#.
+..#.#..#.#
+..##......
+#..#.#.###
+...#......
+#.#..##...
+
+Tile 1901:
+.#.##.#.#.
+#.........
+#.##..#.##
+...###...#
+.....#.#.#
+.#.....#..
+....#.#...
+..#...#..#
+#........#
+####.###..
+
+Tile 3917:
+.##.#..#.#
+#.##....#.
+#.....#...
+#.#...#.##
+..........
+..........
+.#....#.#.
+.........#
+.....#....
+#.#.##....
+
+Tile 1831:
+.#..#..##.
+#.....##..
+###....###
+.#.#.##..#
+#....#...#
+......#.#.
+.....#..##
+#..##.....
+####.#.##.
+...##.#..#
+
+Tile 3557:
+..#.#.#.#.
+##........
+.......#..
+.##.......
+..........
+....#..#..
+#...#....#
+#..#####.#
+#..#...##.
+#.....###.
+
+Tile 2659:
+####.##.#.
+.##.##...#
+####..#...
+##........
+####......
+.......#.#
+###....#..
+.....#..##
+#....#...#
+.#..###.#.
+
+Tile 3061:
+.#..#.#..#
+........#.
+##.#....#.
+###....#..
+.........#
+..#..#....
+....#..#.#
+.#.##...##
+##.#....##
+.#.#.##.##
+
+Tile 3593:
+###.#.####
+.#........
+#..#....#.
+.......###
+.#....##.#
+....#..##.
+#.#.....##
+#..#...#..
+.#......#.
+#....##..#
+
+Tile 2719:
+..###.#..#
+..##...##.
+..##.....#
+#.......#.
+...#....##
+#.#....#..
+#.......#.
+#..#.....#
+........##
+.#.#..##.#
+
+Tile 3089:
+##.#.#.#.#
+.#..#....#
+.#.#.....#
+##...#.#.#
+.......#..
+###..####.
+....#.....
+........#.
+.#.....##.
+..####..#.
+
+Tile 1723:
+..#.##.###
+#..###.#.#
+..#..#...#
+....#.#...
+....#....#
+#....#....
+#.....#...
+#.#..#.#..
+#...###..#
+###.####..
+
+Tile 2297:
+.##....#.#
+####..#.##
+#.##...##.
+#.##...#.#
+###.##..##
+....#...##
+##....##.#
+..##...##.
+##.#.#..#.
+#...#.##..
+
+Tile 3659:
+.#####....
+....#.#.##
+.#..#....#
+....#....#
+.....#...#
+.....#..##
+##..#.....
+##...#....
+####....##
+##......#.
+
+Tile 1847:
+###.#.####
+..##.....#
+#.......#.
+##......#.
+..#.#.....
+#.......#.
+.#..#...#.
+.#......#.
+#.....###.
+##.###.##.
+
+Tile 1601:
+#.#.##.###
+.#..#...#.
+##...#..#.
+#.#####..#
+.......#.#
+##..##.##.
+..#.#..#..
+..###....#
+.....#...#
+....#####.
+
+Tile 3323:
+..#..##.##
+##......##
+###.#...#.
+.#..#..#..
+#...#..###
+#....##...
+##.....#.#
+...####...
+....#.....
+..##....##
+
+Tile 1321:
+###.######
+#...#.#..#
+##........
+#..#..#.#.
+..##.#..#.
+.........#
+.#.......#
+#..#......
+##.#.....#
+.###...#.#
+
+Tile 2551:
+....##...#
+...#.##...
+.##.......
+...#..#...
+#.#...##.#
+#..##.#...
+.##..#.##.
+##....#..#
+...#.....#
+..#.#.#.#.
+
+Tile 2503:
+...#..##.#
+.........#
+#.#....##.
+#.........
+##..#.#...
+#...#..#..
+...#......
+.##.##....
+#.........
+###.....##
+
+Tile 1163:
+#.####..#.
+.##.#.#...
+#.#..#####
+......#...
+##....#..#
+#.......##
+#.#.##..#.
+##...###.#
+#.........
+.##.#...##
+
+Tile 1039:
+#.###.#.#.
+.##......#
+.#...#..#.
+.#...#...#
+#.#...#..#
+##.#...#..
+#.##......
+#.#.#..#..
+##...#..##
+#.####..##
+
+Tile 2953:
+...#.#.#.#
+..#.#.....
+.........#
+#..#...#.#
+......#...
+.........#
+....#..#..
+.###....#.
+##.##..###
+..####.#..
+
+Tile 1609:
+...#...#..
+#....##..#
+...###.#..
+#.##.##..#
+#.#.##.#..
+##.......#
+.##...#..#
+#....#....
+........#.
+.....#..#.
+
+Tile 1187:
+####.##...
+..........
+.....#...#
+#.#......#
+#....#.###
+.#..###.#.
+##...#....
+......#..#
+....#.#..#
+#####...##
+
+Tile 3313:
+#######..#
+#.#...####
+..........
+#.#..##...
+###......#
+##........
+##......##
+##..#.#...
+..#..#..#.
+#..#...##.
+
+Tile 3221:
+....#.#.#.
+##..#.....
+.#.##..#..
+#..##..#.#
+....#....#
+##.......#
+#.......#.
+#.###...##
+#..#......
+#....##...
+
+Tile 2647:
+.##.#.####
+..#.......
+#...##....
+#..#....##
+......#...
+..##......
+.#.....#.#
+###.##....
+###...###.
+##.#.#..#.
+
+Tile 2879:
+#.#.#..###
+......####
+##....#.#.
+.#.......#
+....##..#.
+#..#.###.#
+#.........
+##.......#
+#...##...#
+..#...##.#
+
+Tile 2423:
+.###.#..#.
+..###.##..
+..#.#...##
+#....#...#
+#..#.##...
+#..#....##
+.....#....
+##.##....#
+....#....#
+...#..#.#.
+
+Tile 2557:
+.#..#..##.
+#....##.##
+...#.#...#
+#...####..
+#........#
+...#....##
+..........
+.##..#.##.
+#.#..#...#
+.###..#.#.
+
+Tile 2819:
+..#......#
+#....#....
+##..#...##
+#......###
+#..##.....
+#.###.#...
+.##...####
+..........
+#........#
+#...##.#.#
+
+Tile 2531:
+....#.#..#
+..#..#..#.
+#....#...#
+#..#..#..#
+.........#
+#.#.......
+#......###
+#.#...##..
+#....###.#
+.#.#####.#
+
+Tile 1109:
+..#.#.#.##
+.....#....
+#...##.#.#
+##.##.#...
+.........#
+.#..#.#..#
+#.........
+.##...#..#
+#.#..#..#.
+.#.###.#..
+
+Tile 1103:
+#..##.#...
+.###......
+#..#.....#
+.....###.#
+.#..#.##.#
+......##.#
+#...##.#..
+...#...###
+.##..#.##.
+.#.#.#..#.
+
+Tile 2713:
+.###.##...
+#.##...#.#
+.....#...#
+#.........
+##...#..##
+.###.#.##.
+#.#..##.##
+#...#..##.
+...#...##.
+.....#.##.
+
+Tile 2927:
+##..#...#.
+...#..#..#
+#..#..#...
+.....#.#..
+##.......#
+...##.##.#
+#.#.......
+.###....#.
+....#.####
+####.###.#
+
+Tile 3319:
+....#.#.##
+#.###..###
+.#....#.#.
+.....#..#.
+.##....#..
+....#...##
+#.#...#...
+.......#..
+#.#.###.#.
+......##..
+
+Tile 2311:
+#.#.##...#
+..#....#..
+..#..#..#.
+..#.#.#.##
+......####
+..#..#..##
+##....##.#
+.#..#.....
+.....##..#
+...##.....
+
+Tile 1549:
+##.#.#.#.#
+##..#...#.
+.#....#...
+.#....##.#
+..#..###.#
+#....#..##
+.#.......#
+#.....#.##
+.....#....
+#.#...#.#.
+
+Tile 3631:
+...#.###.#
+........#.
+###..##..#
+###.....#.
+##....##.#
+....#.....
+###.#.#...
+...#..#...
+##..#....#
+....##..#.
+
+Tile 1787:
+#.##.##.#.
+....#...#.
+#..#..#..#
+...#.....#
+#.##.#....
+##.......#
+#.....#...
+#...##.#..
+.#.##.#..#
+###.#....#
+
+Tile 3467:
+########.#
+##...#.#.#
+...#......
+.....#.#.#
+#.....#..#
+#........#
+...#......
+..#.....##
+.#.##..#..
+..#.....#.
+
+Tile 3373:
+##..#.#..#
+...#......
+###.##..#.
+#........#
+.#...#...#
+#....##...
+.#.....#..
+.#....#..#
+#.#..####.
+...####.#.
+
+Tile 3911:
+#.###.#..#
+.##......#
+...#......
+#...#..##.
+.......#.#
+#.#......#
+...##..#.#
+##..#..#.#
+#......##.
+#####..###
+
+Tile 1327:
+...#.#..#.
+.........#
+#..#...#..
+#........#
+###.#.....
+.........#
+##.#......
+#........#
+#..#...#.#
+.#.##..##.
+
+Tile 3643:
+.#.#...#.#
+#.##....#.
+#..#...#..
+....##....
+#....##.##
+..........
+#...#.#.##
+##.#..#..#
+...#....##
+..##..#..#
+
+Tile 2447:
+#...#.###.
+#.....#..#
+#.#.......
+###..#...#
+.....##.##
+#....#...#
+#.#.#.....
+#.....#...
+...##.....
+.#.###.##.
+
+Tile 3181:
+.###..#...
+##...#.#.#
+#..#......
+#......#.#
+.#...##.#.
+#.#......#
+.........#
+.........#
+#.#...#...
+##.##.#.#.
+
+Tile 3037:
+#########.
+...#.#...#
+.##......#
+.#........
+#....#...#
+#..#..#.#.
+...###.#.#
+#.#...#.##
+##..#.#..#
+#..#.##.#.
+
+Tile 3671:
+##.#.#....
+........#.
+##.#....#.
+#.##.#.#.#
+##....##..
+.##...#.#.
+.#.#...#..
+##...##..#
+#.#....###
+##.#..###.
+
+Tile 2909:
+.##...###.
+#.....#..#
+.#..#.....
+#.###.#.##
+#.##.#.##.
+..#......#
+.#..#.#...
+#..#..#.#.
+.#.#...#..
+.###..##.#
+
+Tile 3571:
+..#.#.#..#
+#....#....
+.....##..#
+.....###.#
+....#.#...
+......#..#
+#.......##
+..........
+..#.##..#.
+##.##.##.#
+
+Tile 1931:
+###.##...#
+#...#.#...
+#..#..#.##
+..##......
+...##....#
+#.#.##..##
+#.##.....#
+#..#......
+..#..#.#.#
+....##.#.#
+
+Tile 2689:
+#....#.##.
+....#...##
+......##..
+#....#...#
+........#.
+..........
+##.#.###..
+..#.......
+....##....
+...#.#..##
+
+Tile 3499:
+.#.###.#.#
+......#..#
+..#......#
+.#......#.
+##.......#
+##...##...
+.#......#.
+#......#..
+#....#....
+###.######
+
+Tile 1277:
+...##.#...
+......#..#
+###......#
+#.........
+..##.....#
+#.#....###
+#.........
+#..#.....#
+#.........
+###.#.#...
+
+Tile 2633:
+.#..#.##..
+#........#
+......#..#
+..#.......
+.##....#.#
+#.......#.
+.#.##.....
+#.........
+........#.
+##.#.#####
+
+Tile 1699:
+.##.#..##.
+#..##.....
+...#...##.
+..#....#..
+#..#..##.#
+..#.....##
+.##......#
+..#....#..
+#..###..#.
+#..#.####.
+
+Tile 2339:
+.#.#####..
+##.#...#..
+..##.#....
+.###....#.
+#..##....#
+#.........
+.....#....
+#...#....#
+#..##...#.
+#....##...
+
+Tile 1993:
+.####.....
+.....#..#.
+..#.#..#.#
+#........#
+...##.#.#.
+..#.#.#..#
+.###.##.#.
+..#.#..#..
+....#####.
+..#.#...##
+
+Tile 2467:
+.####..#.#
+#####.....
+##...##...
+#....##.##
+.....###..
+#....###.#
+......#..#
+....##.#..
+....##.#..
+..#...#.#.
+
+Tile 2153:
+.##.##.#.#
+.........#
+....#..##.
+...#......
+#..#....##
+....#....#
+..##.#...#
+........#.
+##..#.##.#
+..#.##....
+
+Tile 1867:
+.#....####
+#...#....#
+....#..#..
+.#.....###
+....#..#.#
+#..#..#..#
+....#...#.
+.....#...#
+.....##...
+.##..#.#.#
+
+Tile 2111:
+..#.#..###
+.....#....
+..#.#.##..
+.#.......#
+..#.......
+..#..#.#..
+.#.....#..
+....#....#
+##.#...#..
+####.##...
+
+Tile 3307:
+.#.#..####
+###..#.#..
+........##
+.....#..#.
+.#....##..
+###.#....#
+.#........
+.......#..
+#.#.....##
+..#.#..##.
+
+Tile 1061:
+##.##.....
+#..#.#..#.
+..#....#..
+#.....#..#
+#.#..#...#
+#.....####
+#....#....
+##......##
+......##.#
+##...##...
+
+Tile 1021:
+##.###.##.
+.#....#..#
+#.....#..#
+#..#..##.#
+##.....#.#
+#.#....##.
+..#.....#.
+.#.....#.#
+.#..#.....
+.....#.##.
+
+Tile 3677:
+.#...#...#
+..........
+....###...
+.######..#
+..#...#...
+#...#.#...
+##.......#
+..#......#
+.#..#....#
+#..##.####
+
+Tile 1231:
+#.###.##..
+..#.......
+#..#.....#
+#..#.....#
+.#.....#.#
+##......##
+.#.###....
+..#....###
+##.....#.#
+##.....#..
+
+Tile 3301:
+.........#
+.#..#....#
+##.#...#.#
+..#..#...#
+.##....##.
+..#...#...
+##.##....#
+#..#.#....
+.....#..##
+#...#..###
+
+Tile 2861:
+.....#.###
+.#####.###
+###.#...#.
+##..###..#
+..........
+##...#.#..
+##..#..#..
+.##..#...#
+#.....#...
+.....###..
+
+Tile 3823:
+.##.##.###
+..#.#.....
+#.#####.#.
+.#......##
+#.#..#.#.#
+...#..##.#
+##..##...#
+....#..#..
+....#....#
+##.#......
+
+Tile 2027:
+.#.#..#..#
+....#.....
+.#..##....
+#..###..##
+#...#.....
+#...#...##
+.#........
+##.##.#...
+.....#.#..
+###..##.##
+
+Tile 3673:
+....####.#
+.#...###.#
+....#..#..
+.#.#.#....
+..#..#....
+#....##.#.
+.....#....
+#...#....#
+#..#.#....
+###.#.#...
+
+Tile 1777:
+.####.####
+#..#....#.
+....###...
+.....#.#..
+....#.....
+.#........
+##.#.....#
+.#.......#
+.#...#...#
+.####.#.##
+
+Tile 2609:
+.#.#####..
+......#..#
+#.#.#.....
+..##...#..
+....#....#
+#....#...#
+..#.#...##
+#...#...##
+#..#.....#
+###..#....
+
+Tile 2687:
+##...#.#.#
+.####.....
+#.#..#..#.
+#...##...#
+#....#.##.
+.##......#
+#..##..#..
+.#.#.#..#.
+#.#.##..##
+##..#...#.
+
+Tile 1451:
+######.#..
+##.###...#
+...##.....
+#..##...#.
+.....#..#.
+#..#..#...
+..#...#...
+##..##...#
+#......##.
+..#..#.#..
+
+Tile 3251:
+.####..##.
+#.........
+##..###...
+#......#..
+##..##..#.
+..........
+#........#
+#........#
+..##.#.###
+........#.
+
+Tile 3391:
+..#######.
+#..#.#...#
+.......#..
+#...#....#
+#.....#..#
+##........
+#.....#..#
+.....#..##
+..###...##
+.#..#.#.#.
+
+Tile 1129:
+.##..#.#..
+##.#.#....
+###...#..#
+..........
+......####
+..........
+##...#...#
+#.#...#.##
+#.........
+###...####
+
+Tile 2087:
+..###.#...
+#...##...#
+...#.....#
+..##...#..
+##.....#.#
+####.....#
+..#.#..#..
+#.#.##....
+..###....#
+.#.#.##.#.
+
+Tile 1361:
+#...######
+...#......
+#.#.#.#..#
+#.....#.##
+....#...##
+#.......##
+#......#..
+#.....#..#
+..#....#.#
+.....##.#.
+
+Tile 1583:
+#.#..##.#.
+#..#.#....
+#...#..#..
+##.....#.#
+#...#.#...
+...###....
+..#..#.##.
+...####..#
+#....#....
+#..#.##.#.
+
+Tile 3361:
+.###.#####
+.##..#...#
+.....##...
+#.#....#..
+#..#...#..
+.........#
+#........#
+..#.......
+#.###.....
+#...###...
+
+Tile 3463:
+.....###.#
+...##.#..#
+.#...#....
+###.##..#.
+#.###...#.
+#..#..#...
+#..##.....
+#..#...#.#
+#........#
+.###..#.#.
+
+Tile 1997:
+#.##....#.
+..#...#...
+#........#
+.....#.#.#
+.#...#....
+#..#.#....
+##...#....
+##.....#.#
+#.........
+#.......##
+
+Tile 2131:
+.##.##.#..
+...#.#...#
+###.####.#
+......###.
+.#.#..#.##
+..#..#.###
+......#.##
+..##..#..#
+...#.#....
+###.####..
+
+Tile 3943:
+###..#####
+.#.#...#.#
+##..#.#.##
+#..#....##
+#...#....#
+#..#..##.#
+..#....##.
+#.......##
+#.........
+..##...##.
+
+Tile 1481:
+.###...#.#
+####.##.#.
+.###.##.#.
+...#.#...#
+#...#....#
+.#.....#..
+..##....##
+##.##..###
+.....#...#
+###.##.#.#
+
+Tile 3191:
+..#.###.##
+#...#...#.
+#....#....
+..#.....#.
+...#..#.##
+........##
+#..#......
+#.........
+.#........
+.......##.
+
+Tile 3833:
+......#...
+.......#..
+......#.#.
+...#.....#
+...##.#.#.
+.#.....###
+#..##..#..
+....#....#
+.#..#..#..
+#.##..#.#.
+
+Tile 1627:
+###...####
+#.........
+#..#..###.
+.....##..#
+#....#....
+#.##..##.#
+....#..##.
+...##...#.
+.###..#...
+..#.##.###
+
+Tile 2801:
+#####.###.
+..#.##.###
+.##...##.#
+#.......##
+.......#..
+..........
+......#..#
+#.....#..#
+##..#.###.
+.#..#.#.##
+
+Tile 1889:
+##.#....##
+..###....#
+#..#.....#
+.#......##
+##..#.#...
+....#...##
+......#...
+#.##....#.
+...##..#..
+.##.#.#...
+
+Tile 1823:
+....#.#.#.
+.#........
+#...##...#
+...####..#
+...#...###
+#...#..#..
+#.#..#....
+#...#..#.#
+......#...
+###.###.#.
+
+Tile 2663:
+##.##.#.##
+.#.#.....#
+.#.##....#
+#....#...#
+#..#..##..
+#.###...#.
+.......#.#
+#..#......
+.....#....
+.##...#...
+
+Tile 1091:
+.##...#.##
+#.....#...
+####.....#
+.......#..
+...#......
+#.#..#...#
+#.#.....##
+##......#.
+..#.......
+.#.#...##.
+
+Tile 3163:
+#####..#.#
+####..#.#.
+.##.#..###
+...#....#.
+.........#
+..#......#
+##.....#.#
+#.....#..#
+#..#...#.#
+.####..##.
+
+Tile 1031:
+.#.##.#...
+##.##..#.#
+.....#....
+#..#......
+......#...
+.....#.#..
+.....#.#.#
+.#...#....
+.##....##.
+.#.##....#
+
+Tile 2269:
+####.####.
+#.........
+#...##.##.
+..##..#..#
+...#......
+.#....#..#
+#..##....#
+..........
+..#.....#.
+.####...##
+
+Tile 3793:
+.##.#.###.
+.##.##..##
+..#...#.#.
+......#..#
+..####....
+#........#
+#....#...#
+#....#.#..
+.#.#..###.
+#...#.###.
+
+Tile 3079:
+#.#.#.#...
+##..#....#
+..#...#..#
+#..###....
+#.#.......
+..#.#.....
+....#.....
+###.##.###
+...##.....
+...###...#
+
+Tile 3187:
+.##.##.###
+.#.....#.#
+..##.##.#.
+#.###.....
+.##.##..##
+#..#.....#
+#...#.#..#
+..#.#...##
+#........#
+...##.#...
+
+Tile 1553:
+.###.#..#.
+.#..##.#..
+#....#...#
+#....##..#
+#.#.##....
+....#...#.
+.........#
+#..##..#..
+.#......#.
+.###.#.#..
+
+Tile 1049:
+##.#.#.###
+...###.#.#
+...##.....
+#...#.#.#.
+....##....
+.##....#..
+.....#.#.#
+..#..#..#.
+..#.#....#
+....#..##.
+
+Tile 2083:
+.#......##
+...#......
+....#.#...
+...##.#..#
+#...##...#
+.....#...#
+..##.#...#
+#....#..##
+.....#....
+...#..#.#.
+
+Tile 3049:
+.#...##.#.
+.#..#....#
+....#.##..
+##..#.....
+.........#
+#......#..
+...#.#....
+...#.##.#.
+.##...#..#
+.##.##.#.#
+
+Tile 3167:
+..##...###
+#....#..#.
+#.#..#....
+#.........
+#..##..#.#
+..........
+.....#..##
+.#.....##.
+##......##
+.##....#..
+
+Tile 1693:
+.#.###..##
+#.........
+##...#....
+..#....#.#
+...#......
+...#.#...#
+.#.....###
+.....#####
+...##....#
+.#.##.....
+
+Tile 2473:
+....#.##.#
+..#......#
+..#......#
+....#..#.#
+#...#.....
+..#..#..#.
+.##..###.#
+#.#..#....
+#....##...
+#.#..#.###
+
+Tile 3821:
+.#.#####.#
+#.......#.
+#..#.#..##
+##........
+.#.....#.#
+.....#....
+.#.#.....#
+..#..##...
+##..#.....
+##.....###
+
+Tile 3529:
+........#.
+.#....##.#
+#......##.
+#..#...#.#
+##........
+#.#...#...
+...#..#.##
+.#.#..#..#
+#..####..#
+.##..##..#
+
+Tile 1801:
+#####.#.##
+#.#.......
+#.#.#####.
+##.#.....#
+....##.#.#
+#..#.#....
+.#........
+#.#.##...#
+#.#......#
+..#..#...#
+
+Tile 3709:
+.##....#..
+........#.
+....#.....
+##..#.#...
+..#..#.#..
+..#.#.....
+#.........
+#.#.##..##
+....##....
+#.#.#....#
+
+Tile 2707:
+###..##.##
+.#.####..#
+#.#.##.#.#
+#...#.#...
+.......###
+.....##...
+...####...
+###...#...
+.........#
+#.###.##..
+
+Tile 3733:
+##...#.##.
+.....#....
+#......##.
+##........
+##...##...
+#.#...#...
+#......#.#
+#.#....#.#
+#...#.#.##
+.#..#...#.
+
+Tile 1663:
+#.#.#.###.
+....##...#
+...#...#.#
+##...####.
+.#........
+##....#..#
+.....#...#
+#..#...#..
+#######..#
+##.#.#.##.
+
+Tile 2309:
+..##..#...
+...#.....#
+########.#
+#....##..#
+.#..#....#
+..#.#....#
+##.....#.#
+..........
+.#....#.##
+##..#.###.
+
+Tile 1483:
+..#..#...#
+##.#.#....
+#.#....###
+##..#.####
+##.#.#.#.#
+..#.#..##.
+..##.....#
+..#....###
+#..##....#
+..####..##
+
+Tile 2591:
+.#.####.##
+.#.#.....#
+#..##..#..
+#...#.#..#
+##.##.#...
+.....###..
+#....##..#
+#....#..#.
+##.#..##..
+..#..#.#..
+
+Tile 2671:
+...#.###.#
+#.#.....#.
+.#.....#..
+...##.####
+.#.###..##
+.#.#.#.#..
+#...##..#.
+#.......##
+.#....##.#
+.#..##..##
+
+Tile 1051:
+#.#.#.....
+..#..#.##.
+......#..#
+#.#.......
+..#.#.#..#
+.#.##.#..#
+#..#.###.#
+#...#..###
+#.......#.
+...#...###
+
+Tile 1613:
+..##...#.#
+#......#..
+#.#..#..##
+.#.#.#....
+#.####.###
+##..##.#..
+##........
+.#.#...#..
+#.#....#..
+.##...#.##
+
+Tile 3457:
+##.#.##..#
+##.#...#.#
+#..#...#.#
+###....#..
+.#....#...
+#...##..##
+..........
+.........#
+..#..#..#.
+..#..####.
+
+Tile 3739:
+...######.
+#.#.#..##.
+#.#.....#.
+#..#..#.##
+#..#......
+#.#......#
+#..##.....
+#.##.#....
+#.#..#..#.
+#.#.#..##.
+
+Tile 2069:
+....#.###.
+#.#...#.#.
+.##.......
+..#.#.....
+..........
+#...#..#..
+..........
+###...#...
+#...#.###.
+.##.##..##
+
+Tile 3623:
+##..##....
+#..#.#....
+.....#....
+#........#
+.#.....#..
+##..#.#.#.
+#....#...#
+..........
+#.##.....#
+#.....#..#
+
+Tile 3613:
+..#.##..#.
+#...##....
+.........#
+#......#..
+....####.#
+..#.##....
+..#.#...##
+#.#..#....
+#.#...#...
+.#####.#..
+
+Tile 3329:
+##....#.#.
+....#..##.
+..##..#.#.
+.#.##..#..
+#.#.#..#..
+.........#
+.......#..
+#..###...#
+###.#.#.#.
+##.#.#...#
+
+Tile 3209:
+.#.....##.
+....####..
+..........
+..##...#..
+....#...#.
+#...##.#.#
+#.##.###..
+#...#....#
+##........
+..#.#####.
+
+Tile 2351:
+#....#####
+#.....#...
+.....#...#
+#.#..#....
+.#.###...#
+.#...##..#
+#.#......#
+#....##.#.
+...#....##
+#####...#.
+
+Tile 3011:
+#.###....#
+#...#.#..#
+........##
+#.....#...
+..#...#.#.
+......#.##
+.....##..#
+.##..#...#
+#...#.....
+#######.##
+
+Tile 1409:
+#..#..#.#.
+....#..#..
+#...#...##
+#..#.#....
+...##..#.#
+#...#.....
+...#.##.##
+#..##.....
+.#......##
+.#######.#
+
+Tile 2341:
+.#.....##.
+.##..#...#
+.#..#.....
+#........#
+#..#.....#
+###.......
+##.##.#...
+.......#.#
+#.#...#...
+##.#.##...
+
+Tile 1747:
+#.....#...
+..##...#.#
+...###....
+.........#
+.#..##.#..
+#.##.....#
+#.###..#..
+#.#......#
+##..##....
+#.####.#.#
+
+Tile 3881:
+...###....
+.........#
+#...##....
+#...##...#
+#.#.#.#...
+..#..##.#.
+#....#....
+#....##.##
+...#......
+####.##.#.
+
+Tile 1307:
+#####.##..
+#...#..###
+..........
+##.#.....#
+..#.#..##.
+....#.#.#.
+..........
+#.........
+.#.....#..
+.#.#.####.
+
+Tile 3779:
+#.....####
+....#...##
+#...#...#.
+#.....##..
+#.##....#.
+#..#....##
+.......#..
+#.#.#....#
+.#..#.#...
+.##..#....
+
+Tile 2957:
+.....##..#
+..#....#.#
+#..#...##.
+.......###
+...#..#.##
+##......#.
+.#.....##.
+#...##.##.
+#....#.###
+..##.#..##
+