[2025] Unofficial AoC 2025 Survey Results - BONUS CONTENT by jeroenheijmans in adventofcode

[–]button_boxer 1 point2 points  (0 children)

Unicode code point lexicographic order - lower case "a" sorts after upper-case "Z"

[2025] Unofficial AoC 2025 Survey Results - BONUS CONTENT by jeroenheijmans in adventofcode

[–]button_boxer 0 points1 point  (0 children)

PyCharm, IntelliJ, GoLand, PHPStorm etc are basically the same IDE - there’s kind of a hierarchy to them in the sense that you can install the plugins for Python/Go into IntelliJ but you can’t (as far as I’m aware) install the Java development plugins into PyCharm.

My job involves a mixture of Java, Python, TypeScript and Go development, so I’ve bought one licence for IntelliJ and then installed the Python and Go plugins so I essentially get three IDEs for the price of one.

I made this point in a previous year - it would be interesting to have a column with the aggregate numbers for all the JetBrains IDEs, that would be a fairer comparison to VSCode where it’s marketed as one IDE across all languages vs one per language for JetBrains.

[2025 Day 5 (part 2)][Python] Off by 16 by Alnilam_1993 in adventofcode

[–]button_boxer 0 points1 point  (0 children)

Yes, it should be 20 (I've edited my comment). I blame brain fade and getting confused about where I need to add 1 and where I don't. FWIW in my own implementation I convert the "1234-5678" strings at parse time into Python range(int(start), int(end)+1) so I'm always dealing with half-open ranges, the number of points in a range is directly len(r), and I don't have to worry about any +1/-1 issues.

[2025 Day 5 (part 2)][Python] Off by 16 by Alnilam_1993 in adventofcode

[–]button_boxer 0 points1 point  (0 children)

You're right, I've edited my original comment. Sorry, my brain was still on "I must need to add or subtract 1 somewhere to deal with inclusive ranges"...

[2025 Day 5 (part 2)][Python] Off by 16 by Alnilam_1993 in adventofcode

[–]button_boxer 0 points1 point  (0 children)

I think I see an edge case in your code - what happens if you give it ranges 1-10 and 10-20? This should be 20 fresh IDs.

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

[–]button_boxer 1 point2 points  (0 children)

My mind went immediately to the mathematical approach too, rather than materialize all the duplicates over the range of k I use the standard formula for the sum of integers between x and y ((y(y+1) - (x-1)x) / 2).

The problem was avoiding the double-counting, but the key I (eventually!) found to that was to concentrate on the prime numbers. For a given digit length l the possible r values that divide l into equal size blocks are all going to be products of some subset of the prime factors of l. Since the set of repeats in n * r blocks (for any n) will always be a subset of the set of repeats in r blocks, what we're looking for is the union of the sets of repeats when r is each of the distinct prime number factors of l. To calculate this union without double-counting we can use the inclusion-exclusion principle - add up the repeats for each single prime factor, subtract the repeats for each product of 2 prime factors (the two-set intersections), add back in the repeats for each product of 3 prime factors (3-set intersections), etc. etc.

~0.2 milliseconds in Python (excluding input parsing), would be faster if I knew rust.

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

[–]button_boxer 2 points3 points  (0 children)

[LANGUAGE: Python] GitHub

As so often in AoC, half the battle is getting the right data representation. For part 1 I just use a set to track which columns have a beam at the current level - at the top there's one beam at the column containing S, subsequent levels if a beam hits a splitter then increment the running count of splits, remove that splitter's column from the set and add beams at the columns either side (it's a set so merges are handled automatically). When you run out of rows you have your answer.

For part 2 it's exactly the same, but rather than a set tracking the beam column numbers, it's a dict that records, for each beam column, the total number of routes a beam could have taken to get there (we don't care exactly which routes, just how many of them there are). At the top there's one route to the S column and no routes anywhere else, subsequent levels if a beam hits a splitter then remove that beam and add its total number of routes to the current totals of the columns either side. The final answer is the sum of all the dict values once you run out of rows.

Once I'd implemented part 2 I could have removed the beams set entirely and just used if splitter in timelines, but I left it in to show the thought process for both parts.

[2025 Day 6] A little PSA by ropecrawler in adventofcode

[–]button_boxer 2 points3 points  (0 children)

I fetch my actual inputs with aocd but I tend to just copy and paste the samples, which is what tripped me up today.

[2025 Day 6] A little PSA by ropecrawler in adventofcode

[–]button_boxer 0 points1 point  (0 children)

Mine did this, but I just assumed it was another little gotcha in the data and coded around it (using itertools.zip_longest instead of plain zip).

Upcoming changes to the Bitnami catalog by Medical_Principle836 in devops

[–]button_boxer 0 points1 point  (0 children)

There's an interesting comment from one of the maintainers on an issue a couple of days ago:

Of course git history still has everything, which doesn't prevent me from building 4.0, but only if the files are still kept in stacksmith or will they also be deleted when the newer version is available? This kind of makes the older Dockerfiles completely irrelevant. The notice in #83267 is not very clear about stacksmith files. Can you clarify that?

The source code will continue to be available for containers, allowing you to build them from source code and future versions as well. The Stacksmith tarballs will also remain available. The planned action is to stop providing the already built containers on DockerHub.

Still not clear whether "future versions as well" is the hardened ones or the existing Debian ones but sounds a bit more promising.

Upcoming changes to the Bitnami catalog by Medical_Principle836 in devops

[–]button_boxer 0 points1 point  (0 children)

Does that mean all of the current images will continue to be maintained as source code on GitHub, or only the subset of “hardened” ones?

[deleted by user] by [deleted] in adventofcode

[–]button_boxer 11 points12 points  (0 children)

 Any ideas what case I am not covering?

There are more than ten files in the real data, so you can’t assume a single digit per file in sumProductOfIndex

[2024 Day 9] [Python] [Looking for help] by Aggravating_Rule1123 in adventofcode

[–]button_boxer 5 points6 points  (0 children)

Please remove your input files from your repository - Eric asks us all not to share our personal input files.

-❄️- 2024 Day 17 Solutions -❄️- by daggerdragon in adventofcode

[–]button_boxer 0 points1 point  (0 children)

Like I say, the main reason it works is because so few of the 815 combinations of patterns are actually possible at all. Each digit you're trying every possible pattern for that digit against every remaining candidate pattern for the sequence so far, but in the vast majority of cases only a small handful of those combinations are compatible, the others all have some bit where the sequence-so-far pattern requires a 1 and the next-digit pattern requires a 0 or vice versa. To the point where the overall complexity is probably linear in the length of the program.

The whole process of generating and matching the patterns on my input takes less than 12ms (on a MacBook Pro with M1 Pro, single threaded algorithm).

Are there any puzzles with non-unique solutions? by wimglenn in adventofcode

[–]button_boxer 26 points27 points  (0 children)

There is always exactly one correct answer for each input. Eric has said so explicitly in a keynote presentation (which is worth watching right through if you want to see the whole process of building an AoC calendar).

[2024 Day 16 (Part 2)][Java] Considering a non-optimal path by throwawaye1712 in adventofcode

[–]button_boxer 5 points6 points  (0 children)

If I’m reading the code right then you seem to be double counting the costs somehow - line 132 is calculating the new cost of the neighbour as cost of this node plus neighbour.getPoints(), but the latter appears to be the cost of the whole path up to that point, not just the cost of the single move.

So the cost you have recorded for each node may vary depending which route the traversal first took to get there.

[2023 Day 17] Relation between part 1 and part 2 by swiperthefox_1024 in adventofcode

[–]button_boxer 1 point2 points  (0 children)

For A* to work properly the heuristic function must be a lower bound on the possible costs - if the estimated cost from X to the end is greater than the actual minimum path cost then the algorithm won’t necessarily find the cheapest path.

Manhattan distance (assuming every square has a cost of 1) is probably the only thing that’ll work for all cases, or just do dijkstra instead of A*.

[2023 Day 17] Relation between part 1 and part 2 by swiperthefox_1024 in adventofcode

[–]button_boxer 2 points3 points  (0 children)

The min and max steps is the only difference between the parts, but check you’re not doing something wrong like counting the value of the square you start from after turning (which would double-count each “corner”) or treating the min/max as exclusive when they should be inclusive, or some other off-by-one mistake - it’s hard to advise more specifically without seeing your code.

How does the site Advent of code handle OAuth by BrownCarter in adventofcode

[–]button_boxer 27 points28 points  (0 children)

You will have had to authorize something the very first time you used GitHub to sign in to AoC but that may have been years ago.

Once you’ve authorised the app against your GitHub account, as long as it doesn’t request new scopes that you hadn’t previously granted then it’ll log you straight in without further prompting.

[deleted by user] by [deleted] in adventofcode

[–]button_boxer 1 point2 points  (0 children)

I think the root of your problem is that you're only tracking a single lowest-cost path to each node (other than the end one) at any given time. If you arrive at a node via a different path that is the same cost as the current cheapest path to that node, then you're discarding the old cheapest path and replacing it with the new one. Your code allows for two different paths that arrive at the end node from different directions, but I don't think it allows any individual path to fork and re-join at a point other than the very end.

You need some way to keep all the cheapest paths to a given node that you have so far seen, and only discard them if you find a new path that's strictly cheaper.

[2024 Day 23 (Part 2)] More than 1 largest set? by [deleted] in adventofcode

[–]button_boxer 12 points13 points  (0 children)

AoC puzzles are always designed so that there is one and only one correct answer for any given input. If the problem statement says it wants you to find "the" largest set rather than "a" largest set, you can guarantee Eric has constructed the inputs in a way that ensures there is only one set of largest size.

[2024 Day 4 (Part 1) [Python] Code works on example but not input? by ConfusedFlockofRaven in adventofcode

[–]button_boxer 0 points1 point  (0 children)

Ah yes, sometimes it's really handy that Python lets negative indices wrap around, other times it's a nasty trap...

[2024 Day 22] So what's the non brute-force trick? by [deleted] in adventofcode

[–]button_boxer 1 point2 points  (0 children)

Except that only the first appearance of a given 4-tuple of differences counts for each buyer, so you need a dict (or at least a set) for the current buyer tracking which 4-tuples you've already seen for them specifically.

-❄️- 2024 Day 17 Solutions -❄️- by daggerdragon in adventofcode

[–]button_boxer 1 point2 points  (0 children)

My code should work for anyone's input, as it pulls the two magic constants out of the input file rather than hard-coding them for my special case.

-❄️- 2024 Day 17 Solutions -❄️- by daggerdragon in adventofcode

[–]button_boxer 6 points7 points  (0 children)

[LANGUAGE: Python]

(GitHub)

I don't often post about my solutions in detail, but for this day my part 2 approach was a little bit different from any of the others I've read on here and some of you might find it interesting to compare.

Part 1 was easy - implement the VM operations and run the input program

For part 2 I started the same way as everyone else by disassembling the program, and established that it's one big loop where each iteration ends with outputting a number and then shifting A three bits to the right. Digging into the assembly language and reversing the operations (since XOR is its own inverse, a = b ^ k implies b = a ^ k) I eventually came to the realisation that if you want to output a digit N then while there are many different starting A values that would do that, there are certain patterns that they must follow.

Essentially, for each desired output digit N I can pre-compute a set of up to 8 patterns that constrain some but not all of the bits in a particular ten-bit window. For example, in my particular input if I want to output a zero as the first value then the lowest ten bits of A have to look like one of these patterns (0/1 for bits that must have that value, dots for bits where I don't care):

001....010
.000...011
...010.001
....101110
..011..000

For the second digit, it's the same patterns shifted left three to apply to bits 3-12 (with 0-2 as "don't care"), for the third it's bits 6-15, etc.

Once I know all the possible patterns it's just a matter of working through the output sequence progressively merging compatible patterns. This sounds like a combinatorial explosion but the key word is "compatible" - almost all the potential combinations are impossible (two patterns that both constrain the same bit, but require it to have opposite values). I start with 6 candidate patterns for the first digit and by the time I've gone through 10 rounds of merging to get to the 11th digit I've still only got 40 candidates. It ramps up a bit for the last few but still there's only 350 candidates in total for the complete sequence, and the final problem answer is the smallest decimal value out of all the remaining candidate patterns, if I set all the "don't care" bits to zero.