mirror of
https://github.com/Noettore/AdventOfCode.git
synced 2025-10-15 03:36:39 +02:00
AoC 2020: day17
Signed-off-by: Ettore Dreucci <ettore.dreucci@gmail.com>
This commit is contained in:
8
2020-python/inputs/day_17
Normal file
8
2020-python/inputs/day_17
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
##.#####
|
||||||
|
#.##..#.
|
||||||
|
.##...##
|
||||||
|
###.#...
|
||||||
|
.#######
|
||||||
|
##....##
|
||||||
|
###.###.
|
||||||
|
.#.#.#..
|
95
2020-python/solutions/day_17.py
Normal file
95
2020-python/solutions/day_17.py
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
"""AOC 2020 Day 17"""
|
||||||
|
|
||||||
|
import pathlib
|
||||||
|
import time
|
||||||
|
import itertools
|
||||||
|
|
||||||
|
TEST_INPUT = """.#.
|
||||||
|
..#
|
||||||
|
###"""
|
||||||
|
|
||||||
|
def read_input(input_path: str) -> str:
|
||||||
|
"""take input file path and return a str with the file's content"""
|
||||||
|
with open(input_path, 'r') as input_file:
|
||||||
|
input_data = input_file.read().strip()
|
||||||
|
return input_data
|
||||||
|
|
||||||
|
def extract(input_data: str, dims: int) -> set:
|
||||||
|
"""take input data and return the appropriate data structure"""
|
||||||
|
alive_cells = set()
|
||||||
|
zeros = [0]*(dims-2)
|
||||||
|
for x_cell, row in enumerate(input_data.split('\n')):
|
||||||
|
for y_cell, cell in enumerate(row):
|
||||||
|
if cell == '#':
|
||||||
|
alive_cells.add((x_cell, y_cell, *zeros))
|
||||||
|
return alive_cells
|
||||||
|
|
||||||
|
def count_alive_neighbors(alive_cells: set, coords: tuple) -> int:
|
||||||
|
"""return the number of alive neighbors of a given cell"""
|
||||||
|
alive = 0
|
||||||
|
ranges = ((c-1, c, c+1) for c in coords)
|
||||||
|
for cell in itertools.product(*ranges):
|
||||||
|
if cell in alive_cells:
|
||||||
|
alive += 1
|
||||||
|
if coords in alive_cells:
|
||||||
|
alive -= 1
|
||||||
|
return alive
|
||||||
|
|
||||||
|
def get_cube_limits(alive_cells: set, dims: int) -> list:
|
||||||
|
"""return cube bounds incremented for expansion"""
|
||||||
|
limits = list()
|
||||||
|
for i in range(dims):
|
||||||
|
low = float('Inf')
|
||||||
|
high = -float('Inf')
|
||||||
|
for row in alive_cells:
|
||||||
|
if row[i] < low:
|
||||||
|
low = row[i]
|
||||||
|
elif row[i] > high:
|
||||||
|
high = row[i]
|
||||||
|
limits.append(range(low-1, high+2))
|
||||||
|
return limits
|
||||||
|
|
||||||
|
def step_cube(alive_cells: set, dims: int) -> set:
|
||||||
|
"""return next step alive cells"""
|
||||||
|
next_step = set()
|
||||||
|
for cell in itertools.product(*get_cube_limits(alive_cells, dims)):
|
||||||
|
alive_neighbors = count_alive_neighbors(alive_cells, cell)
|
||||||
|
if (cell in alive_cells and alive_neighbors in (2, 3)) or alive_neighbors == 3:
|
||||||
|
next_step.add(cell)
|
||||||
|
return next_step
|
||||||
|
|
||||||
|
def part1(input_data: str) -> int:
|
||||||
|
"""part1 solver"""
|
||||||
|
cube = extract(input_data, 3)
|
||||||
|
for _ in range(6):
|
||||||
|
cube = step_cube(cube, 3)
|
||||||
|
return len(cube)
|
||||||
|
|
||||||
|
def part2(input_data: str) -> int:
|
||||||
|
"""part2 solver"""
|
||||||
|
cube = extract(input_data, 4)
|
||||||
|
for _ in range(6):
|
||||||
|
cube = step_cube(cube, 4)
|
||||||
|
return len(cube)
|
||||||
|
|
||||||
|
def test_input_day_17():
|
||||||
|
"""pytest testing function"""
|
||||||
|
assert part1(TEST_INPUT) == 112
|
||||||
|
assert part2(TEST_INPUT) == 848
|
||||||
|
|
||||||
|
def test_bench_day_17(benchmark):
|
||||||
|
"""pytest-benchmark function"""
|
||||||
|
benchmark(main)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""main function"""
|
||||||
|
input_path = str(pathlib.Path(__file__).resolve().parent.parent) + "/inputs/" + str(pathlib.Path(__file__).stem)
|
||||||
|
start_time = time.time()
|
||||||
|
input_data = read_input(input_path)
|
||||||
|
print("Part 1: %d" % part1(input_data))
|
||||||
|
print("Part 2: %d" % part2(input_data))
|
||||||
|
end_time = time.time()
|
||||||
|
print("Execution time: %f" % (end_time-start_time))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@@ -26,3 +26,4 @@
|
|||||||
| [Day 14](https://adventofcode.com/2020/day/14) | [64.058ms](./2020-python/solutions/day_14.py) | [56.398ms](./2020-python/solutions/day_14.py) |
|
| [Day 14](https://adventofcode.com/2020/day/14) | [64.058ms](./2020-python/solutions/day_14.py) | [56.398ms](./2020-python/solutions/day_14.py) |
|
||||||
| [Day 15](https://adventofcode.com/2020/day/15) | [4.463s](./2020-python/solutions/day_15.py) | [718.712ms](./2020-python/solutions/day_15.py) |
|
| [Day 15](https://adventofcode.com/2020/day/15) | [4.463s](./2020-python/solutions/day_15.py) | [718.712ms](./2020-python/solutions/day_15.py) |
|
||||||
| [Day 16](https://adventofcode.com/2020/day/16) | [11.108ms](./2020-python/solutions/day_16.py) | [2.903ms](./2020-python/solutions/day_16.py) |
|
| [Day 16](https://adventofcode.com/2020/day/16) | [11.108ms](./2020-python/solutions/day_16.py) | [2.903ms](./2020-python/solutions/day_16.py) |
|
||||||
|
| [Day 17](https://adventofcode.com/2020/day/17) | [743.804ms](./2020-python/solutions/day_17.py) | [836.255ms](./2020-python/solutions/day_17.py) |
|
||||||
|
Reference in New Issue
Block a user