This repositry serves as my collection of answers written in typescript.
The project uses Bun as runtime.
The solvings are placed in the /days
folder where each day has it's own folder. Each day has it's own test, and utils file to abstract logic.
All of the examples for each day has written test case in the respective index.test.ts
file for the day.
When the day is solved, a test for the correct result is added.
To run the tests:
$ bun test
Below are my notes on how it went for the individual days. It's honest and initial thoughts.
Day | Name | Stars | Execution time | Notes |
---|---|---|---|---|
01 | Trebuchet | ⭐⭐ | 2.36ms | Part two was difficult to solve, due to the fact, that the first number should be found left-to-right but the last number right-to-left. E.g.eightwoeightwo is equal to 82 . I started by replacing by it's occurance index, wich gave me 8wo8wo , but it should have been 8weeigh2 . So on the last number, the last occurence wins vs. the first occurance where the first character. The way i ended up solving it, was to pre-/sufix the number with the word to make sure not to break a words. that gave me: eight8eightow2twoeight8eightwo2two . Then a simple regex /[^\d]/ig to only get the numbers worked like a charm 8282 => 82 . |
02 | Cube Conundrum | ⭐⭐ | 4.08ms | I found these parts to fairly easy compared to day 1. I quickly created a parser to make the game data into an object format which helped me a lot in the 2nd part. |
03 | Gear Ratios | ⭐⭐ | 9.43ms | What a mess! I really struggled with this. I spent hours on what I now think was overcomplicating it. I struggled mostly with the second part. For some reason, I just couldn't wrap my head around it. Seeing on the leaderboard that people had solved it in 15 minutes was definitely demotivating 😅. What I ended up struggling the most with was numbers on the same line like422.729 . Since the adjacency could be diagonal, it ended up becoming one large number instead of two separate ones. I solved it a bit messily. I think I would have used a regular expression to test if it was a line with two numbers if I were to refactor it. |
04 | Scratchcards | ⭐⭐ | 459.31ms | Compared to yesterday this was fairly easy. I did struggle a bit with part two, and ended up brute-forcing the result. Wich is evident in the execution time (slow 🐌). I Used a Class this time to encaptulate the logic with the entity. That helped me a lot in yet another looping-hell. (Edit;) I add some caching of the pointable numbers and copies to speed up the task. Furthermore i made a index map of the original cards to be able to lookup direcly in the map for the card index instead of the find method. This changede the execution speed from around ~7700ms to ~475ms (~94% speed improvement). See the original implementation45cf53f. |
05 | If You Give A Seed A Fertilizer | ⭐⭐ | 1.64ms | Wauw, i quickly got part one but really struggeled with part two. As previously, my code wasn't made for handling that large ranges and list of inputs. I ended up rewriting the whole algorithm into a function that could handle both parts using the ranges approach. Felt this could have been done more elegantly - but maybe not more efficient. |
06 | Wait For It | ⭐⭐ | 0.08ms | I fairly quickly got both parts of today. As soon as i figured out the alogrithm, is was easy to calculate the answers. Originally the second part was slow to calculate (~210ms). But by removing the use of Array's and rely more on just plain types i got it down to ~54ms (~74% speed improvement) (See the original implementation124ec44). Update: After looking at the subreddit, I found that most had used brute force, just as I did. But some had used quadratic math to find the result. I then ported it to JS to see the potential speed improvements. I can now run the second part in 0.04 ms, that is a whopping 99.98% improvement from the original implementation ⚡️. The math (at least to me) is complicated. I can't imagine the struggle if the input had a lot of rows to process (people actually found it too easy compared with yesterday). |
07 | Camel Cards | ⭐⭐ | 8.52ms | Sorting, sorting, and more sorting. Today's task was about sorting hands in the right order. I figured out way too late that the comparison was based on the original card order and not the sorted order of the individual cards. I spent a lot of trial and error on sorting the cards high to low and also winning --> high card (e.g., Q2323 --> 3322Q because the two pairs are the winning cards). But that was not how it was intended 🙈 Basically, after I removed the sorting algorithm, it all worked as expected. But it took me a while to figure out since the examples worked with the sorted winning card order. In the second part, it was just to shift the ranking of the cards and modify the classification algorithm to take the jokes into consideration. Again, the sorting order was making today a headache. Update: I've managede to clean up the code significantly, and was able to use the same algorith for both parts. The speed improved a tiny bit from 11.21ms to 8.52 (~24% improvement). See the original implementation here 6fdda01. |
08 | Haunted Wasteland | ⭐⭐ | 19.05ms | Can you find the right path? Todays task, to me, had a huge difficulty gap between part 1 and 2. The first part was fairly easy, and i was pretty strigt forward to handle with a while loop. I triede the brute-force attempt (once again 🙈) on the second part. But i was just running forever. I had to lookup how other people had solved it (am i the only one that gets imposter syndrome looking at those skilled people?). I found a solution using the Least Common Multiple algorithm. I don't think i would have ever found that solution by myself. I was on the right path though in the second part leading up preperations to the actual calculation. But that was where i stranded (lost and alone). I really only deserve a silver star for today. But i implemented the LCM approach in typesript to show how to solve it. |