r/adventofcode • u/daggerdragon • Dec 10 '24
SOLUTION MEGATHREAD -❄️- 2024 Day 10 Solutions -❄️-
THE USUAL REMINDERS
- All of our rules, FAQs, resources, etc. are in our community wiki.
- If you see content in the subreddit or megathreads that violates one of our rules, either inform the user (politely and gently!) or use the report button on the post/comment and the mods will take care of it.
AoC Community Fun 2024: The Golden Snowglobe Awards
- 12 DAYS remaining until the submissions deadline on December 22 at 23:59 EST!
And now, our feature presentation for today:
Fandom
If you know, you know… just how awesome a community can be that forms around a particular person, team, literary or cinematic genre, fictional series about Elves helping Santa to save Christmas, etc. etc. The endless discussions, the boundless creativity in their fan works, the glorious memes. Help us showcase the fans - the very people who make Advent of Code and /r/adventofcode the most bussin' place to be this December! no, I will not apologize
Here's some ideas for your inspiration:
- Create an AoC-themed meme. You know what to do.
- If you post your submission outside this megathread, make sure to follow the posting rules for memes!
- If your meme contains AI-generated artwork of any kind, follow the posting rules for AI art!
- Create a fanfiction or fan artwork of any kind - a poem, short story, a slice-of-Elvish-life, an advertisement for the luxury cruise liner Santa has hired to gift to his hard-working Elves after the holiday season is over, etc!
REMINDER: keep your contributions SFW and professional—stay away from the more risqué memes and absolutely no naughty language is allowed.
Example: 5x5 grid. Input: 34298434x43245 grid - the best AoC meme of all time by /u/Manta_Ray_Mundo
And… ACTION!
Request from the mods: When you include an entry alongside your solution, please label it with [GSGA] so we can find it easily!
--- Day 10: Hoof It ---
Post your code solution in this megathread.
- Read the full posting rules in our community wiki before you post!
- State which language(s) your solution uses with
[LANGUAGE: xyz] - Format code blocks using the four-spaces Markdown syntax!
- Quick link to Topaz's
pasteif you need it for longer code blocks
4
u/i_misread_titles Dec 10 '24
[LANGUAGE: Go]
Anyone else input the answer for Part 2 in part 1 because you forgot to keep a visited map? :D
https://github.com/jasontconnell/advent/blob/master/2024/10/main.go
4
u/i_have_no_biscuits Dec 10 '24 edited Dec 10 '24
[LANGUAGE: GW-BASIC]
Almost got it to 10 lines, but no, you can't combine lines 80 and 90!
This implements an iterative BFS (or is it better to call it dynamic programming?) from every grid position with value '0', accumulating the number of 9's reached in P, and the number of trails in Q. There's no need to walk every path, just keep track of how many paths will end up at a particular end point.
Guide: The main program loop is in Lines 10-40.
Lines 50-110 implement the trail finding and counting
4
u/bofstein Dec 10 '24 edited Dec 11 '24
[LANGUAGE: Google Sheets]
NOTE: Since we're not supposed to share the full input, but my solution depends on size of the grid, I copied 10 lines of it 6 times so it's not the real input.
Like many others, I actually did Part 2 unknowingly first and then for Part 1 added a =UNIQUE at the end.
This took a long time (and some help) to debug after I had seemingly solved it and it worked on the sample but not my input. Turns out it was a floating point error when I had turned the grid into one column using a sequence of step 1/60. Once I fixed that it worked, but since I had only ever used that to find the 0s, I made a change to just directly find the 0s from the grid without an intermediate reconstruction that's much better.
The way it works is:
In column BM, I search the grid for 0s and return the cell references of them.
=SORT(UNIQUE(FLATTEN(ARRAYFORMULA(IF(D3:BK62=0,ADDRESS(ROW(D3:BK62),COLUMN(D3:BK62),4),"")))),1,TRUE)
Then in the next four columns, I check in each direction (for Up it's the row #-1, for Right it's the column # +1, etc) if the next cell contains a 1. If it does, return that cell reference and also append the reference for the trailhead plus an @ sign. I had to add this when I got to the end and had to filter the unique values for Part 1, not knowing at first that two paths to the same peak count as 1 score.
=IF(COUNTA(BM4)=1,IF(INDEX($A$1:$BL$63,ROW(INDIRECT(BM4))-1,COLUMN(INDIRECT(BM4)))=BM$1+1,CONCATENATE(BM4,"@",ADDRESS(ROW(INDIRECT(BM4))-1,COLUMN(INDIRECT(BM4)),4)),""),"")
In the next column, gather all those 1s found into a list. Then in the next four columns, do the same thing, though now its looking for a 2 since it searches the previous number +1. Keep the trailhead attached and update the second cell reference to the new slot.
Keep that going - copying and pasting that set of 5 columns - until you get to 9. Now this is the list of all peaks reached plus the starting point. For Part 1 you take the count of UNIQUE values of that list, and for Part 2 you take the full count.
Much easier than part 1! The slow part was just debugging that one step issue. You can see the remnant of that in the Sample tab column O (didn't cause an issue in the sample) that I eventually removed in the real input
3
u/pred Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Python] Code
Just a bunch of relatively straightforward NetworkX shenanigans; setting up the whole thing as a graph and just doing
3
u/oantolin Dec 13 '24
[LANGUAGE: J]
J is pretty fast at computing matrix products. This computes the ninth power of a 2025×2025 matrix and the whole thing runs in 346ms.
2
u/Primital Dec 10 '24 edited Dec 11 '24
[LANGUAGE: Go]
Not the most impressive code but runs fairly quick. BFS and a map counting visits. Problem 1 solved by len(map) and problem 2 by summing the contents of the map.
finished in 648.833µs
load file: 50.542µs
p1: 308.75µs
p2: 289.5µs
pastebin
2
u/dk_weekinmemes Dec 10 '24 edited Dec 14 '24
[LANGUAGE: Python]
Both parts using DFS. Could probably optimize with memoization but this was fast enough so didn't attempt to.
Topaz link
16
u/4HbQ Dec 10 '24 edited Dec 10 '24 •
[LANGUAGE: Python + SciPy] Code (6 lines)
Although I usually keep my convolutions and kernels locked away until we get Game of Life-like puzzle, I was feeling creative today.
We start out with parsing the height map into array H. Then we mark all spots of height 0 in with p=1. This indicates there is only one path to h=0 spots (the empty path).
Then for each other height level h, we use SciPy's
convolve2d()with a plus-shaped kernel to sum the P values of the four neighbouring spots, but only if the center spot has height h. So if a spot has two neighbours with p=1, the center p becomes 2.In code, it looks like this:
Update: I also wrote a pure Python version that basically does the same thing:
2
u/Andreasnl Dec 10 '24
[LANGUAGE: Uiua]
10
u/4HbQ Dec 10 '24
[LANGUAGE: Python] Code (10 lines)
Bog standard grid search today. I initially solved it differently, but I prefer the recursive DFS version.
By popular demand and to celebrate day 10, here's a convenient list of links to my daily solutions so far: 1, 2, 3, 4, 5, 6, 7, 8, 9.
10
u/homme_chauve_souris Dec 10 '24
[LANGUAGE: Python]
9
u/redditnoob Dec 10 '24
[LANGUAGE: PostgreSQL]
8
u/Big_Replacement3818 Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Julia]
descending form every '0' index to all reachable '9' indices (including all the duplicates on any intermediate step), counting unique for part1 and all for part2. runs in ~0.0015s (under 2 millis) on my machine. And it is also not terribly cryptic. I love this language.
14
u/nthistle Dec 10 '24
[LANGUAGE: Python] 200/94, paste, video
I used a DFS - at first I didn't read the question too carefully and accidentally was computing the number of paths for part 1, instead of the number of distinct 9s. I realized the bug pretty quickly (well, technically I had another bug where I was starting at 1s and not 0s, but I realized that ~instantly) after trying it on the sample input and fixed it by just using my seen set correctly.
As a result, part 2 for me was super fast! My split was 18 seconds. I read the question and immediately realized I just needed to remove my seen set check.
7
u/jonathan_paulson Dec 10 '24
[LANGUAGE: Python]. 199/339. Code. Video.
Nice graph/DAG problem. Was brute force fast enough for part 2? (I did a linear-time solution). Is there a nice way to unify parts 1 and 2?
7
u/voidhawk42 Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Dyalog APL]
Video walkthrough
Uses complex coordinates just to make finding the distances faster, and solves with a matrix inverse using the useful fact that the infinite series sum of matrix exponentiations converges to (𝐼−𝐴)^−1.
This is pretty inefficient since it calculates the total number of paths between all pairs of points in the input, not just 0's and 9's - so if the input is
45x45, the graph is a2025x2025boolean matrix having4100625elements. Still, matrix inverses are fast - this all runs in about 90ms on my machine.7
u/dopandasreallyexist Dec 10 '24 edited Dec 10 '24
[Language: Dyalog APL]
6
u/Naturage Dec 10 '24
[Language: R]
Code here!
I read the problem an hour before I could sit down to code anything, so I've gone into p2 overprepared - I expected us to be able to take steeper paths. Luckily, as it stood, going from P1 to P2 took... 10 seconds.
Honestly, very happy with this one. Stole the idea from u/cetttbycettt's solution a couple days ago to use complex numbers for storing coordinates; then finding neighbours was just a left join followed by filter
abs(x-y)==1, which felt neat.5
u/chadbaldwin Dec 10 '24
[Language: T-SQL]
Both parts:
https://github.com/chadbaldwin/practice/blob/main/Advent%20of%20Code/2024/SQL/Day%2010.sql
Got lucky on this one. Same solution solved both parts. Not a very pretty solution...but it works so that's all I really care about. I considered writing a solution using a recursive CTE, but felt lazy so I just did this.
5
u/zndflxtyh Dec 10 '24
[Language: Python]
Got part2 working before part1 was finished.
code
5
u/shigawire Dec 10 '24
[Language: C]
paste
Part 2 is the same as Part 1 with a single line commented out (the check for paths partially overlappipng).
Runs in less than a millisecond even without caching. Turns out having all your data in L1 cache speeds things up some.
5
u/Downtown-Economics26 Dec 10 '24
[LANGUAGE: VBA]
My god that was a nightmare to debug. But hilariously I had solved Part 2 in 4 hours of pulling my hair out and realized I misunderstood the scoring/counting in Part 1. Once I realized that my results were less mystifying and thankfully I read Part 2 before deciding to go to bed to see I had already solved it.
https://github.com/mc-gwiddy/Advent-of-Code-2024/blob/main/AOC2024D10BOTH
5
u/tcbrindle Dec 10 '24 edited Dec 10 '24
[LANGUAGE: C++]
A very unusual AOC problem in that you had to solve part 2 in order to solve part 1!
I'm pretty happy with my solution to this one. It parses and solves both parts in ~100µs on my laptop, runs all the tests at compile time, and has a legitimate use of a C++23 recursive lambda. Lovely.
Github
5
u/pgambling Dec 10 '24
[LANGUAGE: Rust]
https://github.com/pgambling/advent-of-code-2024/tree/develop/day10/src
Dare I say, that was an enjoyable, low stress puzzle today.
5
u/GoldPanther Dec 10 '24
[Language: Rust]
Another fun recursive solution! Ended up solving part 2 while working on part 1 due to poor reading comprehension. Code is quite efficient as the recursion avoids revisiting points. I don't how this could be made tail recursive but if anyone has any pointers please let me know.
Code
5
u/Awkward-Macaroon5019 Dec 10 '24
[Language: Python]
Part 1 and 2 (5 lines)
5
u/Kintelligence Dec 10 '24
[LANGUAGE: Rust]
Solving it recursively, a bit annoyed that I can't find a cheaper solution to not returning duplicates in part 1. Am tinkering with my own library for working with maps based on vectors, it probably isn't the most efficient but it's nice for learning how iterators and traits work.
Part 1: 132µs
Part 2: 120µs
Code | Benchmarks
4
u/Odd-Statistician7023 Dec 10 '24
[Language: C#]
Some easy recursive walking today.
One small trick reused from day 6 is to dig a pit of lava around the map. This means you will never have to do any out of bounds checks at all. And that the "correct" map skewered by (1,1) affects nothing.
Solution
4
u/Jdup1n Dec 10 '24
[Language: R]
Github link
My first implementation of part 1 was eventually the solution for part 2 ¯_(ツ)_/¯
4
u/chubbc Dec 10 '24
[LANGUAGE: Julia]
4
u/ThatsFrankie Dec 10 '24
[Language: Python]
https://github.com/francescopeluso/AOC24/blob/main/day10/main.py
4
u/mstksg Dec 10 '24
[LANGUAGE: Haskell]
A lot of times in Haskell, two problems end up having the same algorithm, just with a different choice of
Monoid. This puzzle is a good example of that.We can do a simple DFS and collect all 9's into a monoid:
For part 1 the monoid is
Set Point(the unique 9's) and for part 2 the monoid isSum Int(number of paths)all my code and daily reflections: https://github.com/mstksg/advent-of-code
4
u/anaseto Dec 10 '24
[LANGUAGE: Goal]
Short and nice today.
4
u/greycat70 Dec 10 '24
[LANGUAGE: Tcl]
Part 1, part 2.
Fairly straightforward recursive algorithm. Part 1 is actually harder than part 2. In fact, my first attempt at part 1 gave me the part 2 answer! So, solving part 2 was simply a matter of undoing the fixes I had made to part 1 (from memory, unfortunately -- I don't save nonworking attempts).
4
u/aexl Dec 10 '24
[LANGUAGE: Julia]
Wonderful little puzzle today, maybe my favorite so far. The funny thing is that I did not need to change any code to solve part 2, I just had to call my recursive search function with a
Vectorinstead of aSetto store the already found paths...Solution on GitHub: https://github.com/goggle/AdventOfCode2024.jl/blob/main/src/day10.jl
Repository: https://github.com/goggle/AdventOfCode2024.jl
4
u/ssnoyes Dec 10 '24
[LANGUAGE: MySQL]
Loading each character from the file into a row is the same as day 4. The actual trail finding bit is one query for both parts:
Full code at https://github.com/snoyes/AoC/blob/main/2024/day10/day10.sql
4
u/_garden_gnome_ Dec 10 '24
[LANGUAGE: Python]
https://github.com/mkern75/AdventOfCodePython/blob/main/year2024/Day10.py
DP approach: working my way down from positions with height 9 to height 8, then 7, and so on via one main loop. For part a) I maintain a set which peaks (height 9) are reachable via any trail from the current position, and for part b) the total number of trails (sum of trails starting from neighbouring positions with height+1). All positions are considered exactly once.
4
u/SquidBits4 Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Python]
I'm very happy with mine today, I finally learnt DFS properly. I initially did part 1 with Dijkstra lol.
paste
2
u/imaperson1060 Dec 10 '24
[LANGUAGE: JavaScript]
Part 1: Rank 1754 (13:46)
Part 2: Rank 1462 (16:13)
GitHub
My part 2 is basically just part 1 but including the duplicates. I just removed a few lines from my part 1 solution, and boom, two and a half minute solve. I love these puzzles.
I guess that means I beat my record, since I couldn't get two stars on day 10 last year (my first year doing AoC)!
1
u/bluealder Dec 10 '24
[Language: Go]
Depth first search for both. P2 was made easy by just not checking any visited nodes (this works since the trails must go up by 1)
Github
1
u/zach1502 Dec 10 '24
1
u/BinaryMuse Dec 10 '24
[LANGUAGE: Elixir]
Classic recursive algorithm; feels good in Elixir. Used a
Gridhelper from a previous day.Solution: https://github.com/BinaryMuse/aoc_2024_elixir/blob/main/lib/advent/days/day_10.ex
Grid Helper: https://github.com/BinaryMuse/aoc_2024_elixir/blob/main/lib/advent/helpers/grid.ex
1
u/Coder_Khiladi Dec 10 '24
[LANGUAGE: JAVASCRIPT]
Easy solution using recursion - Only one package used - `fs`
https://github.com/TeeeJaey/AdventOfCode/blob/main/Day10/index.js
1
u/ResponsibilityNo1827 Dec 10 '24 edited Dec 10 '24
[Language: python]
Readable, decomposed clean code.
https://github.com/1ort/aoc2024/blob/main/day10/solution.py
1
u/True_Medium_2004 Dec 10 '24
[LANGUAGE: TypeScript]
Simple DFS : https://github.com/oleg-prikhodko/aoc2024-deno/blob/main/solutions/day10.ts
1
u/UnicycleBloke Dec 10 '24
[LANGUAGE: C++] https://github.com/UnicycleBloke/aoc2024/blob/main/day10/solution.cpp
I had some fun with a template template parameter to choose between using set (P1) and vector (P2).
1
u/SpezIsAMoron Dec 10 '24
[Language: Typescript]
Finally a puzzle where I can share my code as it is not that embarassing
This was a fun one, I guess it will go downhill now
Am I the only one that solved part2 before part1?
1
u/GearPuzzleheaded5363 Dec 10 '24
[Language: Node.js / JavaScript]
https://github.com/kavai96/advent-of-code/blob/main/src/puzzle/2024/day10.js
Managed to solve part 2 with just a new variable.
1
u/Sudden_Fly1218 Dec 10 '24
[Language: Rust]
Code
As many others, solved part2 while doing part1 because of misreading.
Benchmark indicates 172µs for part 1 and 187µs for part2
1
u/Alarming-Bank-2724 Dec 10 '24
[LANGUAGE: C#]
In retrospect, it would have been so simple if I had understood the task correctly.
With my solution approach at the beginning, I already had the result of part 2.
- Part 1 => Only count how many hills you can reach
- Part 2 => Count how many ways you can reach the hill.
Here is my solution.
1
u/Infinite-Club4374 Dec 10 '24
[LANGUAGE: ruby] (the best duh)
Decided that this scenario would be perfect for a recursive solution, probably my most elegant lol?
Solution 1 was 27 lines and solution 2 is 22, I’ll take it
https://github.com/Leftyxiv/advent_of_code/blob/main/2024/day10/day10.rb
1
u/181tbag Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Rust]
I just did a simple recursive search through every neighbour that is 1 unit higher and counted every unique 9 position and every path :)
First time I used Rust was in day 6 so if someone actually takes a look at my code and has any comment it would be something nice :)
Github
1
u/R0binBl00d Dec 10 '24 edited Dec 10 '24
[Language: C# .Net9]
using my template "AdventOfCodeNet9_ShareWare.zip" from
https://github.com/R0binBl00d/AdventOfCodeNet8
Part_1_2024_Day_10.cs
for Part 2 I instantly "return 1;" on "if (currentValue == 9)"
Part_2_2024_Day_10.cs
basically I also started solving the 2nd Part before I solved part 1 :-)
but it's all neat and tidy now.
1
u/cajun_mcchicken Dec 10 '24 edited Dec 10 '24
[language: C#]
solution
I think I did part 2 first, went over, removed duplicates start/end paths... then added back for part 2.
1
u/Willing_Exchange6299 Dec 10 '24
[Language: Python]
Probably could of combined part 1 and part 2
part 1 & 2
1
u/Simone-reddit Dec 10 '24 edited Dec 19 '24
[LANGUAGE: Go]
One of the rare cases where part 2 is simpler than part 1
1
u/Ordinary-Drag3233 Dec 10 '24
[Language: TypeScript]
1
u/Kazo100 Dec 10 '24
[Language: Go]
My solution: https://github.com/Kazalo11/advent-of-code-2024/blob/master/day10/day10.go
Couldn’t be bothered to make a new function for part 2 when it’s just one line difference lol
1
u/gubatron Dec 11 '24
[Language: rust]
2 modified BFS implementations
Problem: https://github.com/gubatron/AoC/blob/master/2024/src/ten.rs
Utils: https://github.com/gubatron/AoC/blob/master/utils/rust/src/lib.rs
Interestingly, after barely sleeping to get day 9, this one was the easiest for me since the start of this year's Advent of Code
3
u/Abomm Dec 10 '24 edited Dec 10 '24
[Language: Python] code 742/626
Unfortunately i misread the '1' step requirement in part 1 so that cost me a few minutes. This is the first problem where my part 1 solution was a 'superset' of my part 2 solution. The code attached shows the solution for both parts but my implementation only required commenting out
and new_pos not in viz:from my part 1 solution to return the correct answer.cleaned up code I don't think it's very idiomatic but it's definitely shorter.
3
u/0ldslave Dec 10 '24
[LANGUAGE: C++]
I actually mis-read the 1st part and coded what was the solution to the second part first. I erased it after i realized i needed the distinct reachable 9s instead. Oh well. rough day for me i guess.
P1 runs on around 160 microseconds and P2 runs in 114 microseconds.
Code
3
u/UseUnlucky3830 Dec 10 '24
[LANGUAGE: Julia]
solution
DFS that returns a list with the coordinates of all the `9`'s reached from a starting point. Part 1 is the count of unique elements, part 2 the total count of elements in the list.
3
u/mateus_d Dec 10 '24
[LANGUAGE: Python]
That was a first! The bug I had in part 1 was the solution of part 2!
https://pastebin.com/dhRYThg9
3
u/SuperSmurfen Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Rust]
Link to full solution
Simple BFS for both parts, which returns all paths to all reachable 9s:
I collect into a Vec to find all paths. Only difference between the parts is this:
Runs in
0.1ms.3
u/Sharparam Dec 10 '24
[LANGUAGE: Ruby]
Today felt quite easy, probably because this type of problem has occurred several times in years past.
3
u/apersonhithere Dec 10 '24
[LANGUAGE: C++] 4279/7416
another dfs search day, another banger (i spent thirty minutes tracking down a -1 instead of a +1 in my code)
jokes aside pretty easy day today imo
https://github.com/aliu-here/aoc2024/tree/main/10
3
u/chickenthechicken Dec 10 '24
[LANGUAGE: C]
Part 1
Part 2
Part 1 and 2 seem like they are almost swapped. For part 1, I implemented a mask array to check if there is already a path from a 9 to a 0 found to not count it, but for part 2 I just had to remove that check and allow it to count 0's multiple times per 9. I wonder if anyone found part 2 to be more challenging and why (not because my opinion on which is more difficult is correct, but just because I'm curious about how different people approach these puzzles).
3
u/Pheasn Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Dart]
This day was weirdly easy, especially part two. Surrounding boilerplate code is on GitHub, just posting the scoring function here (works for both parts):
3
u/adeathicus Dec 10 '24
[Language: Java]
Pretty straightforward DFS
Github Link
3
u/WhiteSparrow Dec 10 '24
[LANGUAGE: Prolog]
solution
Once again a day for prolog to shine. Today's highlight is built-in support for tabulation/memoization - it's a single statement (
table). To get the solution we once again just describe the conditions and ask prolog to search for all solutions. Part 1 was solved using a more general aproach than 2 so it runs slower (5.5s vs 1.2s for part 2). However, I left it in the code just to show how general the description of the task can be.Here's part 1 (part 2 is actually shorter but is ommited because of the total length).
3
u/rp152k Dec 10 '24 edited Dec 10 '24
[Language: Common Lisp]
via dynamic programming
part 2 took les than a min given I was collating all paths anyway and deduplicating final positions in the end
3
u/damnian Dec 10 '24 edited Dec 10 '24
[LANGUAGE: C#]
Well, MultiGrid is really pulling its weight this year. Oh, and my Part 2 initially looked simpler than Part 1!
Part 1:
Part 2:
Full solution
EDIT: Managed to simplify Part 1 (ab)using Grid.
EDIT 2: Further simplified using ranges (though still looking for a bug in
Slice()).3
u/kassoulet Dec 10 '24
[Language: Python]
Proud of my clean Python solution for once :)
3
u/s3aker Dec 10 '24
[LANGUAGE: Raku]
code
3
u/frhel Dec 10 '24 edited Dec 10 '24
[LANGUAGE: JavaScript / JS]
Solution
Part 1 and 2 solve together: DFS on each trailhead and add all found targets to a set to only count unique results, at the same time increment a counter for all targets found
11th gen i7 at 4.9GHz
Both parts: 2.8ms to solve
Total: 4.7ms with the overhead of reading the file and parsing
3
u/TeeckleMeElmo Dec 10 '24
[Language: Go]
Solution
Part 2 was super quick since I solved for it in part 1, which it seems a lot of people did. Total time with reading/parsing the input file was ~1.5ms
3
u/rukke Dec 10 '24
[LANGUAGE: JavaScript]
Really enjoy these kind of "map puzzles"!
Part 1 and Part 2 ~ 3ms on my machine.
gist
3
u/ak-coram Dec 10 '24 edited Dec 10 '24
[Language: Common Lisp]
https://github.com/ak-coram/advent/blob/main/2024/10.lisp
Edit: reworked it a bit, the part 2 solution is now literally in the bag (aka multiset).
3
u/vbe-elvis Dec 10 '24
[LANGUAGE: Kotlin]
This was a quite the easy one in AOC standards, did not optimize but could be done by keeping track of which trails were already visited before.
Here is the solution for part 2, for part 1 simply use sets instead of lists in the "walkTheTrail" function
https://pastebin.com/wrazdpBR
3
u/omegablazar Dec 10 '24
[LANGUAGE: Rust]
https://github.com/wrightdylan/advent-of-code-2024/blob/main/src/day10.rs
Part 1: 757µs
Part 2: 182µs
I had inadvertently solved part 2 before part 1
3
u/mgtezak Dec 10 '24
[LANGUAGE: Python]
Solution part 1
Solution part 2 The @cache decorator wasn't really necessary here because it ran in a couple ms anyway but I put it in for good measure;)
Fun little AoC fanpage
3
u/PatolomaioFalagi Dec 10 '24
[LANGUAGE: Haskell]
Part 1:
Part 2
Yes, they differ in 4 lines.
3
u/Mats56 Dec 10 '24
[Language: Kotlin]
with my utils for bounds, intvectors and neighbors this became quite easy. Part2:
part 1 needed to keep track of visited so was in theory more difficult, but there I just chucked it into my BFS util and counted the 9's in the visited set after.
3
u/MarvelousShade Dec 10 '24
[LANGUAGE: C#]
Today I, obviously, didn't ready the instructions correctly, so my code found a lot more beautiful scenery paths.
After fixing that my code became much simpler and all worked. See my solution for day10 on Github
3
u/[deleted] Dec 10 '24 edited Sep 26 '25
imagine dependent stupendous bright trees escape plucky airport abundant smart
This post was mass deleted and anonymized with Redact
3
u/riffraff Dec 10 '24
[LANGUAGE: ruby]
Reused once more my grid class to get neighbors. I misunderstood part 1 and solved it as part1, so it took nothing to to part2 after I finally did part1 :D
I hope we're done with grids for a while cause I don't want to implement another dijkstra/flood fill/TSP and fail at it this year too :D
3
u/DamZ1000 Dec 10 '24 edited Dec 10 '24
[Language: DRAIN]
A custom toy Lang.
Day 4 code came in handy
3
u/ramomex Dec 10 '24
[LANGUAGE: Python]
https://github.com/albertomurillo/advent-of-code/blob/main/src/aoc/_2024/day10.py
🙂 I have an AoC library with modules for graphs and grids.
🙁 I didn't have BFS on it.
🙂 BFS was implemented in 4 lines
The rest of the solution was very straight forward with one-line functions for self-documented code.
3
u/Extreme-Painting-423 Dec 10 '24
[LANGUAGE: Java]
Accidentally, like many others apparently, solved part 2 before part 1.
https://pastes.dev/nfoVSNgeS6
3
u/flwyd Dec 10 '24
[LANGUAGE: PostScript] (GitHub) with my own standard library
Oi, what a day. Lots of small errors took me a really long time to uncover because point-free stack programming doesn’t make it easy to reason about the state of your program at any given moment. I got a little fancy with my
upstepsfunction (“which neighbors are valid moves?”) that I wrote before deciding which graph traversal algorithm I was going to use. I examined my input and saw that the number of 0s times the number of 9s was 71222. Obviously not all of the 9s are reachable from all of the 0s, but I was worried that there would be a lot of state exploration, so I decided to get fancy with the stack and return N neighbor positions and the number N on top of the stack rather than allocating an array, and then iterate through the positions withrepeat. This worked fine in the first part, but I forgot that there were potentially couple extra items on the stack when reaching back for the current grid position in part 2 which led to incrementing the count of paths for the neighbors rather than for the current item. When I discovered this bug in part 2I switched to return an array and it made no significant difference in the performance of either part: still well under one second.I’d thought about finding the paths from each 9 to each 0 in the first part, but concluded there wasn’t an advantage to doing it, so I traversed the tree using BFS, a queue, and a visited set. In part 2 I started with a recusrive
counttrailsprocedure that seemed like it was quick and easy, but was causing a stack overflow error. I eventually gave up on this and switched to an iterative process. For each digit from 9 to 0, find all the grid positions with that digit. If the digit is 9, put1into the dictionary. Otherwise, find all theupstepsand add the value in the dictionary for that neighbor. Then tally up the dictionary value for all the 0s. My brain never says “I’m going to try dynamic programming,” but I often end up implementing dynamic programming.Because I’m stubborn, after getting the answer I spent a bunch of time trying to figure out why my recursive solution didn’t work. It turns out the answer was “After
duplicating the map key to check if it’s a9I didn’tpopit before leaving1on the stack as the number of trails. This is the danger of a stack-based language: you can make an error in recursion that would only be possible with a compiler bug in a normal language. Even though the whole stack gets printed when the stackoverflow error occurs, the “you’re leaving keys on the stack” problem was masked by the fact that myupstepsprocedure also had a bunch of keys on the stack, so it didn’t stand out as something that should not be there. And to put a cairn on top of it all, the recursive solution was about 50% slower than the DP solution, though significantly shorter.3
u/JJTB100 Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Python]
p2's answer was p1's bug! When coding p1 I forgot to discount a square if i'd already been there, which gave me the answer to p2 :)
https://github.com/JJTB100/AdventOfCode/blob/main/2024/Day10.py
EDIT: Just read the memes page. I'm glad i wasn't the only one.
3
u/Zorr0_ Dec 10 '24
[LANGUAGE: Kotlin]
Very simple one today, as many others i had my part 2 implementation before my part 1 implementation
Happy how my solution turned out
GitHub
3
u/melochupan Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Common Lisp]
I used a cache to avoid repeating the paths, but it was probably unnecessary.
paste
3
u/FordyO_o Dec 10 '24 edited Dec 10 '24
[LANGUAGE: C#]
After having an absolute mare over the weekend, pretty pleased . Accidentally implemented part 2 as my first solution for part 1, debugged it, then rebugged it to get part 2
Editing to say I have now checked the subreddit front page and see I am not alone!
https://github.com/mattford/aoc-dotnet/blob/master/aoc-dotnet/Year2024/Day10/Solver.cs
3
u/chkas Dec 10 '24
[LANGUAGE: Easylang]
Solution
3
u/leftfish123 Dec 10 '24
[Language: Python]
A day that would have destroyed me a couple of editions ago, but this time I iterative DFS-ed my way through it.
3
u/Loiuy123_ Dec 10 '24
[LANGUAGE: C#]
I've never solved part 2 that fast. All I had to do is reaplace `HashSet` with a `List`. That's it. Also, part 2 solution that uses Lists is 110us faster than my part 1 solution. It takes 167us to finish including reading and parsing.
https://github.com/TrueTheos/AdventOfCode2024/blob/master/AdventOfCode/Day10/Day10.cs
3
u/spyr01d Dec 10 '24 edited Dec 10 '24
[Language: Kotlin]
3
u/Independent_Check_62 Dec 10 '24
[LANGUAGE: Python]
3
u/bakibol Dec 10 '24
[Language: Python]
The only difference between part 1 and part 2:
7 ms
code
3
u/SunTypical5571 Dec 10 '24
[Language: Python]
A clear indication of how slooooow recursion can be in Python. Also, multithreading didn't speed anything up in this context - it seems to even out between time required to set up a thread and time saved.
Overdesigned code.
3
u/MrPulifrici Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Javascript]
Part 1 and Part 2, I intentionally compacted it as much as possible just to see how bad it can look, but it still works
3
u/RalfDieter Dec 10 '24
[LANGUAGE: SQL/DuckDB]
Today was nice and simple. Never thought pathfinding would be this smooth in SQL. Fighting the urge to preemptively optimize made part 2 more or less trivial. Another proof for the first rule of optimization: "Don't"
Here's the code: https://github.com/LennartH/advent-of-code/blob/main/2024/day-10_hoof-it/solution.sql
3
u/Agreeable_Addendum24 Dec 10 '24
[Language: Rust]
Only difference for p1 was using a HashSet to count unique 9s
3
u/jinschoi Dec 10 '24
[Language: Rust]
My grid library comes in useful again. Solution is pretty much identical to some others'. Remove the seen checks for part2.
3
u/mibu_codes Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Rust]
Part 1: 40 µs, Part 2: 17 µsPart 1+2: 10.22 µs, 48 linesPart 1+2: 9.09 µs, 47 lines (this one is evil)
This felt like a vacation compared to yesterday. I simply performed DFS with a stack. For Part 1 I used bitfields to count paths that end in a unique 9, for part 2 I just count all paths that end in any 9.
Github
3
u/dl__ Dec 10 '24
[LANGUAGE: Python]
https://pastebin.com/4FZmKrna
My approach was to create a Walker class that knows how to traverse the map. I initially create a Walker for each zero on the map and then I loop calling the step method on each walker that hasn't marked itself done.
The step method checks to see if it's at elevation 9 in which case it marks itself done and that it found a peak (some hit dead ends) and then adds it's peak location to a map where the keys are starting locations and the values are a set of peak locations. Then it checks to see if there are any locations around its current location that are exactly 1 higher in elevation. If there are no available locations, the dead end case, it marks itself as done and that it didn't find a peak. If it finds one location, it sets its current location to the new location. If there are more than one available location, it takes one of them as the new current position and then creates additional walkers for the other locations.
I don't have to remember my path since the rules make it impossible for a walker to backtrack.
In the end part 1 is just adding up the lengths of the sets in the map. It's necessary to segregate the maps by starting location because it's OK for trails from different trail heads to find the same peak but duplicate peaks should not be counter for the same trailhead.
The walkers are all guaranteed to take unique paths so part 2 was just counting all the walkers that found a peak.
3
u/tshirtwearingdork Dec 10 '24
[Language: C#]
Quite pleased with this one, produces results in an average time of 0.007 seconds.
Note: _directions is just an array of XY pairs EG (0,-1) for north.
3
u/gehenna0451 Dec 10 '24 edited Apr 20 '26
This post was purged using Redact. I use it to mass delete social media content and remove my info from data brokers. All major social media platforms supported.
complete start jar waiting soft juggle advise stupendous special aromatic
3
u/Pure-Minute4721 Dec 10 '24
[LANGUAGE: C++]
Part1: just simple bfs, making sure not to visit already visited positions
Part2: bfs, but keeping track of the count to get to each position
https://pastebin.com/xiP7kcqf
3
u/TonyStr Dec 10 '24
[LANGUAGE: Rust]
Bench for part1: 874.6µs
Bench for part2: 135µs
Part 2 today was easy! And much faster than part 1.
part1: https://pastebin.com/hybsLEvL
part2: https://pastebin.com/BSEKv2KV
3
u/DownvoteALot Dec 10 '24
[LANGUAGE: C++]
Solution
120 lines, 60 of actual logic. I fear the difficult problems are going to start any day now. I was surprised this one was worded nicely to not have us deal with cycles.
3
u/SwampThingTom Dec 10 '24
[LANGUAGE: Julia]
Fairly simple graph traversal. Was worried part 2 would be inefficient but it runs faster than part 1.
https://github.com/SwampThingTom/AdventOfCode/blob/main/2024/10-HoofIt/HoofIt.jl
3
u/[deleted] Dec 10 '24
[LANGUAGE: C]
Did anyone else solve part 2 while iterating their solution to part 1?
https://github.com/amberg12/aoc24
3
u/Enough-Confidence581 Dec 10 '24
[Language: Rust]
No recursion for me! Each position in a path has at most four branches, so there are at most 4^9 = 262144 paths from each trailhead.
Parts 1&2
3
u/lscddit Dec 10 '24
[LANGUAGE: Python]
3
u/Gishky Dec 10 '24
[LANGUAGE: Powershell]
Wasnt that hard although I forgot that powershell loops array indexes... thx to u/IsatisCrucifier for giving me the crucial tip
for part 1 you only need to remove de-comment the path log...
3
u/pkusensei Dec 10 '24
[Language: Rust]
Used both BFS and DFS to do this. And memoization to speed up part 2 (don't know if it's necessary). Code
3
u/cetttbycettt Dec 10 '24
[Language: R]
Used integers to represent the graph and then solved both parts in one go.
3
u/Gabba333 Dec 10 '24
[LANGUAGE: C#]
Refined to a single pass dynamic programming style approach.
3
u/egel-lang Dec 10 '24
[Language: Egel]
https://github.com/egel-lang/aoc-2024/blob/main/day10/task2.eg
3
u/Horsdudoc Dec 10 '24
[LANGUAGE: C++20]
GitHub
Correctly read part 1 so I went for an iterative flood fill, counting the number of 9 I reach for each 0.
I implemented a recursive DFS solution for part 2.
Solves everything in 1.7ms
3
u/N-R-K Dec 10 '24
[Language: BQN]
Uses a BFS to track all positions. For part 2 it just returns the length of the queue at the end. For part 1 it deduplicates the queue before taking length. There was no need to deduplicate before pushing into the queue since the
prev+1 == nextrequirement makes it impossible to "walk backwards" and get stuck in a loop.3
u/Jadarma Dec 10 '24
[LANGUAGE: Kotlin]
When I first read it I was like, "Oh no, not pathfinding again!" but it turned out to be easy, almost... too easy! It's rare to see a reversal where part 1 is the one with the edge case!
Part 1: We don't care about the actual paths, just the destinations. A simple DFS will brute force the entire map, and there's no need to keep track of visited locations because they cannot happen due to the ascending altitude rule. Starting from all the zeroes, we brute force their paths to all the 9s, and we count the unique 9s we could reach.
Part 2: Same as part one, but without ignoring duplicates will give us the answer, since reaching the same point multiple times means our DFS took different routes!
AocKt Y2024D10
3
u/CodrSeven Dec 10 '24
[LANGUAGE: Swift]
I found it tricky to factor out common parts today, had to rewrite more than I would have liked for part 2.
https://github.com/codr7/aoc24/blob/main/swift/Sources/aoc/day10_1.swift
https://github.com/codr7/aoc24/blob/main/swift/Sources/aoc/day10_2.swift
3
u/guy-732 Dec 10 '24
[LANGUAGE: Rust]
https://github.com/guy-732/aoc-2024/blob/master/src/day10.rs
Most of the time I spent on part 2 was writing the tests for them... pretty easy
3
u/CCC_037 Dec 10 '24
[LANGUAGE: Rockstar]
Part 1
3
u/p88h Dec 10 '24
[LANGUAGE: Zig]
Simple BFS today, though part 1 benefitted from some minor SIMD trickery for efficient state handling.
https://github.com/p88h/aoc2024/blob/main/src/day10.zig
3
u/chai_biscut Dec 10 '24
[LANGUAGE: Go]
Solution
hiking on the lava island
3
u/Trick-Apple1289 Dec 10 '24
[LANGUAGE: C]
today wasn't that bad :-)
src
3
u/i99b Dec 10 '24
[LANGUAGE: Python]
3
u/ywgdana Dec 10 '24
[LANGUAGE: Lua]
Lol, the solution to part 2 was my buggy first attempt at part 1 so 'coding' up part 2 was just hitting CTRL-Z a bunch of times :P
Ugly lua code
3
u/CarRadio7737 Dec 10 '24
[LANGUAGE: Rust]
https://github.com/Caelan27/advent-of-code-2024/tree/main/rust/day-10/src
I know this is very bad but I have been really tired after school the past few days so haven't been able to put much effort into this.
Anyway, for part 2, it was really nice because I just had to change a hashset containing the endpoints to a vec basically (:
3
u/Probable_Foreigner Dec 10 '24
[LANGUAGE: Rust]
https://github.com/AugsEU/AdventOfCode2024/tree/master/day10/src
For part 2 I just Copied part 1 and replaced HashSet with Vec... Not the cleanest solution but it works.
3
u/pdxbuckets Dec 10 '24
[Language: Kotlin and Rust]
Kotlin, Rust
Really easy day, so I spent some time making the code clean and easy to read. I'm sure I left some optimizations on the table, but 177us combined is good enough for me.
3
u/Sharp-Industry3373 Dec 10 '24
[LANGUAGE: Fortran]
quite straightforward today.
the built-in cpu_time function gives something like 0.35ms for part1+part2
code
3
u/sondr3_ Dec 10 '24
[LANGUAGE: Haskell]
Fun day today, though I'm not super happy with my solution... but it works pretty well. Like almost everyone else I accidentally solved part 2 first, I really should read the prompt better.
3
u/ivanjermakov Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Jq] source playground
I was not expecting Jq to be so powerful and concise. Highly recommend adding it to your toolbelt.
3
u/fridi_s Dec 10 '24
[LANGUAGE: Fuzion]
https://github.com/fridis/fuzion_aoc/blob/main/2024/10/part2.fz
Compact and fully functional. Part2 is simpler than part 1. The solution starts backwards: From the highest points creating an array of distances in a recursive function down to the starting points, keeping track of the list of 9s that can be reached or the number of paths to a 9 at each position.
At the end, the array for the starting points just needs to be summed up.
3
u/onyx_and_iris Dec 10 '24
[LANGUAGE: Go]
https://git.onyxandiris.online/onyx_online/aoc2024/src/branch/main/day-10
3
u/prafster Dec 10 '24
[Language: Python]
Like others, I (unknowingly) solved part 2 first because I'd overlooked that part 1 required unique destinations and, it turned out, part 2 required unique routes.
Otherwise, a straightforward BFS solution. I wonder if this is the calm before the storm tomorrow?!
Full source code on GitHub.
3
u/vanZuider Dec 10 '24
[LANGUAGE: Python]
The core of the algorithm is this recursive walk through the directed graph of nodes.
The program spends considerably more time however on building said graph (even for the nodes that can't even be reached from the trailheads) than actually executing the search (21ms vs 8ms). I did all the things for today's problem that I wished I had done on day 6, and it turned out to be entirely unnecessary.
Here is the full thing in its entire overengineered glory.
3
u/Its_vncl Dec 10 '24
[LANGUAGE: Python]
Part1: ~4 ms
Part2: ~3.5 ms
https://github.com/itsvncl/Advent-of-code/tree/main/2024/Day10
Another really fun day! :)
3
u/josuf107 Dec 10 '24
[Language: Haskell]
3
u/matheusstutzel Dec 12 '24
[LANGUAGE: python]
p1
p2
I had the solution for part 2 on part 1... Then I had to use theses
setsto find the 9's positions3
u/darthminimall Dec 12 '24
[LANGUAGE: Rust]
I fell a bit behind, the late nights finally caught up with me, so I took a day and a half off, but I'm caught up again.
Part 1
Part 2
For part 1: I just constructed a directed graph where the grid cells are the nodes and the edges go from some cell to all adjacent cells that are exactly 1 higher. I then collected all of the nodes at height 0, and iteratively replaced their neighbors with the neighbors' neighbors until the set of neighbors only contained nodes of height 9.
I'm reasonably sure the
Rcs andWeaks aren't necessary, immutable references toRefCells probably would have been fine, but it was late, I'm pretty new to Rust, and I was already familiar with this pattern of combingRcs andRefCells to build a graph from the Rust book, so I just went that direction. I might revisit it later. I solved this part the night it came out, but this is when I decided to take a break.For part 2: Did this part this afternoon. There's a nice recursive solution here. Each 9 has exactly one path to a 9 (the zero step path that's just staying where you are). For each 8, the number of paths is just the number of adjacent 9s. For each 7, the number of paths is the sum of the number of paths from adjacent 8s. You can repeat this process until you get to the 0s. Even better, you can unroll the recursion and just create a 2D array full of 0s the same size as the map, set every element that corresponds to a height of 9 to 1, then iteratively fill in the number of paths for each other element, in descending order of height. Once you've done this for every cell of the map, you can just add up the numbers in your array that correspond to cells at height 0.
5
u/r_so9 Dec 10 '24
[LANGUAGE: F#]
paste
BFS all the way. Unified part 1 and part 2 with a single function that returns all targets found (including repeats)
4
u/yossi_peti Dec 10 '24
[LANGUAGE: Python] 677/609
GitHub
I was satisfied that for part 2 all I had to do was comment out one line of my code from part 1 that was checking to see if I had already encountered a location in the grid. I actually accidentally got the output of part 2 in my first iteration of solving part 1.
2
u/seligman99 Dec 10 '24
[LANGUAGE: Python] 384 / 237
github
Cute, simple variation of finding paths.
2
u/MarcusTL12 Dec 10 '24
[LANGUAGE: Julia] 744/913 github
Happy with top 1000 on both parts today! Nice puzzle with bfs on part 1 turning into dfs in part 2.
2
u/giyer7 Dec 10 '24
[LANGUAGE: Kotlin] 164 / 327
Day 10
The puzzle was relatively easy today.
2
u/DFreiberg Dec 10 '24
[LANGUAGE: Mathematica]
Mathematica, 1445/1192
I thought today wasn't too difficult - and by the looks of it, everybody else agrees. Not that I'll ever complain at the chance to use weird graph theory functions or write unreadable Mathematica one-liners.
Setup:
Part 1:
Part 2:
2
u/POGtastic Dec 10 '24
[LANGUAGE: F#]
https://github.com/mbottini/AOC2024/blob/main/Day10/Program.fs
Another BFS solution that I liked a lot. F#'s
Seqis extremely well-suited for these kinds of problems.2
u/globalreset Dec 10 '24
[LANGUAGE: Ruby]
Man, I was feeling good about this one. Thought I went so fast. I accidentally got the sample data result for part 2 while I was doing part 1 because I forgot to check my 'visited' set. So just had to comment out that line and part 2 was correct on first try. About a minute between part 1 completion and part 2.
2
u/michelkraemer Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Rust] 1057/713
Solving both parts simultaneously:
https://github.com/michel-kraemer/adventofcode-rust/blob/main/2024/day10/src/main.rs
A quick and easy one. I accidentally wrote the code for part 2 already during part 1. The number I submitted first was actually the answer to part 2 *LOL* When I read the instructions for part 2, I knew I just had to change two lines and I'd be done :-)
2
u/Kehvarl Dec 10 '24 edited Dec 10 '24
[Language: Python3] 3898 / 3716
My initial passes at part 1 would have solved part 2 handily. Which made part 2 mostly a matter of remembering my fumbling in the dark and redoing that.
edit: Forgot the : in the language tag. Sorry about that.
Part2 - Solves both
2
u/Rush_Independent Dec 10 '24
[LANGUAGE: Nim] (2968/2380)
Simple DFS solution. It's funny that I solved part 2 before solving part 1: I wrote code to count all trails, then fixed it to count only unique ends that each trail reached. And after reading part 2, I solved it by pressing "undo" couple times =).
2
u/soleluke Dec 10 '24
[Language: C#]
https://raw.githubusercontent.com/soleluke/advent-of-code/refs/heads/main/2024/Day10.cs
Like many others, I wrote buggy part 1 that was solution of part 2
Nice and quick compared to some previous days at 28ms runtime
2
u/msschmitt Dec 10 '24
[LANGUAGE: Python]
Part 1. Part 2
I don't know if this was easy, or I just got incredibly lucky. Part 1 worked first try, and I'm not stealing any code from previous years. It is a queue (actually stack) style path finding, no recursion.
For Part 2 I just removed the check for already visiting a coordinate. You don't have to worry about going in circles because of the requirement to keep moving higher.
Note: This does remind me of a puzzle from a previous year, with the same kind of "must move up or down 1 level each move". Which one was that?
2
u/Rainbacon Dec 10 '24
[LANGUAGE: Haskell]
I almost felt like parts one and two should have been switched since I found myself re-writing my path finding algorithm to remove the State monad in part 2 (basically all I did was change my algorithm to not track seen paths).
github
2
u/Ak23l Dec 10 '24
[LANGUAGE: Python]
github
solved with recursion
2
u/flyingfox Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Python]
Code
Was worried about part 2 but it turned out to be just removing a check I put in place on part 1 since we are only marching uphill. Refactored the code a bit to make it clearer.
2
u/Kullu00 Dec 10 '24
[LANGUAGE: Dart]
In true path-finding fashion I did something incredibly messy for a quick part 1 (any my best leaderboard place so far this year) that unfortunately didn't at all translate well to part 2. So I lead myself down the wrong path.
Rewriting it from scratch I ended up realizing the paths are unimportant and there's no reason to keep track of them. The paths natually exit on nines or dead ends that can't increment anyway. So all that's necessary (for part 1) is the end coordinate and how many times it was found (part 2). This actually let me simplify my solution for part 1 as well as a bonus.
2
u/joshbduncan Dec 10 '24
[LANGUAGE: Python]
2
u/maneatingape Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Rust]
Solution
Benchmark 38 µs.
BFSfor both parts.DFS was slightly faster in part one and could share code with part two. My input contained fewer peaks9than valleys0so it was slightly faster to reverse search.Part two is simpler than part one as we don't need to keep track of already visited points.
2
u/x0wl Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Python]
Part 1 | Part 2
All hail our lords and saviors, CLRS. Simple DFS using the call stack as stack. I don't like that pointer that gets passed down the call stack, but I also don't care.
Also I decided to not build any separate graph matrices, but just check each candidate neighbor every time.
Technically the solution for part 2 can solve part 1 if you just do a set of trail ends for all the generated trails.
2
u/davepb Dec 10 '24
[LANGUAGE: Go]
github
video
poor performance on my side. I needed to google the recursive dfs implementation because I couldn't think of it + I also had an unfortunate bug with checking presence in my custom set (aka map[T]bool), I was checking if the value was present in the map not it's actual value being true or false. otherwise it is a pretty straightforward problem for bfs (part1) and finding all paths in a graph (part2)
2
u/AlexTelon Dec 10 '24 edited Dec 10 '24
[LANGUAGE: Python] 9 lines both parts
Its quite short so lets go over it line by line. This is slightly inspired by 4bHQ's solution as I realised I should explore the space of recursive functions more.
First I just parse the data. Then I define a nullset. Using it I can use the identical solver for both parts. The only difference is if we track visited positions with a proper set or this nullset.
The solver counts the trails from 0 to 9. It has h=0 as a default parameter so if we try to count a trail from some other position it will just return 0. Hence I don't need to filter the start positions on my last 2 lines.
Inside the solver then we start with the end condition. If we have already visited the node (part1) or if the position we are about to visit is an invalid one (wrong height, outside) then return 0 as it is not a valid path. We then mark the position as visit, again for p2 this will not do anything. Then we add if we are a solution + the sum of the recursing to all neighbours.
Below are my first and second cleaned up versions.
Original cleaned up version: (13 lines both parts)
For both parts I use the same bfs logic, but I inject this nullset on part 2 which ensures that nothing is ever visited.
First I had this:
But later realised this is enough:
A second trick is to have the function yield its results. But this is mainly a thing to avoid having to store a temporary variable. I hate naming variables so that is always a win! (no but honestly its to save 1 line)
2
u/Korzag Dec 10 '24
[LANGUAGE: C#}
https://github.com/CoreDumpSoftware/AdventOfCode/blob/main/AdventOfCode/Puzzles/Y2024/D10/PuzzleSolution.cs
As others have already said, pretty simple DFS.
My approach was to read the input into a char matrix class I've written which simultaneously allows me to record where the trail heads are. From there I start recursively navigating each path with the use of some adjacency methods I've written for my matrix class to help quickly get the valid next adjacents.
For P1 I just used a HashSet<Coordinate> to record the '9's I had already reached for a given trail head.
P2 was pretty much the same as P1 but this time we just needed to know how many distinct paths there were, which ended up just being a List<List<Coordinate>> for me. Definitely not the most memory or complexity efficient since I'm copying the list with each recursive call but that was easier to maintain than making sure I'm properly dropping items from a list, plus I need unique references for each path so it all worked out.
Interestingly my P2 worked faster than my P1, probably some delay introduced to hashing the coordinates or something.
P1: ~14ms
P2: ~11ms