Monday, 2021-01-04

Advent of Code 2020 wrapup

This was a good year, in my opinion. It was a return to the 2015-2017 era, before the unfortunate experiment in collective puzzle-making in 2018, and the “armature” of the intcode puzzles in 2019. These were fun, and impressive, but if you missed out on doing them there was ~45% of the puzzles gone.

I managed to solve all puzzles before the end of the year, with a personal score of 48 out of 50, which is the best I’ve done since 2016.

AoC has grown hugely, even compared to last year. Here’s how many solved both parts of day 1 and day 25 (essentially solving every puzzle):

Year 2 stars day 1 2 stars day 25 Personal best ranking
for 2 stars
2015 50,358 3,521 422 (day 16)
2019 101,125 3,137 2,111 (day 23)
2020 148,468 11,285 5,040 (day 18)

Favorite puzzle was probably day 20, where we had to do some image recognition. I didn’t finish this on the day it was released but had some fun polishing it later.

Tuesday, 2020-12-01

Advent of Code 2020

Completed all puzzles on 2020-12-30

Project website: Advent of Code 2020.

Previous years: 2015, 2016, 2017, 2018. 2019.

I use Perl for all the solutions.

Most assume the input data is in a file called input.txt in the same directory as the file.

Ratings (new for 2020)

I’m giving each puzzle a subjective rating between 1 and 5. This is based on difficulty, “fiddliness” and how happy I am with my own solution.

A note on scoring

I score my problems to mark where I’ve finished a solution myself or given up and looked for hints. A score of 2 means I solved both the daily problems myself, a score of 1 means I looked up a hint for one of the problems, and a zero score means I didn’t solve any of the problems myself.

My goals for this year (in descending order of priority):

  • get 40 stars or more (75%)
  • solve all problems up until day 15 without any external input
  • solve all problems within 24 hours of release

Final score: 48/50

Link to Github repo.

Day 1 - Day 2 - Day 3 - Day 4 - Day 5 - Day 6 - Day 7 - Day 8 - Day 9 - Day 10 - Day 11 - Day 12 - Day 13 - Day 14 - Day 15 - Day 16 - Day 17 - Day 18 - Day 19 - Day 20 - Day 21 - Day 22 - Day 23 - Day 24 - Day 25

Day 1 - Report Repair

Day 1 - complete solution

Not much to say about this. I used a hash to keep track of the “rest” of the values when comparing.

Apparently this (or at least part 2) is the 3SUM problem which is considered “hard”. I accidentally implemented the standard solution in part 1 so props for that I guess.

I still believe firing up the Perl interpreter and loading the actual file takes longer than just solving part 2 with two nested loops.

Beginning programmer example: loops and hashes/dicts/maps.

Puzzle rating: 3/5

Score: 2

Day 2 - Password Philosophy

Day 2 - complete solution

Despite actually being awake and caffienated when the puzzle dropped, I still managed to mess this up. Extra annoying when it’s basically tailor-made for Perl.

Here’s a partial list

  • messed up the initial regex
  • assigned $min and $max to the same value
  • messed up the comparison range in part 1
  • off-by-one error in the indexing in part 2
  • in part 2, tried to use the sum() function from List::Utils but forgot to use parentheses around the array

Beginning programmer example: parsing input, exclusive OR.

Puzzle rating: 3/5

Score: 2

Day 3 - Toboggan Trajectory

Day 3 - complete solution Day 3 - alternative solution

Veterans of previous AoC’s will get pathfinding flashbacks from this problem’s description, but it turns out it’s a bit simpler - as can be expected for day 3.

I decided before coding to not store the map explicitely as individual coordinates, instead just storing the rows as a text string and unpacking via split when needed.

Another decision was to work with the test input first to confirm my algorithm. That way it would be easier to, for example, print out the rows in case I needed to visually debug.

Beginning programmer example: dealing with infinite repeats using mod.

Puzzle rating: 4/5

Score: 2

Day 4 - Passport Processing

Day 4 - complete solution

This is a “M4P” problem - Made for Perl.

Nothing really to say about this. Set the $/ variable to an empty string to import the records as paragraphs.

I used a dispatch table to avoid a giant if/then/else statement.

Beginning programmer example: regexps! (and handling mult-line input).

Puzzle rating: 3/5

Score: 2

Day 5 - Binary Boarding

Day 5 - complete solution

I have a massive binary blind spot, so I just knew there was going to be a CS-appropriate simple solution to this. But I just followed the instructions and got the right answer in the end anyway.

Beginning programmer example: binary.

Puzzle rating: 3/5

Score: 2

Day 6 - Custom Customs

Day 6 - complete solution

Another easy problem, and during the weekend too! <anxiety intensifies>

My first stab at part 1 contained one specific data structure, that I had to tear out for part 2. After submitting the solution I realized the first solution could work for both.

Puzzle rating: 4/5

Score: 2

Day 7 - Handy Haversacks

Day 7 - complete solution

As was expected, difficulty has ramped up a bit.

Can’t really explain what I did here … the main idea was using BFS to scan the “table”, but part 2 was basically me fiddling around with terms until the test cases passed.

Puzzle rating: 4/5

Score: 2

Day 8 - Handheld Halting

Day 8 - complete solution

This year’s register rodeo, but with a fun twist.

Part 2 was solved by brute forcing every solution, it still took only ~0.3s to find the answer.

Puzzle rating: 4/5

Score: 2

Day 9 - Encoding Error

Day 9 - complete solution

An ok puzzle. It pays to read what’s sought carefully…

Puzzle rating: 4/5

Score: 2

Day 10 - Adapter Array

Day 10 - complete solution

This was a tough one! I was too impatient to really start to optimize after making a solution that solved the two example files, so I “cheated” and looked for inspiration. Full credit in source.

As a bonus I learned about postfix dereferencing in Perl.

Puzzle rating: 4/5

Score: 1.

Day 11 - Seating System

Day 11 - complete solution Day 11 - part 1 Day 11 - part 2

Ugh, got burned by Perl’s negative indices on arrays which messed up part 2. I rewrote it using hashrefs instead.

Puzzle rating: 2/5, mostly because we’ve seen this sort of puzzle before and I don’t enjoy them that much.

Score: 2

Day 12 - Rain Risk

Day 12 - complete solution Day 12 - part 1 Day 12 - part 2

A not too taxing problem.

I don’t like having to re-write the guts of part 1 to solve part 2, however.

Update: after some perusal of the subreddit I realized it was easy enough to run both solutions in one pass, so I rewrote part 2 to handle that.

