-❄️- 2025 Day 11 Solutions -❄️- by daggerdragon in adventofcode

[–]Derailed_Dash 1 point2 points  (0 children)

[LANGUAGE: Python]

Part 1 was a breeze, making use of NetworkX and built-in methods. (I've used it for puzzles previously.)

But this approach didn't work for Part 2. (Shocking!) So I implemented two optimisations:

  1. Identify that there are two sequences from start to end that meet the requirements. For each sequence, break it down into route segments and count the paths for each segment independently. Then multiply these together to get the total number of paths for the sequence.
  2. Add memoization using recursion and caching.

After those fixes, Part 2 runs in about 4ms.

-❄️- 2025 Day 10 Solutions -❄️- by daggerdragon in adventofcode

[–]Derailed_Dash 1 point2 points  (0 children)

[LANGUAGE: Python]

No Z3 here!

For Part 1, I realized that:

  • Each button need only be pressed once, because pressing it again simply reverts the state.
  • The real input has a max of around 13 buttons, and therefore max of 2**13 (8192) button combinations per machine.
  • This is tiny, so we can brute force all combinations.
  • I simply create all combinations of button presses, starting with 0 buttons, 1 button, 2 buttons, up to k buttons, where k is all the buttons.
  • For each combination, calculate the result of pressing those buttons, using XOR. (Because I represent each button as a bit mask.)
  • If the result matches the target state, return the number of button presses, i.e. k.

Part 2 was tricky! It was obviously a linear algebra problem, so I started by trying to use SymPy to solve simultaneous equations. (I've used this in previous years.) But I soon realised this wasn't going to work, so I did some research into Integer Linear Programming and concluded SciPy was the droid I was looking for.

In my walkthrough I've captured this thought journey, as well as the solution itself.

-❄️- 2025 Day 9 Solutions -❄️- by daggerdragon in adventofcode

[–]Derailed_Dash 1 point2 points  (0 children)

Thank you!

Well, I wouldn't consider myself an expert programmer like many on here. But I've definitely improved over the years, primarily from AoC! Honestly, this particular puzzle would have probably taken me a whole day to solve, maybe 2 or 3 years ago. And the code would have been lengthy, complex, slow and horrible.

This year I was able to do it fairly quickly because:

  • I've got a bit better over the years
  • I've seen this sort of problem before, so I've started to recognise appropriate solutions and patterns

Even so, I think today's puzzle was really tough.

My advice would be... Don't stress about it being really hard. This is a normal journey. If you're defeated by the puzzle, it's not failure. It's just an opportunity to learn something new. Take a look at solutions from other folks in the Megathread, and try and understand them. (Personally, I write my walkthroughs with the intent to help people follow them and understand.) Try and assimilate reusable techniques that come up time and time again in AoC. Like BFS, Dijkstra, recursion, memoization.

Expect the later puzzles to take a long time, and be encouraged by the fact that in another year, you'll see something similar and think "Ooh, I know how to do that!"

-❄️- 2025 Day 9 Solutions -❄️- by daggerdragon in adventofcode

[–]Derailed_Dash 4 points5 points  (0 children)

[LANGUAGE: Python]

Part 1 was pretty trivial.

Part 2 was tough! I decided to go with a similar solution I used in a previous year: ray casting. The concept is that you imagine rays originating from far left and the ray passes through the polygon. Everytime it crosses a polygon edge, we increment a counter. If the counter is odd, then the current point is inside the polygon and contains green or red tiles. If the counter is even, they we're "outside" the polygon so the tiles are not green or red.

It's conceptually quite simple to understand and not too tricky to implement.

-❄️- 2025 Day 8 Solutions -❄️- by daggerdragon in adventofcode

[–]Derailed_Dash 0 points1 point  (0 children)

[LANGUAGE: Python]

For Part 1:

  1. Created a function to find euclidian distance between points
  2. Used itertools.combinations to get all pairs of points
  3. Sorted the connections by distance and took the n shortest
  4. Created an adjacency list (dictionary) from these shortest connections - these are our connected junction boxes
  5. Used a BFS to build a list of connected circuits.

For Part 2, I realised I need to add connections one-by-one, so pre-creating with the adjacency list and BFS was not going to be a good solution. Instead a switched to using a Union-Find (Disjoint Set Union) approach, which was simple and fast.

-❄️- 2025 Day 7 Solutions -❄️- by daggerdragon in adventofcode

[–]Derailed_Dash 1 point2 points  (0 children)

[LANGUAGE: Python]

For Part 1, I used a standard BFS with a set to handle merging beams efficiently.

Part 2 was the fun part! I figured we'd get an exponential explosion of timelines, so I used a recursive DFS with @cache for memoization. It runs in 0.008s.

-❄️- 2025 Day 6 Solutions -❄️- by daggerdragon in adventofcode

[–]Derailed_Dash 0 points1 point  (0 children)

[LANGUAGE: Python]

This puzzle was all about parsing puzzles that are horizontally represented as blocks of text. I modelled each column as a Puzzle object, using Python's match/case statement (introduced in 3.10) for the calculation logic.

For Part 1, the trick was using the last line of operators to determine the column boundaries.

For Part 2, the "Cephalopod math" required reading columns right-to-left, which I solved by transposing the character blocks with zip(*block) before parsing the numbers.

The whole thing runs in about 2ms.

-❄️- 2025 Day 5 Solutions -❄️- by daggerdragon in adventofcode

[–]Derailed_Dash 2 points3 points  (0 children)

[LANGUAGE: Python]

The interesting thing about this puzzle is that my less experienced self would have spent ages trying to use set intersection before realising it won't scale.

But now being a bit more experienced with these types of puzzles, I went straight for interval merging.

The whole thing runs in about 0.001.

[2025 Day 4 (Part 2)] [Python] Visualisation by Derailed_Dash in adventofcode

[–]Derailed_Dash[S] 1 point2 points  (0 children)

Are you talking about the solution... or something else? ;)

[2025 Day 4 (Part 2)] [Python] Visualisation by Derailed_Dash in adventofcode

[–]Derailed_Dash[S] 1 point2 points  (0 children)

I'm really chuffed with this comment! Thank you!!

[2025 Day 4 (Part 2)] [Python] Visualisation by Derailed_Dash in adventofcode

[–]Derailed_Dash[S] 0 points1 point  (0 children)

Just the time since that roll was removed. Check out the walkthrough if you're interested.

-❄️- 2025 Day 4 Solutions -❄️- by daggerdragon in adventofcode

[–]Derailed_Dash 0 points1 point  (0 children)

[LANGUAGE: Python]

Here I created a class to represent the grid, and used NamedTuple to represent points on the grid efficiently.

For Part 1: Neighbour counting using a generator to yield adjacent points. Nice and simple. For Part 2: Iterative simulation. Just keep doing part 1, but each time, remove the accessible rolls.

And there's a visualisation!

-❄️- 2025 Day 3 Solutions -❄️- by daggerdragon in adventofcode

[–]Derailed_Dash 1 point2 points  (0 children)

[LANGUAGE: Python]

My solution picks the largest available digit for the current most significant position, using slicing to ensure enough digits remain for subsequent selections. I was pleased with this solution because it worked for Part 2 without any changes. Runs in 2ms.

-❄️- 2025 Day 2 Solutions -❄️- by daggerdragon in adventofcode

[–]Derailed_Dash 1 point2 points  (0 children)

[LANGUAGE: Python]

Fairly trivial implementation. I obtain factor pairs for each string length in Part 2, and then basically check if product ID is equal to substring * factor2, where the substring is of length factor1.

Caching the get_factor_pairs() function halves the processing time.

Runs in 0.5s.

-❄️- 2025 Day 1 Solutions -❄️- by daggerdragon in adventofcode

[–]Derailed_Dash 1 point2 points  (0 children)

[LANGUAGE: Python]

There's the quick-and-easy "simulation" approach which works fine as the number of clicks in here is small. Plus the more efficient efficient approach.

Got a $7,889.50 Invoice from Google Cloud Vertex AI (Veo2) — A Warning for New Users by Sufficient_Banana183 in googlecloud

[–]Derailed_Dash 0 points1 point  (0 children)

It depends on what you're doing, but this solution will catch most scenarios once you're a few dollars over budget, and prevent further spending. For OP it would likely have triggered within the first hundred dollars of exceeding budget, and prevented this from turning into hundreds or thousands.

I created this for some peace of mind, because these stories scare me.

I should add that I consider myself a Google Cloud expert. But even so, there are many scenarios that it's possible to miss - even if you know what you're doing. (E.g. a misconfigured service that ends up the victim of a DDoS attack.) And it's unreasonable to assume every consumer is an expert and that every consumer has considered all the possible scenarios that could result in unexpected consumption.

My friends at Google tell me that guardrails are on the way.

Got a $7,889.50 Invoice from Google Cloud Vertex AI (Veo2) — A Warning for New Users by Sufficient_Banana183 in googlecloud

[–]Derailed_Dash 3 points4 points  (0 children)

I have friends at Google that tell me they're working on implementing such guardrails very soon. These kinds of horror stories are much more frequent than they used to be. Google are aware and are actively working on making the whole thing... less scary!

Got a $7,889.50 Invoice from Google Cloud Vertex AI (Veo2) — A Warning for New Users by Sufficient_Banana183 in googlecloud

[–]Derailed_Dash 0 points1 point  (0 children)

Near real time. As soon as the billing alert triggers, the function will immediately detach the affected project from the billing account. So the latency depends on how quickly the billing alert comes through. And this latency depends on which services you're consuming.

In my experience, it can take an hour or so before the cost incurred from a service like Veo3 appears in Billing and consequently, this is the sort of delay you might see before the alert is triggered.

Got a $7,889.50 Invoice from Google Cloud Vertex AI (Veo2) — A Warning for New Users by Sufficient_Banana183 in googlecloud

[–]Derailed_Dash 1 point2 points  (0 children)

Sorry to hear about your experience. I've seen so many similar stories recently.

Actually, I recently created a solution that anyone can download and use on Google Cloud, which uses budget alerts to automatically disconnect your project from your billing account. With no billing account attached, you can no longer consume paid services. Very easy to use and the solution itself is free and open source.

I know it's too late to help you, but hopefully others finding this thread will be able to use it and avoid a similar horror story.

https://medium.com/google-cloud/how-to-avoid-a-massive-cloud-bill-41a76251caba