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

Today there’s a chance to demonstrate powerful features of Raku on the solution of Day 18 of this year’s Advent of Code.

The task is to print the sum of a list of expressions with +, *, and parentheses, but the precedence of the operations is equal in the first part of the problem, and is opposite to the standard precedence in the second part.

In other words, 3 + 4 * 5 + 6 is (((3 + 4) * 5) + 6) in the first case and (3 + 4) * (5 + 6) in the second.

Here is the solution. I hope you are impressed too.

use MONKEY-SEE-NO-EVAL;
 
sub infix:<m>($a, $b) { $a * $b }

say [+] ('input.txt'.IO.lines.race.map: *.trans('*' => 'm')).map: {EVAL($_)}

The lines with the expressions come from the file input.txt. For each line, I am replacing * with m, which I earlier made an infix operator that actually does multiplication.

For the second part, we need our m to have lower precedence than +. There’s nothing simpler:

sub infix:<m>($a, $b) is looser<+> { $a * $b }

Parsing and evaluation are done using EVAL.

* * *

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

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

  1. Cool! It took me a while to understand why you had to replace the ‘*’ by the letter ‘m’. Then I realized you had to make both operators have the same precedence to solve the first problem. After that I had to agree that using EVAL isn’t cheating at all. 🙂

    Nice job!

    1. Yes, my first try was to simply redefine both * and +, but I could not change their built-in precedence with either traits, so I had to replace one of the operators with a custom one.

Leave a 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