Puzzle rating: 3/5.

Score: 2

Day 13 - Shuttle Search

Day 13 - complete solution

A tough Sunday problem.

Everyone on the internet figured out that this was an implementation of the Chinese Remainder Theorem, but I followed the logic of a commenter on Reddit (credit in source) and I’m quite proud of the solution.

Puzzle rating: 4/5

Score: 2

Day 14 - Docking Data

Day 14 - complete solution Day 14 - part 1 Day 14 - part 2

A bit of a fiddly problem, which I solved by only dealing with strings and arrays. Bit manipulation is for CS weenies.

I got good help from today’s solutions megathread in the AoC subreddit.

Puzzle rating: 3/5

Score: 2

Day 15 - Rambunctious Recitation

Day 15 - part 1 Day 15 - part 2

This looked complicated at first glance but wasn’t hard to implement.

My part 1 code solves part 2, given a powerful enough computer (I had to use my Raspberry Pi 4). However it takes very long on my standard VPS, so I re-implemented a solution from /u/musifter on Reddit. Credit in source.

Puzzle rating: 3/5

Score: 2

Day 16 - Ticket Translation

Day 16 - complete solution

I realized this was basically the same as 2018D16, but I had a hard time wrapping my head around how to lay out the gathering of required info. A bit of a slog.

Puzzle rating: 3/5

Score: 2

Day 17 - Conway Cubes

Day 17 - part 1 Day 17 - part 2

What if Conway’s game of life - but in more dimensions?!

Not too hard, but not too entertaining either.

Puzzle rating: 3/5

Score: 2

Day 18 - Operator Order

Day 18 - complete solution

A CS staple. So I didn’t feel bad for googling “shunting-yard algorithm” and cribbing a solution from Rosettacode.org. Same for the RPN evaluation algorithm, but I found a much more straightforward implementation on Perlmonks. Credits in source.

I wonder how many CS grads nowadays have even seen a shunting-yard. The nerds in the MIT model railroad society had, of course, and Djikstra too.

Puzzle rating: 3/5

Score: 2

Day 19 - Monster Messages

Day 19 - part 1

For part 1, I tried using Parse::RecDescent and managed to get a kludgy solution, but without really knowing what I was doing.

Skipped part 2 for this one.

Puzzle rating: 3/5

Score: 1

Day 20 - Jurassic Jigsaw

Day 20 - complete solution

This year’s most involved problem. In the end it’s not that difficult, but there are a lot of moving parts.

I’m happy that the code I wrote first (to manipulate grids for part 1) was useful for part 2 too.

Puzzle rating: 4/5

Score: 2

Day 21 - Allergen Assessment

Day 21 - complete solution

Not my favorite puzzle this year. I had the right idea on how to go about it but had to look around for practical solutions.

Puzzle rating: 2/5, mostly because I’m cranky today.

Score: 2

Day 22 - Crab Combat

Day 22 - complete solution

I took a “free card” for part 2 today. Credit in source.

Puzzle rating: 3/5

Score: 1

Day 23 - Crab Cups

Day 23 - part 1 Day 23 - part 2

Part one saw me getting very fiddly with splice, an effort that was not appropriate for part 2…

Score: 2

Day 24 - Lobby Layout

Day 24 - complete solution

A fun little problem. I reused my hex grid logic from 2017D11 and the technique from this year’s day 17 to find the solution.

Puzzle rating: 4/5

Score: 2

Day 25 - Combo Breaker

Day 25 - complete solution

Nice and simple Christmas day puzzle.

I love the denoument of our hero’s journey. Luckily for him, I don’t have all the stars, so I guess I’ll have to stay in the resort until I can finish all the puzzles!

Puzzle rating: 3/5

Score: 2

Thursday, 2019-12-26

Advent of Code 2019 wrapup

I enjoyed this year’s edition more than last year’s.

It was a combination of being slightly easier, and having a better attitude to it coming in. In 2018, I was aiming for as good a result as I had in 2016, which was 49 stars out of 50. This left very little margin for bailing out of tough problems, and led to increased frustration when I didn’t have the time required to solve a problem within 24 hours.

I was thinking of not participating, but as time drew near, I got inspired, and even solved a couple of left-over problems from last year in preparation.

This year I gave myself more leeway for simply bailing on problems that didn’t seem fun. This turned out to be day 21. I also gave up on day 6, which was probably a mistake, and part 2 of day 22.

I also felt that this year was easier than 2018. In part, this was because of nearly half of the problems being intcode problems, where we first had to write an interpreter for a specific machine code, and then apply that interpreter to various fun follow-up questions, like playing Breakout or Adventure.

Then I had a lot of support from the dedicated IRC channel from lobste.rs. I’d like to thank regulars jjuran, wink, gthm and tumdum for encouragement and friendly competition.

I still have a number of stars to get, but unlike last year, I’m looking forward to solving those problems.

Sunday, 2019-12-01

Advent of Code 2019

This blog post is a work in progress

Project website: Advent of Code 2019.

Previous years: 2015, 2016, 2017, 2018.

I use Perl for all the solutions.

Most assume the input data is in a file called input.txt in the same directory as the file.

A note on scoring

Current score (2020-12-25): 46. I’m aiming for a final of 44+1.

I score my problems to mark where I’ve finished a solution myself or given up and looked for hints. A score of 2 means I solved both the daily problems myself, a score of 1 means I looked up a hint for one of the problems, and a zero score means I didn’t solve any of the problems myself.

My goals for this year (in descending order of priority):

  • get 38 stars or more (75%)
  • solve all problems within 24 hours of release

Link to Github repo.

TODO

  • complete day 18

Day 1 - Day 2 - Day 3 - Day 4 - Day 5 - Day 6 - Day 7 - Day 8 - Day 9 - Day 10 - Day 11 - Day 12 - Day 13 - Day 14 - Day 15 - Day 16 - Day 17 - Day 19 - Day 20 - Day 21 - Day 22 - Day 23 - Day 24 - Day 25

Day 1 - The Tyranny of the Rocket Equation

Day 1 - complete solution

A nice and simple problem to kick off this year.

Score: 2

Day 2 - 1202 Program Alarm

Day 2 - complete solution

An earlier appearance of register rodeo than expected! I think we’ll see more of this going forward.

[intcode part 1]

Score: 2

Day 3 - Crossed Wires

Day 3 - complete solution

