day 18
This commit is contained in:
parent
14ee180067
commit
7d2df3d1f1
|
@ -0,0 +1,110 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
|
||||||
|
class Tile(Enum):
|
||||||
|
EMPTY = 0
|
||||||
|
YARD = 1
|
||||||
|
TREE = 2
|
||||||
|
|
||||||
|
|
||||||
|
def char2tile(char):
|
||||||
|
return {".": Tile.EMPTY,
|
||||||
|
"#": Tile.YARD,
|
||||||
|
"|": Tile.TREE}[char]
|
||||||
|
|
||||||
|
|
||||||
|
def tile2char(tile):
|
||||||
|
return {Tile.EMPTY: ".",
|
||||||
|
Tile.YARD: "#",
|
||||||
|
Tile.TREE: "|"}[tile]
|
||||||
|
|
||||||
|
|
||||||
|
def loadmap(fname):
|
||||||
|
field = {}
|
||||||
|
width = 0
|
||||||
|
height = 0
|
||||||
|
with open(fname) as f:
|
||||||
|
for y, line in enumerate(f.readlines()):
|
||||||
|
height = y
|
||||||
|
for x, char in enumerate(line.strip()):
|
||||||
|
field[(x, y)] = char2tile(char)
|
||||||
|
width = y
|
||||||
|
return field, width + 1, height + 1
|
||||||
|
|
||||||
|
|
||||||
|
def printmap(field, width, height):
|
||||||
|
for y in range(0, height):
|
||||||
|
for x in range(0, width):
|
||||||
|
print(tile2char(field[(x, y)]), end="")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def iterneighbors(field, cx, cy):
|
||||||
|
for y in range(cy - 1, cy + 2):
|
||||||
|
for x in range(cx - 1, cx + 2):
|
||||||
|
if x != cx or y != cy:
|
||||||
|
try:
|
||||||
|
yield field[(x, y)]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def tick(field, width, height):
|
||||||
|
"""
|
||||||
|
Empty => Trees >=3 adj with trees
|
||||||
|
Trees => Yard >=3 adj with yards
|
||||||
|
Yard => Yard >0 adj with yard AND >0 adj with trees
|
||||||
|
Yard => Empty If above rule fails
|
||||||
|
"""
|
||||||
|
newfield = {}
|
||||||
|
for y in range(0, height):
|
||||||
|
for x in range(0, width):
|
||||||
|
counts = defaultdict(int)
|
||||||
|
for tile in iterneighbors(field, x, y):
|
||||||
|
counts[tile] += 1
|
||||||
|
tile = field[(x, y)]
|
||||||
|
if tile == Tile.EMPTY:
|
||||||
|
if counts[Tile.TREE] >= 3:
|
||||||
|
tile = Tile.TREE
|
||||||
|
elif tile == Tile.TREE:
|
||||||
|
if counts[Tile.YARD] >= 3:
|
||||||
|
tile = Tile.YARD
|
||||||
|
elif tile == Tile.YARD:
|
||||||
|
if counts[Tile.YARD] == 0 or counts[Tile.TREE] == 0:
|
||||||
|
tile = Tile.EMPTY
|
||||||
|
newfield[(x, y)] = tile
|
||||||
|
return newfield
|
||||||
|
|
||||||
|
|
||||||
|
def counttypes(field):
|
||||||
|
counts = defaultdict(int)
|
||||||
|
for _, v in field.items():
|
||||||
|
counts[v] += 1
|
||||||
|
return counts
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
field, width, height = loadmap("input.txt")
|
||||||
|
printmap(field, width, height)
|
||||||
|
|
||||||
|
generation = 0
|
||||||
|
while True:
|
||||||
|
# input()
|
||||||
|
generation += 1
|
||||||
|
field = tick(field, width, height)
|
||||||
|
print("Generation", generation)
|
||||||
|
printmap(field, width, height)
|
||||||
|
print()
|
||||||
|
if generation >= 10:
|
||||||
|
break
|
||||||
|
|
||||||
|
counts = counttypes(field)
|
||||||
|
print(counts[Tile.TREE] * counts[Tile.YARD])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,60 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
|
||||||
|
from collections import defaultdict
|
||||||
|
from a import Tile, loadmap, iterneighbors, counttypes
|
||||||
|
|
||||||
|
|
||||||
|
def tick(field, width, height):
|
||||||
|
"""
|
||||||
|
Empty => Trees >=3 adj with trees
|
||||||
|
Trees => Yard >=3 adj with yards
|
||||||
|
Yard => Yard >0 adj with yard AND >0 adj with trees
|
||||||
|
Yard => Empty If above rule fails
|
||||||
|
"""
|
||||||
|
newfield = {}
|
||||||
|
for y in range(0, height):
|
||||||
|
for x in range(0, width):
|
||||||
|
counts = defaultdict(int)
|
||||||
|
for tile in iterneighbors(field, x, y):
|
||||||
|
counts[tile] += 1
|
||||||
|
tile = field[(x, y)]
|
||||||
|
if tile == Tile.EMPTY:
|
||||||
|
if counts[Tile.TREE] >= 3:
|
||||||
|
tile = Tile.TREE
|
||||||
|
elif tile == Tile.TREE:
|
||||||
|
if counts[Tile.YARD] >= 3:
|
||||||
|
tile = Tile.YARD
|
||||||
|
elif tile == Tile.YARD:
|
||||||
|
if counts[Tile.YARD] == 0 or counts[Tile.TREE] == 0:
|
||||||
|
tile = Tile.EMPTY
|
||||||
|
newfield[(x, y)] = tile
|
||||||
|
return newfield
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
field, width, height = loadmap("input.txt")
|
||||||
|
|
||||||
|
# Generations to run: 1000000000
|
||||||
|
# I (manually) noticed it cycles after every X generations: 28
|
||||||
|
# 1000000000 % 28 = 20
|
||||||
|
|
||||||
|
generation = 0
|
||||||
|
|
||||||
|
# Run the first 500 generations
|
||||||
|
while generation <= 500:
|
||||||
|
field = tick(field, width, height)
|
||||||
|
generation += 1
|
||||||
|
|
||||||
|
# Run until our generation minus 20 is a multiple of 28
|
||||||
|
while (generation - 20) % 28 != 0:
|
||||||
|
field = tick(field, width, height)
|
||||||
|
generation += 1
|
||||||
|
|
||||||
|
counts = counttypes(field)
|
||||||
|
total = counts[Tile.TREE] * counts[Tile.YARD]
|
||||||
|
print("Generation", generation, "Total", total)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,50 @@
|
||||||
|
#.##...#....|...#..|...#|...#....|.....|..##.|.|.#
|
||||||
|
||#...##|.|.##....|..#.#......#.#..#......|..#.|.#
|
||||||
|
|......#.##....||..#..||..|.....|..##....|.#.|..|#
|
||||||
|
.|...#||..||#|#.....|#...|.||.||#...#..|.##.......
|
||||||
|
...#.|.||.|.....|..##.#|....|#...|#.#|.#|...#.....
|
||||||
|
##.#....|..|.|....#.#|..##..#.......|.|.||#.......
|
||||||
|
....|..#|...|...|#..#...#....#.........#....#.|..|
|
||||||
|
....##...|..........|.|##|##..||..|..#..#|..|.....
|
||||||
|
........|..#.......|.#|............##.||.##.#..||#
|
||||||
|
.|...|##..#.|..|..|.#|.#.|#...|......#.....#...##|
|
||||||
|
............#.|.|||....|...#.#..#|.#...|.#....#|..
|
||||||
|
.....#....##....|#..##..|......|#.........|..##..|
|
||||||
|
#|.#||...|#...#|#|......#|#.|.#|#.|#...|.....#|.||
|
||||||
|
..|..#..|.#||.#.#.......#..#.#...|.#...|.|.|..|..#
|
||||||
|
.#|....#..#.|........#.....#.|....|#|#........#.|.
|
||||||
|
###|....##|#|||#.||.....#....#.#....|.#...|#..|#..
|
||||||
|
...#.##..#....|...||.#.|#.....||##|#.....|#|...|..
|
||||||
|
#..|.|.|#......|.#....#||...#.|.|..|#...|#|.|#|...
|
||||||
|
....###..|||#..##....||..|.|.#|#.....#||.......|..
|
||||||
|
|....#...#.||.|...#.#|...##.##....||.|.|##.#.#|...
|
||||||
|
#..#...#...|##....#.#|....|.#|#.|.....|##|||...#.|
|
||||||
|
..||.|.#...#.#|#...#..||.|#.|.|.|.###.....|....#..
|
||||||
|
.#|..|###.#....#.......#|.#|..#.|.||.|.||..##...#|
|
||||||
|
|..|....|#.........#|.|.....|.#...|.#|.||..|.|||.|
|
||||||
|
#...........|##|..#..##.......|||..#.....#.|#..##.
|
||||||
|
.#.#..|....|.|||###..#........|..#..|..##|...|#...
|
||||||
|
#.#..|||||....#.#..#...##....#....##.#|......##.#.
|
||||||
|
|.|#|.....|......#.....#........|.||....##|.#...|.
|
||||||
|
#....#.....#.#.|#......|#.|........|#|..#.|##.|.#.
|
||||||
|
.#|##..|.||..#|....#.|..#|#.#...###|...#.#....#...
|
||||||
|
#...#....||..#.|...||..#....|.|......|||....#.....
|
||||||
|
.#|....#|...#.#....|...|#|#.##...|.|.#||||..|.##.#
|
||||||
|
....#..#....|.|.#....|..|||#....#...|.#....#.|#.|.
|
||||||
|
.#..###|..|#.....#....|.|.|||.|.|#||#.#..|.##|...#
|
||||||
|
##.#...#|.....||.#..|.|...||.....|||.||#......|#..
|
||||||
|
||#|.|...||......#...#.|#..|..#.......##..##.#...#
|
||||||
|
...##.|#....#||.|.#.|#..........#...#.......#....|
|
||||||
|
..#...#...|#..|||..#||||....#..|.#..#.#..||.##|.||
|
||||||
|
#..|...|##||.||..|#.|.#....|.......|..#....|.#|...
|
||||||
|
...|.#####.##|####..#.|..#....#...|#.#.#|......||.
|
||||||
|
###......|.|..|#.|#....|.......|##.|#|...|.......|
|
||||||
|
##|....|#..|...#..|.||......#|.....##|...|...|..#|
|
||||||
|
..#.|.#.||...###..##.##..|....|..|....#..#...####.
|
||||||
|
.|##.#..|..|...##......#...##||........|.|....#||.
|
||||||
|
##.|#....|...|..|#.....|....|.|....|.|.|..|..#.#..
|
||||||
|
..|.|.#|.|....||#.|#...............##..|...#.....#
|
||||||
|
.#...#.......#.......#.##...#.|.|..####.||#....#||
|
||||||
|
.||#...##.#|.||..##.|....|||##...|#.|...#.#|.#....
|
||||||
|
.#|.||#..#.|#.......||.||#...........#....|###....
|
||||||
|
#|....#......##.#....|.....|##.#|.....|.#..|.....#
|
Loading…
Reference in New Issue