aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Voss <thomasvoss@live.com> 2021-12-12 06:56:03 +0100
committerThomas Voss <thomasvoss@live.com> 2021-12-12 06:56:03 +0100
commitb4195baae3b36bd997a97d24fd5e0ab38dcd5595 (patch)
treeeca4ea75f16be761da19409b83a45ce88dd1b0c5
parentc93fc1b9a11c96a4554ec47029bf085597fdef60 (diff)
Add libaoc
-rw-r--r--.gitignore1
-rw-r--r--2021/04/puzzles.py7
-rwxr-xr-x2021/09/puzzle-1.py42
-rwxr-xr-x2021/09/puzzle-2.py10
-rw-r--r--2021/11/puzzles.py18
-rw-r--r--README.rst14
-rw-r--r--libaoc.py26
7 files changed, 79 insertions, 39 deletions
diff --git a/.gitignore b/.gitignore
index 538d26d..29bc987 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+__pycache__/
.clang-format
puzzle-[12]
tmp[12].*
diff --git a/2021/04/puzzles.py b/2021/04/puzzles.py
index 20036e0..46dfa05 100644
--- a/2021/04/puzzles.py
+++ b/2021/04/puzzles.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python3
-board = list[list[int]]
+from libaoc import flatten, map2d, matrix
+
+board = matrix[int]
last: board = []
@@ -42,8 +44,7 @@ def main() -> None:
# START PART 2
boards = list(filter(lambda b: not bingo(b), boards))
# END PART 2
-
- print(num * sum(map(lambda x: sum(filter(lambda n: n != -1, x)), last)))
+ print(num * sum(flatten(map2d(lambda n: 0 if n == -1 else n, last))))
if __name__ == "__main__":
diff --git a/2021/09/puzzle-1.py b/2021/09/puzzle-1.py
index 5ab2f45..be333a5 100755
--- a/2021/09/puzzle-1.py
+++ b/2021/09/puzzle-1.py
@@ -1,29 +1,33 @@
#!/usr/bin/env python3
+from itertools import product
+
+from libaoc import read_int_matrix
+
+
def main() -> None:
with open("input", "r", encoding="utf-8") as f:
- data = list(map(lambda l: [int(n) for n in l.strip()], f.readlines()))
+ data = read_int_matrix(f)
acc = 0
- rows = len(data[0])
- cols = len(data)
-
- for i in range(cols):
- for j in range(rows):
- if (
- i != 0
- and data[i - 1][j] <= data[i][j]
- or i != cols - 1
- and data[i + 1][j] <= data[i][j]
- or j != 0
- and data[i][j - 1] <= data[i][j]
- or j != rows - 1
- and data[i][j + 1] <= data[i][j]
- ):
- continue
-
- acc += data[i][j] + 1
+ rows = len(data)
+ cols = len(data[0])
+
+ for i, j in product(range(rows), range(cols)):
+ if (
+ i != 0
+ and data[i - 1][j] <= data[i][j]
+ or i != cols - 1
+ and data[i + 1][j] <= data[i][j]
+ or j != 0
+ and data[i][j - 1] <= data[i][j]
+ or j != rows - 1
+ and data[i][j + 1] <= data[i][j]
+ ):
+ continue
+
+ acc += data[i][j] + 1
print(acc)
diff --git a/2021/09/puzzle-2.py b/2021/09/puzzle-2.py
index d435f7c..72e0752 100755
--- a/2021/09/puzzle-2.py
+++ b/2021/09/puzzle-2.py
@@ -9,17 +9,17 @@ from functools import reduce
from itertools import product
from operator import mul
-matrix = list[list[int]]
+from libaoc import matrix, read_int_matrix
-def is_basin(grid: matrix, row: int, col: int) -> bool:
+def is_basin(grid: matrix[int], row: int, col: int) -> bool:
return (
not ((row < 0 or row > len(grid) - 1) or (col < 0 or col > len(grid[0]) - 1))
and grid[row][col] != 9
)
-def floodfill(grid: matrix, row: int, col: int) -> int:
+def floodfill(grid: matrix[int], row: int, col: int) -> int:
if row < 0 or row > len(grid) - 1 or col < 0 or col > len(grid[0]) - 1 or grid[row][col] == 9:
return 0
@@ -43,7 +43,7 @@ def floodfill(grid: matrix, row: int, col: int) -> int:
return size
-def solve(grid: matrix) -> int:
+def solve(grid: matrix[int]) -> int:
return reduce(
mul,
sorted(
@@ -59,7 +59,7 @@ def solve(grid: matrix) -> int:
def main() -> None:
with open("input", "r", encoding="utf-8") as f:
- print(solve(list(map(lambda l: [int(n) for n in l.strip()], f.readlines()))))
+ print(solve(read_int_matrix(f)))
if __name__ == "__main__":
diff --git a/2021/11/puzzles.py b/2021/11/puzzles.py
index ad1fa05..19fb534 100644
--- a/2021/11/puzzles.py
+++ b/2021/11/puzzles.py
@@ -1,16 +1,13 @@
#!/usr/bin/env python3
-# START PART 1
-from itertools import product
-# END PART 1 START PART 2
from itertools import chain, count, product
-# END PART 2
-matrix = list[list[int]]
+from libaoc import map2d, matrix, read_int_matrix
+
rows, cols = -1, -1
-def flash(grid: matrix, i: int, j: int) -> int:
+def flash(grid: matrix[int], i: int, j: int) -> int:
acc = 1
grid[i][j] = -1
@@ -29,7 +26,7 @@ def main() -> None:
global rows, cols
with open("input", "r", encoding="utf-8") as f:
- grid = list(map(lambda l: [int(n) for n in l.strip()], f.readlines()))
+ grid = read_int_matrix(f)
rows = len(grid)
cols = len(grid[0])
@@ -40,8 +37,7 @@ def main() -> None:
# END PART 1 START PART 2
for step in count(1):
# END PART 2
- for i, j in product(range(rows), range(cols)):
- grid[i][j] += 1
+ grid = list(map2d(lambda n: n + 1, grid, list))
for i, j in product(range(rows), range(cols)):
if grid[i][j] > 9:
@@ -53,9 +49,7 @@ def main() -> None:
return
# END PART 2
- for i, j in product(range(rows), range(cols)):
- if grid[i][j] == -1:
- grid[i][j] = 0
+ grid = list(map2d(lambda n: 0 if n == -1 else n, grid, list))
# START PART 1
print(acc)
diff --git a/README.rst b/README.rst
index de11e31..7b9e695 100644
--- a/README.rst
+++ b/README.rst
@@ -18,3 +18,17 @@ the "puzzles.ext" file as it's required to get the "puzzle-1.ext" and "puzzle-2.
actually run properly.
.. _Advent of Code: https://adventofcode.com
+
+
+Running Code
+------------
+
+Some of the solutions in this repo make use of ``libaoc``. In order to run these solutions you need
+to add the directory of the library to the ``PYTHONPATH`` environment variable. In other words,
+instead of doing this::
+
+ $ ./puzzle-1.py
+
+You must do this::
+
+ $ PYTHONPATH=../../ ./puzzle-1.py
diff --git a/libaoc.py b/libaoc.py
new file mode 100644
index 0000000..1316691
--- /dev/null
+++ b/libaoc.py
@@ -0,0 +1,26 @@
+from io import TextIOWrapper
+from typing import Any, Callable, Iterable, Iterator, Optional, TypeVar
+
+S = TypeVar("S")
+T = TypeVar("T")
+matrix = list[list[T]]
+
+
+def flatten(iter: Iterable[Any]) -> Iterator[Any]:
+ if hasattr(iter, "__iter__") and type(iter) != str:
+ for i in iter:
+ yield from flatten(i)
+ else:
+ yield iter
+
+
+def read_int_matrix(f: TextIOWrapper) -> matrix[int]:
+ return list(map(lambda l: [int(n) for n in l.strip()], f.readlines()))
+
+
+def map2d(
+ func: Callable[[Any], Any],
+ iter: Iterable[Iterable[Any]],
+ const: Optional[Callable[[T], S]] = lambda x: x,
+) -> map:
+ return map(lambda i: const(map(func, i)), iter)