Skip to content

Commit

Permalink
AoC 2024 day 10 part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
loociano committed Dec 10, 2024
1 parent 4d32df2 commit 33f362d
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 0 deletions.
Empty file added aoc2024/src/day10/__init__.py
Empty file.
Empty file.
57 changes: 57 additions & 0 deletions aoc2024/src/day10/python/solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Sequence

type Pos = tuple[int, int]

_TRAILHEAD = 0
_SUMMIT = 9
_IS_GRADUAL_SLOPE = lambda level, next_level: next_level == level + 1


def _find_trailheads(topographic_map: Sequence[str]) -> tuple[Pos, ...]:
"""Finds the positions of trailheads. A trailhead is represented by '0'."""
trailhead_positions = []
for y in range(len(topographic_map)):
for x in range(len(topographic_map[0])):
if int(topographic_map[y][x]) == _TRAILHEAD:
trailhead_positions.append((y, x))
return tuple(trailhead_positions)


def _count_reachable_summits(topo_map: Sequence[str], curr_pos: Pos, visited: set[Pos], num_summits: list[int]):
curr_level = int(topo_map[curr_pos[0]][curr_pos[1]])
if curr_level == _SUMMIT and curr_pos not in visited:
num_summits[0] += 1
visited.add(curr_pos)
return
visited.add(curr_pos)
for step in ((-1, 0), (0, 1), (1, 0), (0, -1)):
next_pos = (curr_pos[0] + step[0]), (curr_pos[1] + step[1])
within_map = 0 <= next_pos[0] < len(topo_map) and 0 <= next_pos[1] < len(topo_map[0])
if next_pos not in visited and within_map:
next_level = int(topo_map[next_pos[0]][next_pos[1]])
if _IS_GRADUAL_SLOPE(curr_level, next_level):
_count_reachable_summits(topo_map, next_pos, visited, num_summits)


def get_score_sum(topographic_map: Sequence[str]) -> int:
"""Gets the sum of all the trails from all the trailheads."""
sum_scores = 0
trailheads_positions: tuple[Pos, ...] = _find_trailheads(topographic_map)
for trailhead_pos in trailheads_positions:
num_summits = [0] # Pass by reference.
_count_reachable_summits(topographic_map, trailhead_pos, set(), num_summits)
sum_scores += num_summits[0]
return sum_scores
Empty file added aoc2024/test/day10/__init__.py
Empty file.
Empty file.
7 changes: 7 additions & 0 deletions aoc2024/test/day10/python/example1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
1110111
1111111
1112111
6543456
7111117
8111118
9111119
7 changes: 7 additions & 0 deletions aoc2024/test/day10/python/example2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
1190119
1111198
1112117
6543456
7651987
8761111
9871111
7 changes: 7 additions & 0 deletions aoc2024/test/day10/python/example3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
1011911
2111811
3111711
4567654
1118113
1119112
1111101
8 changes: 8 additions & 0 deletions aoc2024/test/day10/python/example4.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
89010123
78121874
87430965
96549874
45678903
32019012
01329801
10456732
55 changes: 55 additions & 0 deletions aoc2024/test/day10/python/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
3431014564567889856765432104561217856787834345650410767
4321023673078974323896901223650306945698981298701321898
5891134982100165010187878910765445034567820543432456734
6780147890121016978776965010896532121054210612549345321
5491056787630967869987654123987034910123341701678763430
2312349896549890154890123234569123871431259898569321541
1009456785656743213765012234678034565430968367878490651
3238543876871056902153212105765123470121875454965581740
0147612987962347810042309876894325989430960323784670891
1254101796651258923031498121256716788567871212693021892
2760189845640769854120567010343805697634543000542136763
9871456732239878765987632129452934314523652101239545654
8102320121148543651456783478761043203410789654318767650
9810112510098652100347894567898110112341898769101658941
8723203450567787621239998456987567543898101678102347632
7654310961421298692108783015823458672189012363210412345
8941201872330178787145654324310569789076543654789301256
2300312360545689656014345678210655690343218945689430987
1412543451986770145123212109198744521256707650176521230
0503694012876871234338905410012633230569876543287810321
7654789323905965129847654321710123145678107434496929454
8969876454914456056789878930891231010103298921345218765
9878705967823327643056767011765310121012367800234309454
3210214877012018034145654322654301234189456012125498723
4569823898901219123233458743543210945676788321054321610
2378778767432301012012769658652101876501699490167600501
1267129876541018723103818569785438987612588588998010432
0398034567898129654278903478694323986543437677650323234
5487603478987034563365412323456410076345321761541454143
6034512987656189879450343015667567125256780890132969056
7123432100141098508761261018798258934101298743210878765
8923521231232987612567876529680112343210129654323769876
9812340321201236903498985434543209852101234569834954301
6701054450120145812385890365434901769015101078015867232
5432365965034566703456581270125892378754098129126798103
1019879870103875410787610789816765498763137430934567874
2988218789212980325692101296700012187212346501887656985
3678305654310341236543062345341123098703256232796540176
4549456789423467877879871056732014567890107145601230234
0032966761294558906978787810847812346921298050129821965
1121879850387643216785696921956909855430386765434745874
2340960345465434105898585430341098760987438876125636434
3651451276576123434703450121252387721236589980030127123
8960301289789016521012445696761456872345670891234898034
7871210348058907897654332781890018965645671432105677645
6210143232167812898101221650170123454534982145694789876
4301250143456103763218760521985439210122173036783296765
5654367897876554654109654432676098341013054921042107654
8769016788985467891010123354342187657894567832030078503
9878323412832345672561034565223476678743698948121899812
6765467803421232983478743470110569569652107819238987601
5653456912980221012989856789029678454765432108747896542
1012321233470110103456765891098763243854549654656505632
2187410345561256714987654302187654132923458743215014701
7896509876456349876878963213456565001210567898304323892
41 changes: 41 additions & 0 deletions aoc2024/test/day10/python/test_solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest

from common.python3.AdventOfCodeTestCase import AdventOfCodeTestCase
from aoc2024.src.day10.python.solution import get_score_sum


class TestDay09Solution(AdventOfCodeTestCase):
def __init__(self, *args, **kwargs):
(super(TestDay09Solution, self).__init__(__file__, *args, **kwargs))

def test_part1_withExample_getsScore(self):
self.assertEqual(2, get_score_sum(self.examples[0]))

def test_part1_withExample2_getsScore(self):
self.assertEqual(4, get_score_sum(self.examples[1]))

def test_part1_withExample3_getsScore(self):
self.assertEqual(3, get_score_sum(self.examples[2]))

def test_part1_withExample4_getsScore(self):
self.assertEqual(36, get_score_sum(self.examples[3]))

def test_part1_withPuzzleInput_getsScore(self):
self.assertEqual(825, get_score_sum(self.input))


if __name__ == '__main__':
unittest.main()

0 comments on commit 33f362d

Please sign in to comment.