Solve day 10 of AoC 2024

This commit is contained in:
Ivan R. 2024-12-15 21:21:01 +05:00
parent 7cad6a842c
commit 2c9b5c943e
Signed by: lumin
GPG key ID: E0937DC7CD6D3817
5 changed files with 330 additions and 0 deletions

View file

@ -0,0 +1,184 @@
# Advent of Code 2024 day 10 solution in Ruby
[Task page](https://adventofcode.com/2024/day/10)
## Usage
Run tests:
```bash
ruby test.rb
```
Run solution:
```bash
ruby main.rb
```
## Hoof It
You all arrive at a Lava Production Facility on a floating island in the sky.
As the others begin to search the massive industrial complex,
you feel a small nose boop your leg and look down to discover a reindeer wearing a hard hat.
The reindeer is holding a book titled "Lava Island Hiking Guide". However, when you open the book,
you discover that most of it seems to have been scorched by lava! As you're about to ask how you can help,
the reindeer brings you a blank topographic map of the surrounding area (your puzzle input) and looks up at you excitedly.
Perhaps you can help fill in the missing hiking trails?
The topographic map indicates the height at each position using a scale from 0 (lowest) to 9 (highest). For example:
```
0123
1234
8765
9876
```
Based on un-scorched scraps of the book, you determine that a good hiking trail is as long as possible and has an even, gradual, uphill slope.
For all practical purposes, this means that a hiking trail is any path that starts at height 0, ends at height 9,
and always increases by a height of exactly 1 at each step. Hiking trails never include diagonal steps - only up, down, left, or right
(from the perspective of the map).
You look up from the map and notice that the reindeer has helpfully begun to construct a small pile of pencils, markers, rulers,
compasses, stickers, and other equipment you might need to update the map with hiking trails.
A trailhead is any position that starts one or more hiking trails - here, these positions will always have height 0.
Assembling more fragments of pages, you establish that a trailhead's score is the number of 9-height positions reachable
from that trailhead via a hiking trail. In the above example, the single trailhead in the top left corner has a score of 1
because it can reach a single 9 (the one in the bottom left).
This trailhead has a score of 2:
```
...0...
...1...
...2...
6543456
7.....7
8.....8
9.....9
```
(The positions marked . are impassable tiles to simplify these examples; they do not appear on your actual topographic map.)
This trailhead has a score of 4 because every 9 is reachable via a hiking trail except the one immediately to the left of the trailhead:
```
..90..9
...1.98
...2..7
6543456
765.987
876....
987....
```
This topographic map contains two trailheads; the trailhead at the top has a score of 1, while the trailhead at the bottom has a score of 2:
```
10..9..
2...8..
3...7..
4567654
...8..3
...9..2
.....01
```
Here's a larger example:
```
89010123
78121874
87430965
96549874
45678903
32019012
01329801
10456732
```
This larger example has 9 trailheads. Considering the trailheads in reading order, they have scores of 5, 6, 5, 3, 1, 3, 5, 3, and 5.
Adding these scores together, the sum of the scores of all trailheads is 36.
The reindeer gleefully carries over a protractor and adds it to the pile.
What is the sum of the scores of all trailheads on your topographic map?
## Part Two
The reindeer spends a few minutes reviewing your hiking trail map before realizing something, disappearing for a few minutes,
and finally returning with yet another slightly-charred piece of paper.
The paper describes a second way to measure a trailhead called its rating.
A trailhead's rating is the number of distinct hiking trails which begin at that trailhead. For example:
```
.....0.
..4321.
..5..2.
..6543.
..7..4.
..8765.
..9....
```
The above map has a single trailhead; its rating is 3 because there are exactly three distinct hiking trails which begin at that position:
```
.....0. .....0. .....0.
..4321. .....1. .....1.
..5.... .....2. .....2.
..6.... ..6543. .....3.
..7.... ..7.... .....4.
..8.... ..8.... ..8765.
..9.... ..9.... ..9....
```
Here is a map containing a single trailhead with rating 13:
```
..90..9
...1.98
...2..7
6543456
765.987
876....
987....
```
This map contains a single trailhead with rating 227 (because there are 121 distinct hiking trails that lead
to the 9 on the right edge and 106 that lead to the 9 on the bottom edge):
```
012345
123456
234567
345678
4.6789
56789.
```
Here's the larger example from before:
```
89010123
78121874
87430965
96549874
45678903
32019012
01329801
10456732
```
Considering its trailheads in reading order, they have ratings of 20, 24, 10, 4, 1, 4, 5, 8, and 5.
The sum of all trailhead ratings in this larger example topographic map is 81.
You're not sure how, but the reindeer seems to have crafted some tiny flags out of toothpicks and bits of paper and is using them
to mark trailheads on your topographic map. What is the sum of the ratings of all trailheads?

View file

@ -0,0 +1,57 @@
543213210349876210129890176034034565966563210587109092121
656104101236762121456761789125120677877432101498218187030
787215678945643012369852652196541986778943452387367256541
898764101223454921058943543087632345657654363456456349654
234459814312367838901012634678983954108932276545234438743
105308765101298987632108768901017873217841189034105698894
076218965290345676543289457632124561678750025121236787101
987987874387654989123498398543401410589867014240901223218
128876210260123478004567212898532323475678923457816314509
019564320178874565213216500187645654129854503966765405678
323469834569982104304307431234578765036763212875896876989
767878706521676235425498120110569834545678923214387932376
876967017430501543216326013223432728901298012103098541205
985054328941432652107817154370121112854347543892107670314
834123217632965469234908965987430004761256556701256789323
729654306541874678945699874876548123450236789210345430110
618783210930123012876789103765659874210101654345014521221
105690129850019823498632212014567865321256789765623012434
104941010761236710567541003423438978762349809854789923455
203832123450145623456410212789829569451056012343210854396
312745898567876514589321345657810438342347898901345765987
405656776343998105679430103456910123239897687432216705476
512346785434867234578345612765878762101798576521009812345
694567698123452105507656709894349656123603401098967826565
783878981030143245412349814763234341014512032367654983456
012969976543201236093218923452123210012432145456543452187
121001876124210187187108765421005391143465434505412341093
321232565035303298296089012321016789834874328212303433282
210543458749456334345676521056525470765966019301601214101
109851239658765478034785435437434321014987458456732105010
238760548789678969123699876348945610523456367234845256723
321017656698767056782176501267876525676789210105996367894
438998765589850145891089437678801234989654101986087458965
567321996434743234106543228769960145676543243877124349896
675490887525612103257890119454877658983450112568233210787
587586716014101678965432001323768943232162103499545012345
896675105003234567876721017012057890123078213487636776596
745564234123098656989830398701146321265459812345629889487
932213047894187765216541235610235430876343501676712012376
871302120765276894307890344320145210901265430989800193401
560456961294345653210787653410236389810178125476543287632
410367854386543464678876544567107458103269076398389326543
321298765677812104589965433218998567234387681267276410014
123457654308903243218760129809889234985898790354105569123
016534567210211038909678978321010125676787063203234678874
105673898323302347874541065410981589094543154112356787965
234982765432423456743232456723873672187612267053543298874
122801894541510161250101365834712543870101348765632107985
021289843690678870367010212945603434983289659054901001276
130126732784569965478101204988914301874378778123892104345
245035011098430156789678345677765210165134589104743077656
356544324567821025898569101056879321051021678201654988745
987676543056932110185430202346978432896120214312345679034
678989432108945523679021312567566543787034305478943456123
549034549087876654578110453498754694986545456967012987101
432123678896521783063234569787103785675676567852173985432
101210510123430192154345478776212656548989656743089876501

View file

@ -0,0 +1,45 @@
def count_reachable_positions(matrix)
get_score_sum(matrix, true)
end
def count_hiking_trails(matrix)
get_score_sum(matrix, false)
end
def get_score_sum(matrix, skip_visited_cells)
count = 0
for i in 0..matrix.length - 1 do
for j in 0..matrix[0].length - 1 do
next if matrix[i][j] != 0
count += bfs(matrix, i, j, skip_visited_cells)
end
end
count
end
def bfs(matrix, i, j, skip_visited_cells)
visits = Array.new(matrix.length) { Array.new(matrix[0].length, false) }
queue = [[i, j]]
matches = 0
until queue.empty?
i, j = queue.pop
next if skip_visited_cells && visits[i][j]
visits[i][j] = true
if matrix[i][j] == 9
matches += 1
next
end
queue.unshift([i - 1, j]) if i > 0 && matrix[i - 1][j] == matrix[i][j] + 1
queue.unshift([i + 1, j]) if i < matrix.length - 1 && matrix[i + 1][j] == matrix[i][j] + 1
queue.unshift([i, j - 1]) if j > 0 && matrix[i][j - 1] == matrix[i][j] + 1
queue.unshift([i, j + 1]) if j < matrix[0].length - 1 && matrix[i][j + 1] == matrix[i][j] + 1
end
matches
end

View file

@ -0,0 +1,12 @@
require_relative 'lib'
input = File.readlines('input.txt', chomp: true)
matrix = input.map do |row|
row.split('').map { |n| Integer(n) }
end
res1 = count_reachable_positions(matrix)
puts("Part 1: #{res1}")
res2 = count_hiking_trails(matrix)
puts("Part 2: #{res2}")

View file

@ -0,0 +1,32 @@
require_relative 'lib'
require 'test/unit'
class TestLib < Test::Unit::TestCase
def test_count_reachable_positions
input = [
[8, 9, 0, 1, 0, 1, 2, 3],
[7, 8, 1, 2, 1, 8, 7, 4],
[8, 7, 4, 3, 0, 9, 6, 5],
[9, 6, 5, 4, 9, 8, 7, 4],
[4, 5, 6, 7, 8, 9, 0, 3],
[3, 2, 0, 1, 9, 0, 1, 2],
[0, 1, 3, 2, 9, 8, 0, 1],
[1, 0, 4, 5, 6, 7, 3, 2]
]
assert_equal(36, count_reachable_positions(input))
end
def test_count_hiking_trails
input = [
[8, 9, 0, 1, 0, 1, 2, 3],
[7, 8, 1, 2, 1, 8, 7, 4],
[8, 7, 4, 3, 0, 9, 6, 5],
[9, 6, 5, 4, 9, 8, 7, 4],
[4, 5, 6, 7, 8, 9, 0, 3],
[3, 2, 0, 1, 9, 0, 1, 2],
[0, 1, 3, 2, 9, 8, 0, 1],
[1, 0, 4, 5, 6, 7, 3, 2]
]
assert_equal(81, count_hiking_trails(input))
end
end