Thursday, 2022-12-01

Advent of Code 2022

Project website: Advent of Code 2021.

This is a placeholder entry. Current progress can be tracked in the GitHub repo: https://github.com/gustafe/aoc2022#advent-of-code-2022. Comments for solutions are in Pod format in the individual solution files.

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

Related to this entry.

Saturday, 2021-12-25

HOWTO AoC

Some tips about participating in Advent of Code.

AoC is not a competition

If you were to go with online opinion, AoC is all about getting the solutions as fast as possible. This is actually not true, apart from the top 100 scorers every day[1]. Many people post their full solution online on the AoC subreddit as soon as the top 100 slots have been filled. So if you want to get 50 stars, you pick a popular language (like Python), hang out in the solutions megathread, and run the first posted solution on your input to get the correct results.

If your organization has a “competition” where the top scorers in their leaderboard get some reward, don’t participate. It’s too easy to suspect someone of “cheating” for it to be fun.

Instead, focusing on using the event to expand your skills.

You don’t need to finish each puzzle the day it is released, or within the 25 first days of December

The puzzles can be completed at any time and in any order.

Don’t let trivial mistakes trip you up

In almost every puzzle, your personalized input will be provided as a text file. Set up your environment to deal with this consistently.

For example, for every puzzle, I make a new subdirectory. The puzzle input goes into a file called input.txt. The example input goes into another file, test.txt. I then open a new file for my code, and enter a canned template that reads the content of a file into an array, one line per entry. It takes care of newlines and carriage returns (but preserves empty lines).

Then, when it comes to dealing with the input meaning, I can operate on an abstract array instead of a file.

In a similar manner I also set up some modules for dumping variables, running simple tests, etc.

You can see my (Perl) template here.

Use the examples

The puzzle text is clearly written, and any questions you might have regarding the rules of the puzzle are answered in the text or in the example. Once you get the example to run correctly, it’s generally just a question of changing the in-data to “live” to get your answer.

Generally. At higher levels there can be “twists” in how the real data is presented as compared to the examples. Also look out for edge cases. The example data might not include negative numbers, but the real input does. Have you taken that into account?

Puzzles start out easy but get harder

And weekends are generally tougher than weekdays.

Some problem classes tend to make an appearance every event

These include

  • Conway’s Game of Life
  • Register Rodeo - this is my term for a class of problem where you’re given a long list of statements, some of which are data and some of which are instructions, and you need to decode them
  • pathfinding through a maze
  • finding the lowest cost for some complicated series of actions (generalized Dijkstra’s)

Having a basic knowledge about these is beneficial, but not required.

Remember to have fun!

[1] if you want to try to crack the top 100, this guide is not for you.

Wednesday, 2021-12-01

Advent of Code 2021

Project website: Advent of Code 2021.

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

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

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 a total score of 40 or more (75%)
  • solve all problems up until day 15 without any external input - not fulfilled
  • solve all problems within 24 hours of release - not fulfilled

Link to Github repo.

Final status: score of 46/50.

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 31

Day 1 - Sonar Sweep

Day 1 - complete solution

And we’re off!

I wonder if I got a bit too clever by half in this solution, as I’ve been looking over older solutions and can’t even remember solving them. But that’s how it goes I guess.

Puzzle rating: 3/5

Score: 2

Day 2 - Dive!

Day 2 - complete solution

A “standard” Perlish solution (well, my kind of Perl, anyway): a dispatch table for the else/if “switch” construct, and a compact hash containing the state of the two solutions.

Puzzle rating: 3/5

Score: 2

Day 3 - Binary Diagnostic

Day 3 - complete solution

I was honestly surprised that the canonical solution to this wasn’t some esoteric bit-twiddling trick that reduces it to a one-liner.

In part 2, the naive solution is to loop through each “column” to determine which values to count so as to determine whether they are most frequent or not. I used an index for each “set” to keep track of the values already assigned to that set.

Puzzle rating: 3/5

Score: 2

Day 4 - Giant Squid

Day 4 - complete solution

Fairly straight-forward, although part 2 threw me for a loop. I didn’t find a good way to determine the exit condition.

Puzzle rating: 4/5

Score: 2

Day 5 - Hydrothermal Venture

Day 5 - complete solution

Finally ok with my solution.

The first attempt got the job done, but was super-scruffy. I realized after I’d finished that I could treat the direction as unit vectors and work from there, so I re-wrote my solution, but only in as so far as to use the direction as a “selector” to chose which subroutine to call to “paint” the map.

After adding that to the repo, I finally remembered what I’d decided before the rewrite - to use the value of the vector in the paint routine itself.

Note that just using atan2 blindly to determine the direction will point the Y axis incorrectly. It’s probably only an issue if you’re printing the results, but I found that very helpful in debugging.

If anything good can be said about this method is that I eliminated a lot of weirdness along the way. It wasn’t all wasted effort.

Puzzle rating: 3/5

Score: 2

Day 6 - Lanternfish

Day 6 - complete solution

I got off on a bad start with this puzzle, because it worked perfectly for the test input but failed for my puzzle input. I whinged about it on IRC, mentioning I had a very old fish (41 days!). Turns out that was a mispaste and fixing that gave me the correct solution.

I got the answer to the second part 40 seconds later.

Puzzle rating: 4/5, just because my solution was so smooooth

Score: 2

Day 7 - The Treachery of Whales

Day 7 - complete solution

A quite fun one, and the first this year I managed to solve within 1hr of release. This might be TMI but I usually perform my morning ablutions and brew a pot of coffee before starting on a puzzle.

Thinking about this led me to try the average (mean) of the values as the natural solution, but that gave incorrect values. So I just checked the fuel consumption for each and every possible end point, selecting the minimum value. This went plenty fast, as did part 2 once I didn’t actually step through each distance calculating fuel as I went (hint: google “Gauss sum 100”).