This took longer than it had to. I messed up adding the paths, and only managed to get the correct answer to part 1 by chance. Once I plotted the example data I could correct the code, then add the logic for part 2.

I’m not entirely happy with the duplicated direction subroutines. Some people have used complex numbers to simplify this but that would require a separate Perl module to implement.

Score: 2.

Day 4 - Secure Container

Day 4 - complete solution

I blanked on this one and dreaded combinatorics. Turns out brute force is eminently doable. Credits to /u/andreyrmg in the daily solutions thread, and A_D and sim642 in the IRC channels for help in inspiration.

I still think my solution is my own though (and pretty Perlish), so full score today.

Score: 2.

Day 5 - Sunny with a Chance of Asteroids

Day 5 - complete solution

After struggling with the convoluted problem description I was pleasantly surprised to find my code ran flawlessly first try. I still have some niggling issues with the test data, and need to clear that up before the inevitable next intcode problem.

[intcode part 2]

Score: 2.

Day 6 - Universal Orbit Map

Day 6 - complete solution

I bailed on this one and sought inspiration in the daily solutions subreddit. Credit in source!

Score: 0.

Day 7 - Amplification Circuit

Day 7 - part 1 Day 7 - part 2

A tough, but fun one. There were a lot of subtleties in the second part, and I got some pointers from the subreddit.

I got the chance to clean up my intcode implementation, and learned a new facet of Perl.

[intcode part 3]

Score: 2.

Day 8 - Space Image Format

Day 8 - complete solution

Defying expectations (and maybe fears), this Sunday problem was not that complicated.

Of course, it helps if you confirm that what you think is input actually is the same as the problem input. Not that I’d have anything other than theoretical knowledge of this situation…

Score: 2.

Day 9 - intcode test suite

Day 9 - complete solution Day 9 - complete solution

So the Intcode computer is done, and we’ve amassed a number of test cases to ensure it works. I’m kinda sorta happy with my code. It’s not the most elegantly put together but it works fine.

[intcode part 4]

Score: 2.

Day 10 - Monitoring Station

Day 10 - complete solution

This was a fun one, even though I got sidetracked by my incorrect assumptions and got lost in a hallway of indices, all alike.

Part 2 was found by inspecting the output, but hey, a star is a star.

Score: 2.

Day 11 - Space Police

Day 11 - complete solution

Ah, the return of Langton’s ant. Always nice to see an old friend.

Nothing too complex here, although I’m quite proud of the line noise for the dispatch table for movement:

my %directions = (
    '^'=>sub{!$_[0]?['<', 0,-1 ]:['>', 0, 1 ]},
    '<'=>sub{!$_[0]?['v', 1, 0 ]:['^',-1, 0 ]},
    'v'=>sub{!$_[0]?['>', 0, 1 ]:['<', 0,-1 ]},
    '>'=>sub{!$_[0]?['^',-1, 0 ]:['v', 1, 0 ]},
);

[intcode part 5]

Score: 2.

Day 12 - The N-Body Problem

Day 12 - complete solution

A fun little problem.

Score: 2.

Day 13 - Care Package

Day 13 - complete solution

I am in awe of what the creator of Advent of Code has wrought in the form of intcode.

[intcode part 6]

Score: 2.

Day 14 - Space Stoichiometry

Day 14 - complete solution

A hard problem that was satisfying to solve.

Score: 2.

Day 15 - Oxygen System

Day 15 - complete solution

Not my proudest moment. I’m happy my intcode implementation works well enough for this kind of application now, but my utter inability to code a BFS routine is humiliating. In the end I had to use a modified Djikstra’s that I cribbed for last year’s day 22.

[intcode part 7]

Score: 2.

Day 16 - Flawed Frequency Transmission

Day 16 - part 1 Day 16 - part 2

I had a lot of trouble with part 2, mostly due to indexing errors.

Runtime is 2m16s for part 2, which is just barely acceptable.

Score: 2

Day 17 - Set and Forget

Day 17 - complete solution

This one was a slog!

I was very worried that my intcode interpreter was incorrect, but it was actually just me not being able to read the input specification correctly.

[intcode part 8]

Score: 2.

Day 19 - Tractor Beam

Day 19 - complete solution

This was supposed to be a breather…

From the beginning I realized that this problem is best expressed as x in terms of y, instead of the more usual y in term of x, and I made a mental note not to mix them up.

Of course, many hours later I realized I had done that just that.

[intcode part 9]

Score: 2.

Day 20 - Donut Maze

Day 20 - part 1

Part 1 yields easily to a modified BFS approach.

Update 2020-12-26

Part 2 is similar, only adding the “dimension” of the recursive level. There some really scruffy code to figure out the “edges” of the transition.

Score: 1.

Day 21 - Springdroid Adventure

Day 21 - complete solution

I felt zero interest in trying to puzzle this out so found some closed forms on the subreddit.

[intcode part 10]

Score: 0.

Day 22 - Slam Shuffle

Day 22 - part 1

Part one only done for now, part 2 requires way too much weird (read modular) math for me. Damnit, Cap’n, I’m continuous, not discrete!

Score: 1.

Day 23 - Category Six

Day 23 - complete solution

A remarkably straight-forward puzzle.

[intcode part 11]

Score: 2.

Day 24 - Planet of Discord

Day 24 - part 1 Day 24 - part 2

An interesting problem.

Update 2020-12-25 I revisited this after the multiple Games of Life in 2020. Instead of trying to be clever figuring out how to calculate the neighbors, I just created a giant lookup table.

This Reddit post contains all iterations of the example input and was helpful for debugging.

Score: 2

Day 25 - Cryostasis

Day 25 - complete solution

A fitting end to a good edition of Advent of Code!

Score: 2.

Tuesday, 2018-12-25

Advent of Code 2018 wrapup

This year was a tough one. I believe the abundance of week-ends this December added to the number of quite tough problems. Day 15 seems to have been a really big stumbling block for many people.

I’m still not finished at time of writing, I’m at 38 of 50 stars. The TODO list is at the main entry for this year’s contest.

Despite miserably failing in completing each challenge in the day it was released I’m still happy I have some problems remaining going forward.

Saturday, 2018-12-01

Advent of Code 2018

This blog post is a work in progress

Project website: Advent of Code 2018.

Previous years: 2015, 2016, 2017.

I use Perl for all the solutions.

Most assume the input data is in a file called input.txt in the same directory as the file.

A note on scoring

I score my problems to mark where I’ve finished a solution myself or given up and looked for hints. A score of 2 means I solved both the daily problems myself, a score of 1 means I looked up a hint for one of the problems, and a zero score means I didn’t solve any of the problems myself.

