Skip to content

Commit e1004b1

Browse files
committed
Update days plot to be more general
1 parent 7166515 commit e1004b1

File tree

5 files changed

+79
-58
lines changed

5 files changed

+79
-58
lines changed

.pre-commit-config.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
repos:
2+
- repo: local
3+
hooks:
4+
- id: create-day-tiles
5+
name: create-day-tiles
6+
entry: python3 ./days_plot.py
7+
language: system
8+
File renamed without changes.

README.md

+35-32
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,96 @@
11
# My Advent of Code Solutions
22

3-
All solutions expect the input via stdin, which can be easily achieved by piping the input to the program: `julia 1.jl < input.in`. I use the `program-tester.sh` script (see [here](https://github.com/LiquidFun/misc-scripts)), which runs the given program on all `*.in` files in the directory, and tests whether the corresponding `*.ans` file matches the given output. Each program outputs both part 1 and part 2 on separate lines. To validate a program manually, type `diff <(julia 1.jl < input.in) input.ans`.
4-
5-
Programs are initialized with the `init-day.sh` script. I.e. typing `init-day.sh 10` initializes the 10th day by creating a folder named `10`, downloading the input test case with the `session.cookie`, copying the `dummy.py` file and opening the solution file.
6-
7-
* 2021: There is a solution for each problem in Julia. Sometimes there is a Python or APL solution as well. I'm trying out Julia for the first time, mostly focusing on short and elegant code.
8-
93
<!-- REPLACE FROM -->
104
<h1 align="center">
115
2021
126
</h1>
137
<a href="2021/01/1.apl">
14-
<img src="Media/2021/01.png" width="160px">
8+
<img src="Media/2021/01.png" width="161px">
159
</a>
1610
<a href="2021/02/2.jl">
17-
<img src="Media/2021/02.png" width="160px">
11+
<img src="Media/2021/02.png" width="161px">
1812
</a>
1913
<a href="2021/03/3.jl">
20-
<img src="Media/2021/03.png" width="160px">
14+
<img src="Media/2021/03.png" width="161px">
2115
</a>
2216
<a href="2021/04/4.jl">
23-
<img src="Media/2021/04.png" width="160px">
17+
<img src="Media/2021/04.png" width="161px">
2418
</a>
2519
<a href="2021/05/5.jl">
26-
<img src="Media/2021/05.png" width="160px">
20+
<img src="Media/2021/05.png" width="161px">
2721
</a>
2822
<a href="2021/06/6.jl">
29-
<img src="Media/2021/06.png" width="160px">
23+
<img src="Media/2021/06.png" width="161px">
3024
</a>
3125
<a href="2021/07/7.jl">
32-
<img src="Media/2021/07.png" width="160px">
26+
<img src="Media/2021/07.png" width="161px">
3327
</a>
3428
<a href="2021/08/8.jl">
35-
<img src="Media/2021/08.png" width="160px">
29+
<img src="Media/2021/08.png" width="161px">
3630
</a>
3731
<a href="2021/09/9.jl">
38-
<img src="Media/2021/09.png" width="160px">
32+
<img src="Media/2021/09.png" width="161px">
3933
</a>
4034
<a href="2021/10/10.jl">
41-
<img src="Media/2021/10.png" width="160px">
35+
<img src="Media/2021/10.png" width="161px">
4236
</a>
4337
<a href="2021/11/11.jl">
44-
<img src="Media/2021/11.png" width="160px">
38+
<img src="Media/2021/11.png" width="161px">
4539
</a>
4640
<a href="2021/12/12.jl">
47-
<img src="Media/2021/12.png" width="160px">
41+
<img src="Media/2021/12.png" width="161px">
4842
</a>
4943
<a href="2021/13/13.jl">
50-
<img src="Media/2021/13.png" width="160px">
44+
<img src="Media/2021/13.png" width="161px">
5145
</a>
5246
<a href="2021/14/14.jl">
53-
<img src="Media/2021/14.png" width="160px">
47+
<img src="Media/2021/14.png" width="161px">
5448
</a>
5549
<a href="2021/15/15.jl">
56-
<img src="Media/2021/15.png" width="160px">
50+
<img src="Media/2021/15.png" width="161px">
5751
</a>
5852
<a href="2021/16/16.jl">
59-
<img src="Media/2021/16.png" width="160px">
53+
<img src="Media/2021/16.png" width="161px">
6054
</a>
6155
<a href="2021/17/17.jl">
62-
<img src="Media/2021/17.png" width="160px">
56+
<img src="Media/2021/17.png" width="161px">
6357
</a>
6458
<a href="2021/18/18.jl">
65-
<img src="Media/2021/18.png" width="160px">
59+
<img src="Media/2021/18.png" width="161px">
6660
</a>
6761
<a href="2021/19/19.jl">
68-
<img src="Media/2021/19.png" width="160px">
62+
<img src="Media/2021/19.png" width="161px">
6963
</a>
7064
<a href="2021/20/20.jl">
71-
<img src="Media/2021/20.png" width="160px">
65+
<img src="Media/2021/20.png" width="161px">
7266
</a>
7367
<a href="2021/21/21.jl">
74-
<img src="Media/2021/21.png" width="160px">
68+
<img src="Media/2021/21.png" width="161px">
7569
</a>
7670
<a href="2021/22/22.jl">
77-
<img src="Media/2021/22.png" width="160px">
71+
<img src="Media/2021/22.png" width="161px">
7872
</a>
7973
<a href="2021/23/23.jl">
80-
<img src="Media/2021/23.png" width="160px">
74+
<img src="Media/2021/23.png" width="161px">
8175
</a>
8276
<a href="2021/24/24.cpp">
83-
<img src="Media/2021/24.png" width="160px">
77+
<img src="Media/2021/24.png" width="161px">
8478
</a>
8579
<a href="2021/25/25.jl">
86-
<img src="Media/2021/25.png" width="160px">
80+
<img src="Media/2021/25.png" width="161px">
8781
</a>
8882
<!-- REPLACE UNTIL -->
8983

9084

9185
---
9286

93-
The graphic above has been created with [this](days_plot.py) script. Feel free to use it in your own repositories, please credit me though.
87+
88+
All solutions expect the input via stdin, which can be easily achieved by piping the input to the program: `julia 1.jl < input.in`. I use the `program-tester.sh` script (see [here](https://github.com/LiquidFun/misc-scripts)), which runs the given program on all `*.in` files in the directory, and tests whether the corresponding `*.ans` file matches the given output. Each program outputs both part 1 and part 2 on separate lines. To validate a program manually, type `diff <(julia 1.jl < input.in) input.ans`.
89+
90+
Programs are initialized with the `init-day.sh` script. I.e. typing `init-day.sh 10` initializes the 10th day by creating a folder named `10`, downloading the input test case with the `session.cookie`, copying the `dummy.py` file and opening the solution file.
91+
92+
* 2021: There is a solution for each problem in Julia. Sometimes there is a Python or APL solution as well. I'm trying out Julia for the first time, mostly focusing on short and elegant code.
93+
94+
---
95+
96+
The graphic above has been created with [this](days_plot.py) script. Feel free to use it in your own repositories.

days_plot.py

+33-26
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def get_extension_to_colors():
3434
with open(aoc_folder / "Media/github_languages.yml", "r") as file:
3535
github_languages = yaml.load(file, Loader=yaml.FullLoader)
3636
for language, data in github_languages.items():
37-
if "color" in data and "extensions" in data:
37+
if "color" in data and "extensions" in data and data["type"] == "programming":
3838
for extension in data["extensions"]:
3939
extension_to_color[extension.lower()] = data["color"]
4040
return extension_to_color
@@ -66,7 +66,7 @@ def parse_leaderboard(leaderboard_path: Path) -> dict[str, DayScores]:
6666
return leaderboard
6767

6868

69-
def request_leaderboard(year) -> dict[str, DayScores]:
69+
def request_leaderboard(year: int) -> dict[str, DayScores]:
7070
leaderboard_path = cache_path / f"leaderboard{year}.html"
7171
if leaderboard_path.exists():
7272
leaderboard = parse_leaderboard(leaderboard_path)
@@ -117,7 +117,7 @@ def __str__(self):
117117

118118

119119
def darker_color(c: tuple[int, int, int, int]) -> tuple[int, int, int, int]:
120-
return (c[0] - 10, c[1] - 10, c[2] - 10, 255)
120+
return c[0] - 10, c[1] - 10, c[2] - 10, 255
121121

122122

123123
def get_alternating_background(languages, both_parts_completed=True, *, stripe_width=20):
@@ -197,55 +197,62 @@ def gen_day_graphic(day: str, year: str, languages: list[str], day_scores: DaySc
197197
return path
198198

199199

200-
def handle_day(day_path: Path, html: HTML, day_scores: DayScores | None):
200+
def handle_day(day: int, year: int, day_path: Path, html: HTML, day_scores: DayScores | None):
201201
languages = []
202202
solution_file_path = None
203-
loc = 0
204-
for file_path in day_path.glob("*"):
205-
if file_path.is_file():
206-
if file_path.suffix.lower() in extension_to_color:
207-
if solution_file_path is None:
208-
solution_file_path = file_path.relative_to(aoc_folder)
209-
loc = solution_file_path.open().read().count("\n")
210-
languages.append(file_path.suffix.lower())
203+
if day_path is not None:
204+
for file_path in day_path.glob("*"):
205+
if file_path.is_file():
206+
if file_path.suffix.lower() in extension_to_color:
207+
if solution_file_path is None:
208+
solution_file_path = file_path.relative_to(aoc_folder)
209+
languages.append(file_path.suffix.lower())
211210
languages = sorted(set(languages))
212211
if DEBUG:
213-
if day_path.name == "25":
212+
if day == 25:
214213
languages = []
215-
day_graphic_path = gen_day_graphic(day_path.name, day_path.parent.name, languages, day_scores)
214+
day_graphic_path = gen_day_graphic(f"{day:02}", f"{year:04}", languages, day_scores)
216215
day_graphic_path = day_graphic_path.relative_to(aoc_folder)
217216
with html.tag("a", href=str(solution_file_path)):
218-
html.tag("img", closing=False, src=str(day_graphic_path), width="160px")
217+
html.tag("img", closing=False, src=str(day_graphic_path), width="161px")
219218

220219

221-
def handle_year(year_path: Path):
222-
leaderboard = request_leaderboard(year_path.name)
220+
def find_first_number(string: str) -> int:
221+
return int(re.findall(r"\d+", string)[0])
222+
223+
224+
def handle_year(year_path: Path, year: int):
225+
leaderboard = request_leaderboard(year)
223226
if DEBUG:
224227
leaderboard["25"] = None
225228
leaderboard["24"] = DayScores("22:22:22", "12313", "0")
226229
html = HTML()
227230
with html.tag("h1", align="center"):
228-
html.push(f"{year_path.name}")
229-
for day in range(1, 26):
230-
day_str = f"{day:02}"
231-
day_path = year_path / day_str
232-
if day_path.exists():
233-
handle_day(day_path, html, leaderboard.get(str(day), None))
231+
html.push(f"{year}")
232+
days_with_filled_gaps = {find_first_number(p.name): p for p in get_paths_matching_regex(year_path, DAY_PATTERN)}
233+
max_day = max(*days_with_filled_gaps, *map(int, leaderboard))
234+
for day in range(1, max_day + 1):
235+
if day not in days_with_filled_gaps:
236+
days_with_filled_gaps[day] = None
237+
for day, day_path in days_with_filled_gaps.items():
238+
handle_day(day, year, day_path, html, leaderboard.get(str(day), None))
239+
234240
with open("README.md", "r") as file:
235241
text = file.read()
236-
237242
begin = "<!-- REPLACE FROM -->"
238243
end = "<!-- REPLACE UNTIL -->"
239244
pattern = re.compile(rf"{begin}.*{end}", re.DOTALL | re.MULTILINE)
240245
new_text = pattern.sub(f"{begin}\n{html}\n{end}", text)
246+
241247
with open("README.md", "w") as file:
242248
file.write(str(new_text))
243249

244250

245251
def main():
246252
for year_path in sorted(get_paths_matching_regex(aoc_folder, YEAR_PATTERN), reverse=True):
247-
print(f"Generating table for year {year_path.name}")
248-
handle_year(year_path)
253+
year = find_first_number(year_path.name)
254+
print(f"Generating table for year {year}")
255+
handle_year(year_path, year)
249256

250257

251258
if __name__ == '__main__':

requirements.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pillow
2+
requests
3+
pyyaml

0 commit comments

Comments
 (0)