When I had both solutions, I checked the various IRC chats and subreddits and discovered a raging debate on whether taking the median for part 1 and the average for part 2 always gave the correct result for every input. For me they did, so I just restricted by search space to the span of these values, plus a few extra integers for safety. This shaved a couple more milliseconds off the run time.

Puzzle rating: 4/5, I like grade school math

Score: 2

Day 8 - Seven Segment Search

Day 8 - complete solution

Today was a tough one - not the problem, per se, but commitments that made it hard to me to get to a solution that I was happy with.

In the end I just went for brute-forcing every possible permutation, which is 7! or 5,040. The solution takes around 2s to run on my VPS.

Puzzle rating: 3/5, bit fiddly

Score: 2

Day 9 - Smoke Basin

Day 9 - complete solution

This was a straight-forward problem.

I’m a bit surprised my BFS solution worked first time.

Puzzle rating: 3/5

Score: 2

Day 10 - Syntax Scoring

Day 10 - complete solution

Not the most elegant solution but it gets the job done.

Puzzle rating: 3/5

Score: 2

Day 11 - Dumbo Octopus

Day 11 - complete solution

Nice and easy, got 2 stars within one hour of downloading the input.

I don’t think my handling of some flags ($has_changed, $has_synced) is the most elegant. I’m pretty sure I’m doing an extra scan of the entire map every step to ensure everything has settled down. But I get a result within 1s (just) so let’s do some weekend chores instead.

I suspect tomorrow will be… more challenging.

Puzzle rating: 3/5

Score: 2

Day 12 - Passage Pathing

Day 12 - complete solution

I had to look up a solution for this, which was kind of embarrasing for such an early problem.

Full credit in source.

Puzzle rating: 3/5

Score: 0

Day 13 - Transparent Origami

Day 13 - complete solution

As usual, a breather after the weekend.

I was tearing my hair out, running spot checks on my code, before I realized I had coded my output incorrectly.

The rest of my issues was making it read the right way up…

“Best” result so far, around rank 6,500 for part 1…

Puzzle rating: 3/5

Score: 2

Day 14 - Extended Polymerization

Day 14 - complete solution Day 14 - part 1

A tough but fun problem.

Part 1 only for now.

Update 2021-12-15: finished both parts.

Puzzle rating: 4/5

Score: 2

Day 15 - Chiton

Day 15 - part 2

I think I finally figured out A*Dijkstra’s. With the help of a lot of cribbing from previous solutions (like 2018 day 22).

I’ve only included part 2 because I can’t be bothered bounding the box for part 1 so it doesn’t choose a cheaper solution outside those limits.

Puzzle rating: 4/5

Score: 2

Day 16 - Packet Decoder

Day 16 - complete solution Day 16 - part 1

Many people went “BERR” when they saw this: Binary Encoded Register Rodeo!

I had a lot of problems with this, mostly because I managed to get the correct solution for part one a bit by accident, which didn’t help solving part 2.

After a day of tearing my hair trying to pass data between recursion levels I managed to solve it.

Puzzle rating: 4/5 - tough, but fair

Score: 2

Day 17 - Trick Shot

Day 17 - complete solution

Suspiciously easy.

This year’s last weekend is coming up.

Brace yourselves.

Puzzle rating: 3/5

Score: 2

Day 18 - Snailfish

Day 18 - complete solution Day 18 - testing

Completed 2021-12-31

Actually less complicated then at first glance. The main issue was figuring out how to implement the rules where “explode” had higher precedence than “split”, but I managed that with a stack.

Puzzle rating: 4/5

Score: 2

Day 19 - Beacon Scanner

Day 19 - complete solution

Completed 2021-12-28

A fun problem. I found a list of all possible rotation transforms and used them to generate the set of rotations to try, then just compared each and every one to find offsets. Runtime is around 15s.

Puzzle rating: 4/5

Score: 2

Day 20 - Trench Map

Day 20 - complete solution

Back on track after a tough weekend - which I had to skip due to travel.

This was a fun problem once you figured out the trick.

Puzzle rating: 4/5

Score: 2

Day 21 - Dirac Dice

Day 21 - complete solution

A fun problem, but part 2 was too tough for me. I copped out and took a “free” star. Full credit in source!

Puzzle rating: 4/5

Score: 1

Day 22 - Reactor Reboot

Day 22 - part 1 Day 22 - part 2

Cubes - IN SPACE!!

I only had time for part 1 on release day.

Part 2 completed on 2021-01-04.

Puzzle rating: 4/5

Score: 2

Day 23 - Amphipod

Day 23 - complete solution

Completed 2021-12-26

A fun problem but one I had to skip on release day due to preparations for Christmas.

We’ve seen this sort of thing before, I solved it using Dijkstra’s.

In general, we have a start state and an end state, and we can generate new states based on the given rules. These intermediate states can be seen as nodes in a graph we’re constructing on the fly. Applying the movement costs for each amphipod gives the total cost for moving form start to end, and Dijkstra’s algorithm gives the lowest cost.

Puzzle rating: 4/5

Score: 2

Day 24 - Arithmetic Logic Unit

Day 24 - complete solution

I had to crib a solution (credit in source, of course) but I gave myself a point because it was Christmas Eve and that’s when we get presents here, damnit.

Puzzle rating: 4/5

Score: 1

Day 25 - Sea Cucumber

Day 25 - complete solution

And… it’s a wrap.

Not the most elegant solution but it’s a star. I’ll take it.

Puzzle rating: 3/5

Score: 2 (assuming I fix the missing stars!)

Day 31 - Template

Day 31 - commented template

Related to this entry.

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.