My goals for this year (in descending order of priority):

  • match or beat last year’s score of 49/50.
  • solve all problems within 24 hours of release

Link to Github repo.

TODO

This year’s todo list:

  • Not completed
    • Complete day 23 part 2
    • Complete day 20
    • Complete day 17
    • Complete day 15
  • Completed, not published
    • Publish day 21
  • Refine
    • Day 16 - solve part 2 without manual intervention.
    • Day 14 - faster part 2.
    • Day 12 - rewrite part 2 to find the answer programmatically.
    • Day 22 - rewrite part 2 to use A*.
  • General - implement blogging and listing publication using templates
    • Publish day 18
    • Day 8 - clean up and publish solution
    • Day 11 - faster solution

Day 1 - Day 2 - Day 3 - Day 4 - Day 5 - Day 6 - Day 7 - Day 8 - Day 9 - Day 10 - Day 11 - Day 12 - Day 13 - Day 14 - Day 16 - Day 18 - Day 19 - Day 22 - Day 24 - Day 25

Day 1 - Chronal Calibration

Day 1 - complete solution

Capsule summary:

Investigate the properties of summing an infinite list of integers.

A nice start to this year’s puzzles.

I had planned on getting up at 6AM to start with this but I spent the night before playing Fallout 4 so that didn’t happen.

Score: 2.

Day 2 - Inventory Management System

Day 2 - complete solution

Capsule summary:

Investigate the properties of the strings given as input.

Another O(n^2) solution, but for the small sizes involved it barely matters.

Perl’s string munging is helpful as always.

Score: 2.

Day 3 - No Matter How You Slice It

Day 3 - complete solution

Capsule summary:

Investigate the properties of overlapping areas given as input.

Nice and clean. I was worried I’d have to do some complicated lookups to single out the correct swatch in part 2, but it turns out that there was only one possible solution in my input.

Score: 2.

Day 4 - Repose Record

Day 4 - complete solution

Capsule summary:

Given a list of activities, determine properties about the times these activities occur.

Getting the correct answer without resorting to an external run through sort -n was the hardest part of this problem!

There are some nice solutions using a Schwartzian transform out there but to be honest I’d rather have something straightforward and dumb that can understood later.

TODO: better variable naming.

Score: 2.

Day 5 - Alchemical Reduction

Day 5 - complete solution

Capsule summary:

Remove elements from a list, based on rules on which neighbors an element has.

A quick and simple problem.

Score: 2.

Day 6 - Chronal Coordinates

Day 6 - complete solution

Capsule summary:

Investigate areas on a grid, expressed in Manhattan coordinates.

Keywords: Voronoi diagram

This took some careful perusal of the text and example to figure out. I had a lot of problems with my solution when I tried to merge part 1 and part 2 into one solution. Unfortunately I had overwritten the code that actually gave me the first star, and I broke it.

I felt justified to check out other solutions and finally re-wrote using those (essentially using a representation of the board to keep track of the data). The day after I took the time to re-write it again into a version closer to my original idea.

Runtime is a dismal 16s.

Score: 2.

Day 7 - The Sum of Its Parts

Day 7 - part 1 Day 7 - part 2

Capsule summary:

Find a path through a graph, given that some steps must be done to proceed.

Keywords: DAG, directed acyclic graph, topological sort

I’m really happy with solving this. I’m graph-aphasic, as in I’ve never ever grokked them in code, and was dreading finding some random Perl module that I didn’t really understand. In the end I just found the “endpoints” and processed it using a queue.

This made part 2 reasonably easy to code.

Score: 2.

Day 8 - Memory Maneuver

Day 8 - complete solution

Capsule summary:

Investigate the properties of a tree structure given in the form of a string of integers.

Keywords: tree structure, recursive

I had a lot of trouble with this, which wasn’t helped by stuff like people coming over to visit, dinner to cook and eat, and wine to drink. After these distractions were done with I could revisit the problem with fresh eyes.

Score: 2.

Day 9 - Marble Mania

Day 9 - complete solution

Capsule summary:

A game is played by placing marbles in a circle. Investigate the end state given the puzzle input.

Keywords: double-ended circular list

This was a fun problem that was marred by some irritating off-by-one errors in the results. We were blessed with a wealth of example inputs, and I could make most of them work by taking the largest or the next largest value. This gave me my second star, but it was hardly repeatable.

Double-checking my logic against other solution revealed I was thinking correctly, but had a stupid overrun where I managed to take more marbles than were actually available…

Runtime for part 2 is 30s, but you need quite a lot of memory to run it. My wimpy VPS cannot run it natively.

Score: 2.

Day 10 - The Stars Align

Day 10 - complete solution

Capsule summary:

Given a number of points, their positions and velocities, investigate whether they form a coherent message when printed.

Keywords: visualization

A nice palate-cleanser after the horrors of the week-end.

Runtime: 4.6s.

Score: 2.

Day 11 - Chronal Charge

Day 11 - complete solution

Capsule summary:

Investigate the values of subsquares on a 300x300 grid.

Keywords: summed-area table

Trying to solve part 2 using brute force took 173 minutes. Implementing a summed-area table reduced it to 3s.

Score: 2.

Day 12 - Subterranean Sustainability

Day 12 - part 1 Day 12 - part 2

Capsule summary:

A number of plants grow in an infinite line of pots. The existance of a plant for the next generation depends on its neighbors. Investigate what plants remain after a number of generations.

Keywords: cellular automata

This was a fiddly one. I got bit by the shallow copying nature of Perl’s data structures, but implementing the Clone module took care of that.

Then is was just a question of dealing with the inevitable off-by-one errors.

Part 2 was found by reasoning that the pattern would stabilize, and after that is was just a matter of finding the pattern and identifying the offsets.

My Part 1 code can either give the answer to the question with no input, or output some useful metadata if given another argument.

Part 2 answers the question by default, and gives the value for an arbitrary input if that’s given as an argument.

Score: 2.

Day 13 - Mine Cart Madness

Day 13 - complete solution

Capsule summary:

Carts move along a track with turns and junctions. Determine whether they collide.

I’m both proud and ashamed of this one. Proud because my basic code determining how the carts move was correct from the get-go. Ashamed because it took me all day to figure out the collision detection.

Runtime: 0.4s

Score: 2.

Day 14 - Chocolate Charts

Day 14 - part 1 Day 14 - part 2

Capsule summary:

