This commit is contained in:
dave 2018-12-18 11:37:20 -08:00
parent 14ee180067
commit 7d2df3d1f1
3 changed files with 220 additions and 0 deletions

110
18/a.py Executable file
View File

@ -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()

60
18/b.py Executable file
View File

@ -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()

50
18/input.txt Normal file
View File

@ -0,0 +1,50 @@
#.##...#....|...#..|...#|...#....|.....|..##.|.|.#
||#...##|.|.##....|..#.#......#.#..#......|..#.|.#
|......#.##....||..#..||..|.....|..##....|.#.|..|#
.|...#||..||#|#.....|#...|.||.||#...#..|.##.......
...#.|.||.|.....|..##.#|....|#...|#.#|.#|...#.....
##.#....|..|.|....#.#|..##..#.......|.|.||#.......
....|..#|...|...|#..#...#....#.........#....#.|..|
....##...|..........|.|##|##..||..|..#..#|..|.....
........|..#.......|.#|............##.||.##.#..||#
.|...|##..#.|..|..|.#|.#.|#...|......#.....#...##|
............#.|.|||....|...#.#..#|.#...|.#....#|..
.....#....##....|#..##..|......|#.........|..##..|
#|.#||...|#...#|#|......#|#.|.#|#.|#...|.....#|.||
..|..#..|.#||.#.#.......#..#.#...|.#...|.|.|..|..#
.#|....#..#.|........#.....#.|....|#|#........#.|.
###|....##|#|||#.||.....#....#.#....|.#...|#..|#..
...#.##..#....|...||.#.|#.....||##|#.....|#|...|..
#..|.|.|#......|.#....#||...#.|.|..|#...|#|.|#|...
....###..|||#..##....||..|.|.#|#.....#||.......|..
|....#...#.||.|...#.#|...##.##....||.|.|##.#.#|...
#..#...#...|##....#.#|....|.#|#.|.....|##|||...#.|
..||.|.#...#.#|#...#..||.|#.|.|.|.###.....|....#..
.#|..|###.#....#.......#|.#|..#.|.||.|.||..##...#|
|..|....|#.........#|.|.....|.#...|.#|.||..|.|||.|
#...........|##|..#..##.......|||..#.....#.|#..##.
.#.#..|....|.|||###..#........|..#..|..##|...|#...
#.#..|||||....#.#..#...##....#....##.#|......##.#.
|.|#|.....|......#.....#........|.||....##|.#...|.
#....#.....#.#.|#......|#.|........|#|..#.|##.|.#.
.#|##..|.||..#|....#.|..#|#.#...###|...#.#....#...
#...#....||..#.|...||..#....|.|......|||....#.....
.#|....#|...#.#....|...|#|#.##...|.|.#||||..|.##.#
....#..#....|.|.#....|..|||#....#...|.#....#.|#.|.
.#..###|..|#.....#....|.|.|||.|.|#||#.#..|.##|...#
##.#...#|.....||.#..|.|...||.....|||.||#......|#..
||#|.|...||......#...#.|#..|..#.......##..##.#...#
...##.|#....#||.|.#.|#..........#...#.......#....|
..#...#...|#..|||..#||||....#..|.#..#.#..||.##|.||
#..|...|##||.||..|#.|.#....|.......|..#....|.#|...
...|.#####.##|####..#.|..#....#...|#.#.#|......||.
###......|.|..|#.|#....|.......|##.|#|...|.......|
##|....|#..|...#..|.||......#|.....##|...|...|..#|
..#.|.#.||...###..##.##..|....|..|....#..#...####.
.|##.#..|..|...##......#...##||........|.|....#||.
##.|#....|...|..|#.....|....|.|....|.|.|..|..#.#..
..|.|.#|.|....||#.|#...............##..|...#.....#
.#...#.......#.......#.##...#.|.|..####.||#....#||
.||#...##.#|.||..##.|....|||##...|#.|...#.#|.#....
.#|.||#..#.|#.......||.||#...........#....|###....
#|....#......##.#....|.....|##.#|.....|.#..|.....#