Skip to content

Commit ab83f26

Browse files
authored
Merge branch 'master' into get_time
2 parents 4319483 + a886108 commit ab83f26

File tree

219 files changed

+4027
-4307
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

219 files changed

+4027
-4307
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ __pycache__/
88

99
# C extensions
1010
*.so
11+
*.o
1112

1213
# Distribution / packaging
1314
.Python

advent-of-code/README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Advent of Code: Solving Your Puzzles With Python
2+
3+
This repository holds the code for the Real Python [Advent of Code: Solving Your Puzzles With Python](https://realpython.com/python-advent-of-code/) tutorial.
4+
5+
## Dependencies
6+
7+
[Pytest](https://realpython.com/pytest-python-testing/) is used for testing. You should first create a virtual environment:
8+
9+
```console
10+
$ python -m venv venv
11+
$ source venv/bin/activate
12+
```
13+
14+
You can then install `pytest` with `pip`:
15+
16+
```console
17+
(venv) $ python -m pip install pytest
18+
```
19+
20+
The [aoc_grid.py](aoc_grid.py) example uses [Colorama](https://pypi.org/project/colorama/) and [NumPy](https://realpython.com/numpy-tutorial/). To run that example, you should also install those packages into your environment:
21+
22+
```console
23+
(venv) $ python -m pip install colorama numpy
24+
```
25+
26+
The puzzle solutions only use Python's standard library. Note that the solution to [Day 5, 2021](solutions/2021/05_hydrothermal_venture/) uses [structural pattern matching](https://realpython.com/python310-new-features/#structural-pattern-matching) which is only available in [Python 3.10](https://realpython.com/python310-new-features/) and later.
27+
28+
## Author
29+
30+
- **Geir Arne Hjelle**, E-mail: [[email protected]]([email protected])
31+
32+
## License
33+
34+
Distributed under the MIT license. See [`LICENSE`](../LICENSE) for more information.

advent-of-code/aoc_grid.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import numpy as np
2+
from colorama import Cursor
3+
4+
grid = np.array(
5+
[
6+
[1, 1, 1, 1, 1],
7+
[1, 0, 0, 0, 1],
8+
[1, 1, 1, 0, 1],
9+
[1, 0, 0, 2, 1],
10+
[1, 1, 1, 1, 1],
11+
]
12+
)
13+
14+
num_rows, num_cols = grid.shape
15+
for row in range(num_rows):
16+
for col in range(num_cols):
17+
symbol = " *o"[grid[row, col]]
18+
print(f"{Cursor.POS(col + 1, row + 2)}{symbol}")
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from dataclasses import dataclass
2+
3+
4+
@dataclass
5+
class StateMachine:
6+
memory: dict[str, int]
7+
program: list[str]
8+
9+
def run(self):
10+
"""Run the program"""
11+
current_line = 0
12+
while current_line < len(self.program):
13+
instruction = self.program[current_line]
14+
15+
# Set a register to a value
16+
if instruction.startswith("set "):
17+
register, value = instruction[4], int(instruction[6:])
18+
self.memory[register] = value
19+
20+
# Increase the value in a register by 1
21+
elif instruction.startswith("inc "):
22+
register = instruction[4]
23+
self.memory[register] += 1
24+
25+
# Move the line pointer
26+
current_line += 1
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Day 1, 2019: The Tyranny of the Rocket Equation
2+
3+
Resources:
4+
5+
- **Puzzle:** [adventofcode.com](https://adventofcode.com/2019/day/1)
6+
- **Solution:** [realpython.com](https://realpython.com/python-advent-of-code/#practicing-advent-of-code-day-1-2019)
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
"""AoC 1, 2019: The Tyranny of the Rocket Equation"""
2+
3+
# Standard library imports
4+
import pathlib
5+
import sys
6+
7+
8+
def parse(puzzle_input):
9+
"""Parse input"""
10+
return [int(line) for line in puzzle_input.split("\n")]
11+
12+
13+
def part1(module_masses):
14+
"""Solve part 1"""
15+
return sum(mass // 3 - 2 for mass in module_masses)
16+
17+
18+
def part2(module_masses):
19+
"""Solve part 2"""
20+
return sum(all_fuel(mass) for mass in module_masses)
21+
22+
23+
def all_fuel(mass):
24+
"""Calculate fuel while taking mass of the fuel into account.
25+
26+
## Example:
27+
28+
>>> all_fuel(1969)
29+
966
30+
"""
31+
fuel = mass // 3 - 2
32+
if fuel <= 0:
33+
return 0
34+
else:
35+
return fuel + all_fuel(mass=fuel)
36+
37+
38+
def solve(puzzle_input):
39+
"""Solve the puzzle for the given input"""
40+
data = parse(puzzle_input)
41+
solution1 = part1(data)
42+
solution2 = part2(data)
43+
44+
return solution1, solution2
45+
46+
47+
if __name__ == "__main__":
48+
for path in sys.argv[1:]:
49+
print(f"\n{path}:")
50+
solutions = solve(puzzle_input=pathlib.Path(path).read_text().strip())
51+
print("\n".join(str(solution) for solution in solutions))
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
12
2+
14
3+
1969
4+
100756
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""Tests for AoC 1, 2019: The Tyranny of the Rocket Equation"""
2+
3+
# Standard library imports
4+
import pathlib
5+
6+
# Third party imports
7+
import aoc201901 as aoc
8+
import pytest
9+
10+
PUZZLE_DIR = pathlib.Path(__file__).parent
11+
12+
13+
@pytest.fixture
14+
def example1():
15+
puzzle_input = (PUZZLE_DIR / "example1.txt").read_text().strip()
16+
return aoc.parse(puzzle_input)
17+
18+
19+
def test_parse_example1(example1):
20+
"""Test that input is parsed properly"""
21+
assert example1 == [12, 14, 1969, 100756]
22+
23+
24+
def test_part1_example1(example1):
25+
"""Test part 1 on example input"""
26+
assert aoc.part1(example1) == 2 + 2 + 654 + 33583
27+
28+
29+
def test_part2_example1(example1):
30+
"""Test part 2 on example input"""
31+
assert aoc.part2(example1) == 2 + 2 + 966 + 50346
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Day 1, 2020: Report Repair
2+
3+
Resources:
4+
5+
- **Puzzle:** [adventofcode.com](https://adventofcode.com/2020/day/1)
6+
- **Solution:** [realpython.com](https://realpython.com/python-advent-of-code/#the-structure-of-a-solution)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""AoC 1, 2020: Report Repair"""
2+
3+
# Standard library imports
4+
import pathlib
5+
import sys
6+
7+
8+
def parse(puzzle_input):
9+
"""Parse input"""
10+
return [int(line) for line in puzzle_input.split()]
11+
12+
13+
def part1(numbers):
14+
"""Solve part 1"""
15+
for num1 in numbers:
16+
for num2 in numbers:
17+
if num1 < num2 and num1 + num2 == 2020:
18+
return num1 * num2
19+
20+
21+
def part2(numbers):
22+
"""Solve part 2"""
23+
24+
25+
def solve(puzzle_input):
26+
"""Solve the puzzle for the given input"""
27+
data = parse(puzzle_input)
28+
solution1 = part1(data)
29+
solution2 = part2(data)
30+
31+
return solution1, solution2
32+
33+
34+
if __name__ == "__main__":
35+
for path in sys.argv[1:]:
36+
print(f"\n{path}:")
37+
solutions = solve(puzzle_input=pathlib.Path(path).read_text().strip())
38+
print("\n".join(str(solution) for solution in solutions))

0 commit comments

Comments
 (0)