A list is generated programmatically. Investigate its properties as it grows.

Keywords: pattern matching, brute force

Not my favorite problem, not least because my brute-force solution is killed by my VPS.

Runtime for part 2: 2m14s.

Score: 2.

Day 16 - Chronal Classification

Day 16 - complete solution

Capsule summary:

An obfuscated register manipulation routine is presented. Solve the program.

Keywords: registers

This years Register Rodeo! It was fun apart from the horrid input parsing.

Score: 2.

Day 18 - Settlers of The North Pole

Day 18 - complete solution

Capsule summary:

Investigate the properties of a Game of Life setup.

Keywords: game of life

A scruffy solution. I had no problems with part 1, but part 2 was plagued by off-by-one errors.

Score: 2.

Day 19 - Go With The Flow

Day 19 - complete solution

Capsule summary:

Decompile a deliberately inefficient algorithm.

Keywords: registers, decompilation

Decompilation problems are not my favorite problems.

Score: 2.

Day 22 - Mode Maze

Day 22 - complete solution

Capsule summary:

Find the quickest path between two points on a graph.

After some struggle, I finally figured out a good way to conceptualize this.

Right now I’m using straight Djikstra’s which is way too slow.

Edit 2021-01-09 it turns out my issue wasn’t with the Dijkstra’s algo per se, but instead with my implementation of the required priority queue. After using a high-performance version from CPAN I got my runtime down from 15 minutes to around 2 seconds.

Score: 2.

Day 24 - Immune System Simulator 20XX

Day 24 - complete solution

Man, this was a slog. I coded it all myself, but got help online from working solutions to figure out where I was doing it wrong.

Part 2 was found manually.

Score: 2.

Day 25 - Four-Dimensional Adventure

Day 25 - complete solution

Capsule summary:

Investigate points in 4D space.

Keywords: union

Last problem this year. Figured this out through brute force.

Score: 1 (final star only awarded if all other solutions are done!)

Friday, 2017-12-01

Advent of Code 2017

Project website: Advent of Code 2017.

Previous years: 2015, 2016.

I use Perl for all the solutions.

Most assume the input data is in a file called input.txt in the same directory as the file. Some require extra modules from CPAN.

A note on scoring

I score my problems to mark where I’ve finished a solution myself or given up and looked for hints. A score of 2 means I solved both the daily problems myself, a score of 1 means I looked up a hint for one of the problems, and a zero score means I didn’t solve any of the problems myself.

The times are hours and minutes from the time of the puzzle release (00:00 EST) until I posted an announcement on Twitter.

My goals for this year (in descending order of priority):

  • match or beat last year’s score of 49/50.
  • solve all problems within 24 hours of release
  • be among the first 750 on each day’s leaderboard

Final score

  • Problems solved by myself: 47/50. Not really happy with this. I got caught up in the hunt for keeping my place on the local leaderboard, instead of taking the time to actually solve the problems.
  • 3 parts not solved within 24 hours.
  • Average finishing place: 1,801 for part 1, 2,151 for part 2.

Day 1 - Day 2 - Day 3 - Day 4 - Day 5 - Day 6 - Day 7 - Day 8 - Day 9 - Day 10 - Day 11 - Day 12 - Day 13 - Day 14 - Day 15 - Day 16 - Day 17 - Day 18 - Day 19 - Day 20 - Day 21 - Day 22 - Day 23 - Day 24 - Day 25

Day 1 — Inverse Captcha

Day 1 - complete solution

A nice little warmup problem. Eric pulls his usual trick of making you assume something in part 1 that you have to unassume in part 2.

Score: 2

Time: 47m

Leaderboard placement: 783 / 748

Day 2 — Corruption Checksum

Day 2 - complete solution

My suspicion that there’s going to be a lot of functional list-munging in this year’s edition is strengthening.

Score: 2

Time: 2h40m (it’s a Saturday, so I slept in!)

Leaderboard placement: 2,676 / 2,318

Day 3 — Spiral Memory

My solution for day 3: part 1, part 2

A nice headfake again. Of course you’re not going to brute-force the spiral, keeping track of the coordinates for each element, then taking the Manhattan distance of the element you want when you reach it!

Instead you use a solution from Project Euler to segment the search space and find the solution nice and quick.

Then you get to part 2 and discover you need to generate the spiral after all…

Score: 2

Time: 8h23m (first Advent Sunday, shopping for Christmas)

Leaderboard: 2,578 / 3,249

Day 4 — High-Entropy Passphrases

Day 4 - complete solution

A stark contrast to yesterday’s problem. Perl’s text processing features usually make parsing input a breeze but in this case it was almost too easy. I guess I have to be careful for what I wish for in the future.

Score: 2

Time: 37m

Leaderboard: 1,544 / 1,314

Day 5 — A Maze of Twisty Trampolines, All Alike

Day 5 - complete solution

Ah, the list of instructions! An AoC classic.

Wise to previous problems I decided to incorporate test input from the get-go, and to include a debug output. This was a nice addition for part 2, as I could just run the test input and instantly confirm my changes worked.

Runtime for part 2 is around 17.5s, which, as the answer is around 25M steps leads to a “MIPS” value of 1.4.

Score: 2

Time: 41m

Leaderboard: 1,865 / 1,712

Day 6 — Memory Reallocation

Day 6 - complete solution

I liked this puzzle, even if it was a bit on the easy side.

An interesting algorithm for detecting cycles was pointed out in the daily solutions thread: Floyd’s Tortoise and Hare. I don’t think it will give better performance for the limited data set of the puzzle, but part of the fun of AoC is learning new things.

TODO

If I get some time in the future I’d like to rework this problem using an iterator for generate the states and using the Floyd algorithm.

Score: 2

Time: 51m

Leaderboard: 1,553 / 1,433

Day 7 — Recursive Circus

Day 7 - complete solution

I was sure my lack of CS knowledge would bite me, but after 10 hours I’m not seeing any comments like “actually this is just algorithm X” on the subreddit daily thread. I guess most people solved this like I did.

A fun problem, all in all.

Score: 2

Time: 5h22m - solved part one before leaving for work, but part two was delayed by meetings and a reinstalled work computer.

Leaderboard: 1,518 / 2,406

Day 8 — I Heard You Like Registers

Day 8 - complete solution

As this is not my first register rodeo, I ran a quick check to make sure the input values were what I expected (comparison operators, whether a field was an integer or not). After that it was simply a matter of encoding the rules.

