Compare commits

...

4 commits

4 changed files with 245 additions and 0 deletions

66
2024/d10/ex1/ex1.py Executable file
View file

@ -0,0 +1,66 @@
#!/usr/bin/env python
import sys
from collections.abc import Iterator
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
def neighbours(self) -> Iterator["Point"]:
for dx, dy in (
(-1, 0),
(1, 0),
(0, -1),
(0, 1),
):
yield Point(self.x + dx, self.y + dy)
TopoMap = dict[Point, int]
def solve(input: str) -> int:
def parse(input: list[str]) -> TopoMap:
return {
Point(x, y): int(c)
for x, line in enumerate(input)
for y, c in enumerate(line)
}
def find_trail_heads(map: TopoMap) -> set[Point]:
return {p for p, height in map.items() if height == 0}
def score_trail(map: TopoMap, start: Point) -> int:
assert map[start] == 0 # Sanity check
res = 0
queue = {start}
visited: set[Point] = set()
while queue:
p = queue.pop()
visited.add(p)
cur_height = map[p]
if cur_height == 9:
res += 1
for n in p.neighbours():
if map.get(n, cur_height) != (cur_height + 1):
continue
if n in visited:
continue
queue.add(n)
return res
map = parse(input.splitlines())
trail_heads = find_trail_heads(map)
return sum(score_trail(map, head) for head in sorted(trail_heads))
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

59
2024/d10/ex1/input Normal file
View file

@ -0,0 +1,59 @@
18776569014346783430321009012345676543089876765012101843210
09683458723454894321234218987432189452176769854323678956521
14592987654098765436549367016543032360145678765014545697434
23601678432132650145678456323456501278234549343478034788910
10712569549241043278901285434787654329103234256589121078923
89803434678950012789854398103490769210567145187678438967434
67810326589867821016760187312521898123498076094501567456556
50981810410778932345123272210634567087654189143215678304567
41832900325696543451074561028701256198563778012324569213498
32963871234587123898785654139987341017652890123473478012323
87874562187671034567698763245676892456701287634982101701414
96565653094544343452188898743786743326898096545679876894505
05454512123349852143089889652898653217652125621043965787676
12343103098256765001234767601701062108943034432152014690189
01289544567187678114345678015612341007765403569061023543287
01276632101096789823210599126543652210812312678278710871296
10345789780125679814676587439874743321907654589189658960345
01234695690434578705689436510165894430418523971012347454434
12304504541128963210790325565256766569349010810143232323521
23413213232037654309821019874305412678256186743256101210650
34329832198747012313412301878912301569107898653087082198761
65896701007658965412301498965887432354518947894198898017321
96785432216234878905432567054896345823101456763234745654450
87123870125165687876541230123445458910112398654125656723765
21012965634018796982650345678032567421012567432098749810894
76321034676569805401721214789121076578323456501589038902923
85432123589458012392895603210434789489210167895610121451012
96524323428301123483486578765965672374331321234785430543212
87012410210216782174987439834874301065145490121096789678101
73453891346785493065234328703893216521036787654567645679201
02567765445698304160145012012743227434321098943658938983210
11098894332103215659876430125652108965670101812340127654321
25437743210114106765454309836543345696987872701235672105898
36727654012325699877869218747434210780745963890104383236785
49818123963445788566978745658923312321894854761201294345656
56709037874236567345432036547012103456783203454398761787654
43237654365187665432301127015432176501654112341432650198323
54108910210094572301432098326721085432456043210541043278910
45678921109001481676501287445856794101387456101650169867610
38787632278112390789043016532943893232297887232789856701521
29698543465243654632132105621032124540196996243456765432430
10101012354305783541245094765021043256785432123455965432107
67652765410216792150956783876107650122312301098767874345698
58543894324345891067810782987238987201406784567854901236787
49987685456543282123425691096543271230545493201993210340123
32106452567650112054534567899454100045654320192387651259654
40045321898342106567651056928767652198743410887434540568798
51235430210289287438122345210178943329652378976543039875687
67896787320176396129034434356598712410701237010132128064516
10765698451965445001545423347895606549890796521243989123105
23896787567843234652436710212874307432037887430145478798234
34785896765432128763429876108963218901126986543234567017345
25634789854578019854210785654851019985435100125676454156236
18721034563689108943218798743344328776434234234981043205145
09343123872672397654309654312235899643421965547872124314076
43216012901521087898701211201156732554310876958943235023489
56905438765432076985654300321076541467215467867654332133012
47876329034310145676701098730987210398706326321038949874323
56981010123421234565892345645678901237987015432127654365434

