🎄 8/25. Adding up even Fibonacci numbers in Perl 6

🎄 8/25. Adding up even Fibonacci numbers in Raku

N. B. Perl 6 has been renamed to Raku. Click to read more.


Welcome to Day 8 of this year’s Perl 6 One-Liner Advent Calendar. It is about ¼ of the whole series, and don’t forget that you can type ¼ instead of 0.25 in Perl 6!

Today, we are solving problem 2 from Project Euler. The task is to find the sum of all even Fibonacci numbers below four million.

Here’s the complete solution:

(1, 1, * + * ... * > 4_000_000).grep(* %% 2).sum.say

It is equally interesting to parse the code from either left or right. Let’s start from left.

Inside the first parentheses, we are generating a sequence of Fibonacci numbers, which starts with two 1s, and each following number is a sum of two previous ones. In Perl 6, you can express it using a WhateverCode block: * + * is equivalent to {$^a + $^b}.

A less known feature of Perl 6 sequences is the final condition. In many examples you would see either a bare star or an Inf. In our example, we limit the sequence with an explicit upper boundary.

Notice that you cannot simply write:

1, 1, * + * ... 4_000_000

To visualise it better, try a smaller limit, say 100:

> (1, 1, * + * ... 100)
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181

Perl 6 does not stop when the sequence crosses our desired border, and continues generating numbers. It will only stop it if the next calculated element of the sequence equals to the given number exactly, for example:

> (1, 1, * + * ... 144)
(1 1 2 3 5 8 13 21 34 55 89 144)

If you don’t know a Fibonacci number preceding four million, use another WhateverCode block with a Boolean condition: * > 4_000_000. Notice that the condition is opposite to what you would write in a regular loop, as here we are demanding more than four million, not less than. This is the condition that becomes True when you have to stop the sequence. Without the star, you could use the default variable: {$_ > 4_000_000}.

The rest of the code greps even numbers and adds them up. See Day 2 for more detailed explanations of these operations.

Sounds great! Let’s talk more about cool Perl 6 one-liners tomorrow.

8 thoughts on “🎄 8/25. Adding up even Fibonacci numbers in Perl 6”

    1. Very valid comment.

      > 1, 2 ... * > 10
      (1 2 3 4 5 6 7 8 9 10 11)
      > 1, 2 ... * >= 10
      (1 2 3 4 5 6 7 8 9 10)

      But I thought that there’s a very small chance 4000000 is a Fibonacci number, so we can gain one character in the one-liner 🙂 But to be strict, it should be >=.

  1. Actually…

    > (1, 1, * + * … * > 4_000_000).tail
    5702887

    It happens to be odd, so isn’t included in the sum, and the answer is correct. But that’s not a “very slim chance”, 33⅓% of all Fibonacci numbers is even.
    Using ≥ doesn’t help either.

    Correct version:

    1, 1, * + * …^ 4_000_000

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