Advent of Code 2020 Day 12.1/25 in the Raku programming language

Here is my solution of the first part of Day 12 of this year’s Advent of Code. The point in this solution is that I use multi functions a lot. Well, actually, the whole logic of the program is based on the dispatching rules of the variants of a single multi function.

We start with a ship at point (0, 0) on a 2D map and we’ve got a list of instructions such as:

F10
N3
F7
R90
F11

The letters N, S, W, and E mean that you have to move the position the given distance North, South, West, or East. The commands L or R mean that you have to rotate the ship itself anticlockwise or clockwise by 90, 180, or 270 degrees. Initially, the ship looked East.

The task is to tell how far from the beginning your ship finds itself after it followed all the instructions.

Here is my solution.

my ($x, $y) = 0, 0;
my @dirs = <E N W S>;
my $dir = 0; # E

for 'input.txt'.IO.lines -> $line {
    $line ~~ /(\w) (\d+)/;
    move($/[0].Str, $/[1].Int);
}

say $x.abs + $y.abs;

multi sub move('L', $deg) { $dir = ($dir + $deg / 90) % 4 }
multi sub move('R', $deg) { $dir = ($dir - $deg / 90) % 4 }

multi sub move('E', $dist) { $x += $dist }
multi sub move('N', $dist) { $y += $dist }
multi sub move('W', $dist) { $x -= $dist }
multi sub move('S', $dist) { $y -= $dist }

multi sub move('F', $dist where $dir == 0) { $x += $dist }
multi sub move('F', $dist where $dir == 1) { $y += $dist }
multi sub move('F', $dist where $dir == 2) { $x -= $dist }
multi sub move('F', $dist where $dir == 3) { $y -= $dist }

The file with instructions is read line by line, and then a call to move() happens. I have a bunch of such functions for each possible case.

Notice that the variants treat the second argument differently. In the first case, it means degrees, in all other cases, it is distance. But in any case, Raku can distinguish the functions by its first argument.

With F, the things are a bit different. Both the first and the second arguments of the four variants of move('F', $dist) are the same, but there’s also the where clause, which—and that’s the point!—uses the current value of a global variable. So, it does not look at the arguments the function receives, but it still dispatches its behaviour based on a variable.

* * *

→ Browse the code on GitHub
→ See all blog posts on Advent of Code 2020

4 thoughts on “Advent of Code 2020 Day 12.1/25 in the Raku programming language”

Leave a Reply to Michael Cancel reply

Your email address will not be published. Required fields are marked *

Retype the CAPTCHA code from the image
Change the CAPTCHA codeSpeak the CAPTCHA code