61
2024/d10/ex2/ex2.py Executable file
View file

@ -0,0 +1,61 @@
#!/usr/bin/env python
import sys
from collections.abc import Iterator
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
def neighbours(self) -> Iterator["Point"]:
for dx, dy in (
(-1, 0),
(1, 0),
(0, -1),
(0, 1),
):
yield Point(self.x + dx, self.y + dy)
TopoMap = dict[Point, int]
def solve(input: str) -> int:
def parse(input: list[str]) -> TopoMap:
return {
Point(x, y): int(c)
for x, line in enumerate(input)
for y, c in enumerate(line)
}
def find_trail_heads(map: TopoMap) -> set[Point]:
return {p for p, height in map.items() if height == 0}
def rate_trail(map: TopoMap, start: Point) -> int:
def helper(pos: Point) -> int:
if map[pos] == 9:
return 1
res = 0
for n in pos.neighbours():
if map.get(n, -1) != (map[pos] + 1):
continue
res += helper(n)
return res
assert map[start] == 0 # Sanity check
return helper(start)
map = parse(input.splitlines())
trail_heads = find_trail_heads(map)
return sum(rate_trail(map, head) for head in sorted(trail_heads))
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

59
2024/d10/ex2/input Normal file
View file

@ -0,0 +1,59 @@
18776569014346783430321009012345676543089876765012101843210
09683458723454894321234218987432189452176769854323678956521
14592987654098765436549367016543032360145678765014545697434
23601678432132650145678456323456501278234549343478034788910
10712569549241043278901285434787654329103234256589121078923
89803434678950012789854398103490769210567145187678438967434
67810326589867821016760187312521898123498076094501567456556
50981810410778932345123272210634567087654189143215678304567
41832900325696543451074561028701256198563778012324569213498
32963871234587123898785654139987341017652890123473478012323
87874562187671034567698763245676892456701287634982101701414
96565653094544343452188898743786743326898096545679876894505
05454512123349852143089889652898653217652125621043965787676
12343103098256765001234767601701062108943034432152014690189
01289544567187678114345678015612341007765403569061023543287
01276632101096789823210599126543652210812312678278710871296
10345789780125679814676587439874743321907654589189658960345
01234695690434578705689436510165894430418523971012347454434
12304504541128963210790325565256766569349010810143232323521
23413213232037654309821019874305412678256186743256101210650
34329832198747012313412301878912301569107898653087082198761
65896701007658965412301498965887432354518947894198898017321
96785432216234878905432567054896345823101456763234745654450
87123870125165687876541230123445458910112398654125656723765
21012965634018796982650345678032567421012567432098749810894
76321034676569805401721214789121076578323456501589038902923
85432123589458012392895603210434789489210167895610121451012
96524323428301123483486578765965672374331321234785430543212
87012410210216782174987439834874301065145490121096789678101
73453891346785493065234328703893216521036787654567645679201
02567765445698304160145012012743227434321098943658938983210
11098894332103215659876430125652108965670101812340127654321
25437743210114106765454309836543345696987872701235672105898
36727654012325699877869218747434210780745963890104383236785
49818123963445788566978745658923312321894854761201294345656
56709037874236567345432036547012103456783203454398761787654
43237654365187665432301127015432176501654112341432650198323
54108910210094572301432098326721085432456043210541043278910
45678921109001481676501287445856794101387456101650169867610
38787632278112390789043016532943893232297887232789856701521
29698543465243654632132105621032124540196996243456765432430
10101012354305783541245094765021043256785432123455965432107
67652765410216792150956783876107650122312301098767874345698
58543894324345891067810782987238987201406784567854901236787
49987685456543282123425691096543271230545493201993210340123
32106452567650112054534567899454100045654320192387651259654
40045321898342106567651056928767652198743410887434540568798
51235430210289287438122345210178943329652378976543039875687
67896787320176396129034434356598712410701237010132128064516
10765698451965445001545423347895606549890796521243989123105
23896787567843234652436710212874307432037887430145478798234
34785896765432128763429876108963218901126986543234567017345
25634789854578019854210785654851019985435100125676454156236
18721034563689108943218798743344328776434234234981043205145
09343123872672397654309654312235899643421965547872124314076
43216012901521087898701211201156732554310876958943235023489
56905438765432076985654300321076541467215467867654332133012
47876329034310145676701098730987210398706326321038949874323
56981010123421234565892345645678901237987015432127654365434