I could have used Perl’s eval to evaluate the expressions, but I’m not 100% comfortable with it so I just used a giant if/else statement instead.

I chose to write a specific function to read values from the register hash, which made inserting a statement to capture part 2 very simple.

TODO

Implement using dispatch table?

Score: 2

Time: 1h15m

Leaderboard: 1,667 / 1,639

Day 9 — Stream Processing

Day 9 - complete solution

This was a fun one!

After perusing other solutions for day 8 I decided to implement a dispatch table for handling the characters. I’m glad I did because it made adding further checks quite easy.

Part 2 threw me for a loop. I got the wrong answer for the number of garbage characters, and trying to find where my assumptions were wrong in the giant puzzle input felt impossible. However, there are a number of example inputs, and after running my code on them I found where I was mistaken…

Score: 2

Time: 5h35m (I’m not gonna get up at 6AM on a Saturday…)

Leaderboard: 2,604 / 2,850

Day 10 — Knot Hash

My solution for day 10: part 1, part 2

Difficulty is ramping up.

The biggest issue I had with this was the @#%&*! array manipulation in part 1.

Score: 2

Time: 5h09m

Leaderboard: 2,149 / 1,867

Day 11 — Hex Ed

Day 11 - complete solution

A fun problem. I didn’t know anything about hex grids but like everyone and their mom I googled and found this excellent site that explains them well.

Score: 2

Time: 1h02m

Leaderboard: 1,110 / 1,007

Day 12 — Digital Plumber

Day 12 - complete solution

I could probably have solved this in a more Perlish way but here I at least understand what’s going on.

Score: 2

Time: 2h47m

Leaderboard: 2,108 / 2,038

Day 13 — Packet Scanners

My solution for day 13: part 1, part 2

This was the first problem that has a significant runtime (without optimization). Even after some work I have a ~10m runtime for part 2.

TODO

Optimize for faster runtime.

Score: 2

Time: 13h23m

Leaderboard: 2,462 / 4,224

Day 14 — Disk Defragmentation

Day 14 - complete solution

A nice mix of difficulty and entertainment. Unreasonably proud of independently finding the four-way flood fill algorithm.

Score: 2

Time: 4h51m

Leaderboard: 1,096 / 1,636

Day 15 — Dueling Generators

Day 15 - complete solution

Brute force, baby!

I used an iterator for part 2, then wrangled both solutions into one using that technique.

The generators are well known.

Score: 2

Time: 3h06m

Leaderboard: 1,130 / 1,929

Day 16 — Permutation Promenade

Day 16 - complete solution

After the usual struggles with Perl’s lists I got this working.

I decided to go with a dispatch table from the start, which made part 2 easier to implement.

Score: 2

Time: 4h34m

Leaderboard: 1,682 / 1,370

Day 17 — Spinlock

My solution for day 17: part 1, part 2

Solving part 1 gave some data for how to solve part 2. It took some fiddling though!

Score: 2

Time: 8h52m

Leaderboard: 2,067 / 2,990

Day 18 — Duet

My solution for day 18: part 1, part 2

So far the most entertaining problem. Bravo!

Score: 2

Time: 4h33m

Leaderboard: 1,015 / 1,057

Day 19 — A Series of Tubes

Day 19 - complete solution

This was supposed to be a “breather” problem, instead it stymied me something fierce.

Score: 2

Time: 8h36m

Leaderboard: 2,744 / 2,688

Day 20 — Particle Swarm

My solution for day 20: part 1, part 2

Gratified to finally be among the first 1,000 to solve this problem, especially considering how relatively easy it was.

Update Day 20 - alternative part 1 - closed form

Score: 2

Time: 2h29m

Leaderboard: 913 / 984

Day 21 — Fractal Art

Day 21 - complete solution

What a fiddly problem!

Score: 2

Time: > 24h

Leaderboard: 2,426 / 3,035

Day 22 — Sporifica Virus

My solution for day 22: part 1, part 2

This puzzle is based on Langton’s ant which I’ve grappled with for Project Euler. I chose not to re-use any code though.

Runtime for part 2 is 31s which is just barely acceptable

Score: 2

Time: 2h47m

Leaderboard: 1,094 / 1,022

Day 23 — Coprocessor Conflagration

My solution for day 23: part 1, part 2

I had to give up on part 2, it wasn’t interesting enough to power through. Credt for part 2 in source.

Score: 1

Time: 11h31m

Leaderboard: 1,287 / 1,826

Day 24 — Electromagnetic Moat

Day 24 - complete solution

I just couldn’t get this to work so had to bail. Credit in source!

Score: 0

Time: >24h

Leaderboard: 3,057 / 3,012

Day 25 — The Halting Problem

Day 25 - complete solution

My solution runs in 30s which can surely be improved.

Score: 2 (really 1)

Time: 3h31m for part 1

Leaderboard: 1,197 / 2,340

Thursday, 2016-12-01

Advent of Code 2016

Project website: Advent of Code 2016.

My solutions for AoC 2015.

I use Perl for all the solutions.

Most assume the input data is in a file called input.txt in the same directory as the file. Some require extra modules from CPAN.

A note on scoring

I score my problems to mark where I’ve finished a solution myself or given up and looked for hints. A score of 2 means I solved both the daily problems myself, a score of 1 means I looked up a hint for one of the problems, and a zero score means I didn’t solve any of the problems myself.

The times are hours and minutes from the time of the puzzle release (00:00 EST) until I posted an announcement on Twitter.

My goals for this year (in descending order of priority):

  • solve all problems myself (higher cumulative score than last year’s 43/50).
  • solve all problems within 24 hours of release
  • be among the first 1,000 on each day’s leaderboard

Final score

  • Problems solved by myself: 49 / 50 — a big improvement over last year’s 43/50.
  • 3 parts not solved within 24 hours. Shortest time for both parts: 40 minutes. Average time: 5h07m.
  • Average finishing place for each day: 677.8 for part 1, 747.6 for part 2.

Day 1 - Day 2 - Day 3 - Day 4 - Day 5 - Day 6 - Day 7 - Day 8 - Day 9 - Day 10 - Day 11 - Day 12 - Day 13 - Day 14 - Day 15 - Day 16 - Day 17 - Day 18 - Day 19 - Day 20 - Day 21 - Day 22 - Day 23 - Day 24 - Day 25

Day 1 — No Time for a Taxicab

My solution for day 1: part 1, part 2.

I managed to get the correct solution in part 1 despite not taking absolute values in consideration, fixed in code.

