|
1 | 1 | # Advent of Code ⭐️ |
2 | 2 | []() |
3 | 3 |
|
4 | | -Collection of my Advent of Code solutions in a slightly overkill project setup 👻. |
| 4 | +Collection of my Advent of Code solutions in an overkill project setup 👻🎄. |
5 | 5 |
|
6 | 6 | ## Features ✨ |
7 | 7 | - Solutions are timed with the help of a decorator using `time.perf_counter` |
8 | 8 | - Solution and time are printed to console using the `rich` package with `truecolor` |
| 9 | +- Solution profiler decorator using `Cprofile` and `pstats` |
9 | 10 | - Automatic listing of completed solutions in the README |
10 | 11 | - Automatic changelog, using semantic versioning and the conventional commit specification |
11 | 12 | - A badge that is updated automatically with the amount of stars I've collected |
12 | 13 | - Pip installable (`pip install -e .`) with: |
13 | | - - A generate-readme script, which updates the readme |
14 | | - - A run-all script, which dynamically calls every solution in every `adventofcode.year_*.day_*` module |
| 14 | + - A `generate-readme` script, which updates the readme |
| 15 | + - A `run-all` script, which dynamically calls every solution in every `adventofcode.year_*.day_*` module |
| 16 | + - An `add-day` script, which add a solution day file using a template and downloads the input data from the AOC site automatically |
15 | 17 | - Type checked (`mypy`) and linted (`flake8`) |
16 | 18 | - Tested against multiple python versions using `tox` on each push to master and pull request |
17 | 19 |
|
@@ -43,5 +45,86 @@ Collection of my Advent of Code solutions in a slightly overkill project setup |
43 | 45 |
|
44 | 46 | <!-- end completed section --> |
45 | 47 |
|
| 48 | +## Decorators |
| 49 | +What's Christmas without decorations? 🎄 |
| 50 | + |
| 51 | +### Solution timer |
| 52 | +The solution timer times the solution using `time.perf_counter` and outputs the answer and the duration to the console |
| 53 | + |
| 54 | +Example: |
| 55 | +```python |
| 56 | +@solution_timer(2015, 9, 1) # year, day, part |
| 57 | +def part_one(input_data: List[str]) -> int: |
| 58 | + ... |
| 59 | +``` |
| 60 | + |
| 61 | +Output: |
| 62 | +```text |
| 63 | +2015 day 09 part 01: 251 in 0.1356 ms |
| 64 | +``` |
| 65 | + |
| 66 | +### Solution profiler |
| 67 | +The solution profiler runs the `cProfiler` against the solution and outputs the profiler stats using `pstats` to the console. |
| 68 | +It takes an optional `amount` kwarg to set the amount of stats to display, and an optional `sort` kwarg to set the sorting to either |
| 69 | +`time` or `cumulative`. |
| 70 | + |
| 71 | +Example: |
| 72 | +```python |
| 73 | +@solution_profiler(2015, 9, 1) # year, day, part |
| 74 | +def part_one(input_data: List[str]) -> int: |
| 75 | + ... |
| 76 | +``` |
| 77 | + |
| 78 | +Output: |
| 79 | +```text |
| 80 | +91416 function calls (90941 primitive calls) in 0.159 seconds |
| 81 | +
|
| 82 | +Ordered by: internal time |
| 83 | +List reduced from 217 to 3 due to restriction <10> |
| 84 | +
|
| 85 | +ncalls tottime percall cumtime percall filename:lineno(function) |
| 86 | + 1 0.133 0.133 0.136 0.136 /Users/marcelblijleven/.../day_09_2015.py:39(_get_route_distances) |
| 87 | + 1 0.012 0.012 0.015 0.015 /Users/marcelblijleven/.../day_09_2015.py:30(get_all_routes) |
| 88 | +82182 0.006 0.000 0.006 0.000 {method 'append' of 'list' objects} |
| 89 | +``` |
| 90 | + |
| 91 | +## Scripts |
| 92 | +### add-day |
| 93 | +The `add-day` script creates a file based on a 'solution day' template into the correct year module. If no input is found |
| 94 | +for that day, it will automatically download the input and save it in the inputs directory. Note: this only works if the |
| 95 | +session cookie is stored in `.session`. To get this value: |
| 96 | +1. Go to the [AOC site](https://adventofcode.com). |
| 97 | +2. Make sure you're logged in, every user has unique input data |
| 98 | +3. View the cookies and copy the value of the `session` cookie. |
| 99 | +4. Paste the cookie value into the `.session` file |
| 100 | + |
| 101 | +Example: |
| 102 | +```shell |
| 103 | +(venv) add-day 2015 14 |
| 104 | +``` |
| 105 | + |
| 106 | +Output: |
| 107 | +```text |
| 108 | +(venv) [adventofcode] add-day 2015 14 master ✗ ✭ ✱ |
| 109 | +Creating solution day file for year 2015 day 14 |
| 110 | +Wrote template to /Users/marcelblijleven/code/github.com/marcelblijleven/adventofcode/src/adventofcode/year_2015/day_14_2015.py |
| 111 | +Input data already exists for year 2015 day 14, skipping download |
| 112 | +``` |
| 113 | + |
| 114 | +### generate-readme |
| 115 | +The `generate-readme` script dynamically searches for all solutions and writes them to the README.md file. |
| 116 | +When a solution file has a function called `part_one`, it adds a star. When it has a function called `part_two`, it adds another |
| 117 | +star. The `star counter` badge at the top of the README.md file is then updated with the total amount of stars found. |
| 118 | + |
| 119 | +This script is only used in the Github workflow `update_readme.yml`, but can be run locally to using `generate-readme` |
| 120 | + |
| 121 | +### clean-repo |
| 122 | +The `clean-repo` script is used to delete all solutions and inputs from the project. This can be useful if you want to start over, |
| 123 | +or if you've just forked this repo. The `clean-repo` command is run in 'dry run mode' by default, to disable it and actually |
| 124 | +start deleting directories and files, use: |
| 125 | + |
| 126 | +```shell |
| 127 | +(venv) clean-repo --dry-run false |
| 128 | +``` |
46 | 129 |
|
47 | 130 | **Note**: _not all years/solutions have been migrated yet from my previous repositories_ |
0 commit comments