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