Part 2 was frustrating as I didn’t have time to re-think the problem, instead I kludged something on top of part 1.

Score: 2, 9h50m.

Day 2 — Bathroom Security

My solution for day 2: part 1, part 2.

Actually reading the Wikipedia article linked from day 1 helped me with part 2.

Alternate part 2, inspired by this solution.

Score: 2, 4h21m.

Day 3 — Squares With Three Sides

My solution for day 3: part 1, part 2.

The hardest part of this problem was cleaning up the input…

Score: 2, 3h59m.

Day 4 — Security Through Obscurity

My solution for day 4: part 1, part 2.

A fun problem!

Score: 2, 3h38m.

Day 5 — How About a Nice Game of Chess?

My solution for day 5: part 1, part 2.

I already had the required modules installed since 2015 day 4 and initially thought this was going to be straight repeat. While part 1 was indeed simple enough, part 2 threw me for a little loop due to the requirements to keep track of previous entries.

Score: 2, 2h32m.

Day 6 — Signals and Noise

My solution for day 6. Alternative with more map.

Decided to try to solve this over breakfast.

Score: 2, 0h40m.

This was the last of the warmup problems. Things will get tougher from now on.

Day 7 — Internet Protocol Version 7

My solution for day 7: part 1, part 2.

Not very proud of part 2, but at least I know what it does. Using regexps would be the obvious choice but I frankly lack the regex-fu to handle it.

Update: some quick googling revealed the existence of lookahead to deal with overlapping matches, so I whipped together an alternative part 2. This runs appreciably faster (although still within a second).

Just made the first 1,000 submitters for part 2.

Score: 2, 4h36m.

Day 8 — Two-Factor Authentication

My solution for day 8, both parts.

Really didn’t want to do this, it reeked of fiddly bit-flipping, but after thinking a bit the solution presented itself.

Again just squeeked in under the 1,000 first submitters for both parts.

Score: 2, 4h27m.

Day 9 — Explosives in Cyberspace

My solution for day 9: part 1, part 2.

I’m debating whether to award myself 2 points for this, as I had to look for hints for part 2.

The issue was that I was running a recursive solution, but instead of simply counting the characters of a single part and then multiplying by the number of repetitions, I actually created a new array that was the part repeated repetitions times! This led to horrendous execution times.

Score: 2, 5h11m.

Day 10 — Balance Bots

My solution for day 10, both parts.

I usually don’t forget to sort numerically but I did this time, which led to a wild goose chase trying to find out why real input differed from test.

Family commitments prevented a faster time but I still submitted in the first thousand.

Score: 2, 8h15m

Day 11 — Radioisotope Thermoelectric Generators

Finally a solution after almost 6 days.

Not fantastically proud of this, kept plugging away at some solutions even if I’d have had better luck taking a step back and reconsidering. But I solved it myself!

The most problems I had was with the shuffling stuff to and from floors. The last piece fell into place when I realized I had to keep track of the elevator too when considering already visited states.

Solves part 2 in around 11m, which is just barely acceptable.

Score: 2.

Day 12 — Leonardo’s Monorail

Day 12 - complete solution

Score: 2, 5h05m.

Day 13 — A Maze of Twisty Little Cubicles

My solution for day 13: part 1, part 2.

I’ve been thinking a lot about day 11, so the breadth-first search concept came in handy.

Score: 2, 4h39m.

Day 14 — One-Time Pad

My solution for day 14.

This was both tough and kind of boring.

Key insight was this throwaway comment by /u/askalski. Each candidate index is stored in a hash keyed on the duplicate character, and any hit of quintuples is checked

A lot of subtle off-by-one errors made this quite frustrating.

Performance is respectable, especially part 2. Example input:

$ time perl ./d14.pl
==>22728
real    0m0.601s

$ time perl ./d14.pl 2
==>22551
real    0m41.553s

Update 16 Dec 2016 alternative version with cleaner code.

Score: 2, 12h18m.

Day 15 — Timing is Everything

My solution for day 15.

Fast and simple brute-force solved this one.

Score: 2, 1h06m.

Day 16 — Dragon Checksum

My solution for day 16.

The nice and tidy recursive solution I coded for part one takes 1m34s to complete part two, but this is not a very interesting problem so I will just leave it at that.

Score: 2, 3h22m (this is day off for me).

Day 17 — Two Steps Forward

My solution for day 17.

Straight-forward application of techniques known so far. Key to part 2 is to realize BFS returns all solutions, not just the shortest.

Score: 2, submitted after 8h57m on a Saturday.

Day 18 — Like a Rogue

My solution for day 18: complete.

Quick and dirty fourth Advent Sunday breakfast solution. Part 2 runs in 2m30s using the same code as part 1, just many more rows. Brute force baby.

I might try to improve part 2 later.

Edit: here’s a a second attempt. Credit.

Part 2 runtime is 33s for this version.

Score: 2, 3h25m.

Day 19 — An Elephant Named Joseph

My solution for day 19 part 1: part 1.

Part 2 defeated me, this is part 2 with copied code, credit in source.

Update: this alternative is way more Perlish, credit in source!

This is the first problem I actually bailed on, which is a step up from last year. I liked it in a way that you simply couldn’t just run part 2 as a straight continuation of part 1, but had to rethink your strategy, but this problem was too boring for me to bother doing that.

Score: 1, 5h49m.

Day 20 — Firewall Rules

Day 20 - complete solution

Straightforward. Runtime 0.11s.

Score: 2, 4h18m.

Day 21 — Scrambled Letters and Hash

My solution for day 21: part 1, part 2.

A boring and fiddly part 1 led to a straight-forward brute-force solution for part 2. That part finishes in 40s on my machine.

At least I finally got to learn how splice works…

TODO: implement dispatch table?

Score: 2, 5h19m

Day 22 — Grid Computing

My solution for day 22: part 1, part 2.

For part 2, I took a chance that there was nothing hindering moving the empty slot in straight lines apart from the “walls”. A simple count of the needed steps gave the solution.

Score: 2, 4h22m.

Day 23 — Safe Cracking

Complete solution.

Entirely unoptimized, runtime for part 2 is 101 minutes!

I was sidetracked by the fact that my first attempt at part 1 gave the correct solution, but failed for part 2.

TODO: better performance?

Score: 2.

Day 24 — Air Duct Spelunking

Complete solution

I used BFS to compute the distances between all points, then used the technique from AoC 2015 day 9 to generate all possible permutations and print them out.

Part 2 runs in less than 2 seconds.

Score: 2, 8h52m on Christmas eve!

