# 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(\$/.Str, \$/.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.

* * *

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

1. Michael says:

I used an enum trick to get away with only one candidate for move(‘F’, \$dist) – see https://github.com/mscha/aoc/blob/master/aoc2020/aoc12
But even without that trick, you could have used:

multi sub move(‘F’, \$dist where \$dir == 0) { move(@dirs[\$dir], \$dist) }

2. Michael says:

Correction:

I used an enum trick to get away with only one candidate for move(‘F’, \$dist) – see https://github.com/mscha/aoc/blob/master/aoc2020/aoc12
But even without that trick, you could have used:

multi sub move(‘F’, \$dist) { move(@dirs[\$dir], \$dist) }

1. Andrew Shitov says:

That’s good indeed.