Day 25 — Clock Signal

Complete solution

All done! Quick and dirty solution using brute force with crappy pattern detection.

Score: 2, 4h24m.

Monday, 2015-12-14

Advent of Code 2015

Project website: Advent of Code.

I started on these puzzles on 7 Dec 2015. So far I’ve completed all of them, all but a few on the same day they were posted.

I use Perl for all the solutions.

Most assume the input data is in a file called input.txt in the same directory as the file. Some require extra modules from CPAN.

A note on scoring

I score my problems to mark where I’ve finished a solution myself or given up and looked for hints. A score of 2 means I solved both the daily problems myself, a score of 1 means I looked up a hint for one of the problems, and a zero score means I didn’t solve any of the problems myself.

Final score: 43 / 50.

Github link.

Days 1 to 4 - Day 5 - Day 6 - Day 7 - Day 8 - Day 9 - Day 10 - Day 11 - Day 12 - Day 13 - Day 14 - Day 15 - Day 16 - Day 17 - Day 18 - Day 19 - Day 20 - Day 21 - Day 22 - Day 23 - Day 24 - Day 25

Days 1 to 4

Day 5 — Doesn’t He Have Intern-Elves For This?

My solution: part 1 - part 2.

I had to get help with part 2 here, found a regexp in the daily solutions thread for this day.

Score: 1.

Day 6 — Probably a Fire Hazard

Part 1 - part 2.

These could definitely be faster, both run in around 30s.

Score: 2.

Day 7 — Some Assembly Required

Had to scrounge around for tips on how to solve this. I had the basic idea down but the problem was keeping track of the solutions as I iterated around.

Score: 0.

Day 7

Update 2017-12-28 Day 7 - alternative complete solution

Day 8 — Matchsticks

Easily the most boring of the problems so far.

Part 2 only.

Score: 2.

Day 9 — All in a Single Night

Essentially the travelling salesman problem but the number of destinations is small enough to brute-force easily. Uses the Algorithm::Combinatorics module. Output is a list of permutations with the total travelling distance prepended, so just use sort -n to find the answer from the output.

Update 2017-12-28 Day 9 - alternative complete solution. This solution removes the need to sort an output file.

Score: 2.

Day 09.

Day 10 — Elves Look, Elves Say

Another computationally expensive problem but even part 2 runs in under 1 minute for me.

Submitted 3h25m after puzzle release.

Update 2017-12-28 Day 10 - alternative complete solution. Much faster regex-based solution from Rosettacode.

Score: 2.

Day 10.

Day 11 — Corporate Policy.

Day 11 - complete solution

So far my favorite problem!

Submitted 5h56m after puzzle release.

Score: 2.

Day 12 — JSAbacusFramework.io.

Another good puzzle. Uses the JSON module.

Day 12 - complete solution

Submitted 9h25m after puzzle release (I blame family commitments on weekends!).

Score: 2.

Day 13 — Knights of the Dinner Table.

Day 13 - complete solution

This is a modified day 9 with bidirectionally. Even part 2 which adds another element to the permutation finishes very quickly using brute force.

Submitted 5h03m after puzzle release.

Score: 2.

Day 14 — Reindeer Olympics.

A troll! The immediate brute force approach is to simply advance time 1s at a time and check the “position” of each deer at that time. But this is “obviously” dumb so I used a quicker approach for part 1. Part 2 made me regret it…

Submitted for 2 stars 4h04m after puzzle release.

Day 14 - complete solution

Day 14 - complete solution with fancy scoreboard

Score: 2.

Day 15 — Science for Hungry People.

A combination of outside factors and frustration at getting my indexes right made this a tedious slog.

Submitted for 2 stars 9h45m after puzzle release.

Score: 2.

Day 15 - complete solution

Day 16 — Aunt Sue.

A fun one. Submitted for 2 stars after 2h37m.

Score: 2.

Day 16 - complete solution

Day 17 — No Such Thing as Too Much

Tried a recursive approach first, but got stuck for the part 2 and looked in the daily thread for inspiration. Figured out how to use combinations by looking at other’s code.

Submitted for 2 stars after 6h18m.

Score: 1.

Day 17 - complete solution

Day 18 — Like a GIF For Your Yard

Conway’s Game of Life! I’ve never coded this before so it was a fun exercise.

I tried using arrayrefs first but got tripped up by the deep copy (dclone in the code) and decided to go for a hash of hashes instead. I think this contributes to the slow execution time of ~15s.

Submitted for 2 stars after 6h00m.

Score: 2.

Day 18 - complete solution

Day 19 (Saturday) — Medicine for Rudolph

A tough one! I solved part 1 no problems but had to hunt around for hints for part 2.

Day 19 - part 1. Day 19 - part 2 alternative solution.

Score: 1.

Day 20 (Sunday) — Infinite Elves and Infinite Houses

Lack of time and impatience led me to look for hints for this. I had the right initial idea but thought looking for divisors of an integer without the PARI package would be too slow, and I have yet to find a way to install that on the machine I’m using.

In the end it didn’t matter but I wanted this done.

Full credits in source.

Day 20.

Score: 0.

Day 21 — RPG Simulator 20XX

I went for a straightforward solution of generating all combos of items and then running a simulated battle with each.

Day 21.

Score: 2.

Day 22 — Wizard Simulator 20XX

Not a very good solution, relies on brute force to simulate all possible spell casts and then prints out a win or loss. Note that I had to run it for 5M iterations to get the answer to part 2. This is the only problem I didn’t finish in the same day as it was released (apart from the 7 first ones).

Day 22.

Score: 2.

Day 23 — Opening the Turing Lock

Straightforward apart from the slightly ambigious jio instruction — read carefully what it means.

Day 23.

Score: 2.

Day 24 (Christmas eve) — It Hangs in the Balance

I tried to finesse the answer by hand first but it didn’t simply work to manually adjust the packages to get desired answer. Instead I checked valid combinations, but with the following assumptions/optimizations:

  1. I sorted the packages in descending order to check those combinations first.
  2. I assumed the answer wouldn’t contain more than 6 elements, so just checked combinations up to that value of k.
  3. I didn’t bother to confirm the remaining packages would sum correctly.

Runs in about 2s.

Day 24.

Score: 2.

Day 25 (Christmas day) — Let It Snow

Straightforward iterative solution. Runs in over half a minute, those with CS backgrounds used modular exponentiation and got much faster results.

Day 25.

Score: 2.

(un)License

The solution files are in the Public Domain.