Centenary Sequences with Raku
Part 2

Arithmetic and Geometric Sequences

by Arne Sommer

Centenary Sequences with Raku - Part 2: Arithmetic and Geometric Sequences

[100.2] Published 4. November 2020.

See also: The Introduction | Part 1: Raku

Arithmetic Sequences

An Arithmetic Sequence is a sequences where the offset (the difference between the values) is constant. The difference may be positive or negative.

Some examples:

(1, 2, 3, 4)      # Difference: 1
(6, 7, 8, 9)      # Difference: 1
(1, 3, 5, 7)      # Difference: 2
(3, -2, -7, -12)  # Difference: -5

Sequences are more fun when they go on forever, so I'll mainly do that.

001. Positive Integers
We can use a Range for this, to show off that we actually know what it is, instead of just using a Sequence regardlessly.

(1 .. Inf)                                                              # 001

002. Positive Integers and Zero
We can start with 0 (zero).

(0 .. Inf)                                                              # 002

003. Negative Integers
We can count down from -1 to -Inf. Now we have to use a Sequence.

(-1 ... -Inf)                                                           # 003

004. Negative Integers and Zero
We can start with 0 (Zero).

(0 ... -Inf)                                                            # 004

005. Positive Even Integers
We can set up a Sequence with the first two values, and Raku will figure out the pattern for us:

(2, 4 ... Inf)                                                          # 005

The third value and so on are computed by taking the difference between those values, and adding it to the previous one.

> say (2, 4 ... Inf)[^10];
(2 4 6 8 10 12 14 16 18 20)

006. Positive Even Integers and Zero
We can start with 0 (Zero).

(0, 2 ... Inf)                                                          # 006

007. Negative Even Integers
The difference can be negative:

(-2, -4 ... -Inf)                                                       # 007

008. Negative Even Integers and Zero
We can start with 0 (Zero).

(0, -2 ... -Inf)                                                        # 008

009. Positive Odd Integers
Odd numbers are just as easy:

(1, 3 ... Inf)                                                         # 009

010. Negative Odd Integers
Negative values:

(-1, -3 ... -Inf)                                                        # 010

011. From Infinity to Infinity
A sequence without a specific start and end kind of works.

(-Inf .. Inf)                                                           # 011

As long as we do not try to access any values (so no, it does not really work):

say (-Inf .. Inf)[^4];   # -> (-Inf -Inf -Inf -Inf)
say (Inf ... -Inf)[^4];  # -> (Inf Inf Inf Inf)

012. Halley's Comet

Halley's Comet is visible from Earth about every 76 years. (The «about» part is caused by the gravity of other planets influencing the comet orbit.)

We can set it up as a sequence like this, if we ignore the deviation inflicted on reality by the «about» part:

(1530, 1606, 1682 ... Inf)                                              # 012

The next visit?

> say (1530, 1606, 1682 ... Inf)[^10];
(1530 1606 1682 1758 1834 1910 1986 2062 2138 2214)

Or we could specify a numeric upper limit, avoiding the lazy data structure:

> say (1530, 1606, 1682 ... 2100);
(1530 1606 1682 1758 1834 1910 1986 2062)

The upper limit is just a number. The Sequence goes on until we have reached or exceeded that limit, as shown above. Infinity is also just a number, albeit larger than anything specific.

This works out quite well, but you can confuse the reader with things like the second line below:

> say (-2, -4 ... -Inf)[^10];  # -> (-2 -4 -6 -8 -10 -12 -14 -16 -18 -20)
> say (-2, -4 ... Inf)[^10];   # -> (-2 -4 -6 -8 -10 -12 -14 -16 -18 -20)

Geometric Sequences

A Geometric Sequence is a sequence where the offset (difference between the values) increases. We get the next value by multiplying (or dividing) the previous value with a constant.

013. Double the Value
We can specifying the first three values. Raku is pretty good at detecting the Geometric sequence we have in mind:

(1, 2, 4 ... Inf)                                                       # 013a
> say (1, 2, 4 ... Inf)[^10];
(1 2 4 8 16 32 64 128 256 512)

This sequence is also the value of the binary digits, in case you should need them...

It is also possible to specify an explicit rule. In this case we do not have to, as Raku recognizes it.

(1, * * 2 ... Inf)                                                      # 013b

The * * 2 part is the rule. The first * is a placeholder, meaning the previous value. The next * is the multiplication operator, and 2 is the number two. We get the next value by multiplying the previous value with 2.

> say (1, * * 2 ... Inf)[^10];
(1 2 4 8 16 32 64 128 256 512)

014. Triple the Value
We can triple the value:

(1, 3, 9 ... Inf)                                                       # 014
> say (1, 3, 9 ... Inf)[^10];
(1 3 9 27 81 243 729 2187 6561 19683)

015. Quadruple the Value
We can quadruple the value:

(1, 4, 16 ... Inf)                                                      # 015a
> say (1, 4, 16 ... Inf)[^9];
(1 4 16 64 256 1024 4096 16384 65536)

With a rule:

(1, * * 4 ... Inf)                                                      # 015b

016. Quintuple the Value
We can quadruple the value:

(1, 5, 25 ... Inf)                                                      # 016a

With a rule:

(1, * * 5 ... Inf)                                                      # 016b

017. Sextuple the Value
We can sextuple the value:

(1, 6, 36 ... Inf)                                                      # 017a

With a rule:

(1, * * 6 ... Inf)                                                      # 017b

This goes on quite a bit, but I'll stop here.

018. Rule: *2 + 1
We can specify rules that gives Sequences that Raku cannot recognize from the pattern.

Double the previous value, and add 1:

(1, * * 2 +1 ... Inf)                                                   # 018
> say (1, * * 2 +1 ... Inf[^10];
(1 3 7 15 31 63 127 255 511 1023)

019. Rule: *2 + 2
Double the previous value, and add 2:

(1, * * 2 +2 ... Inf)                                                   # 019
> say (1, * * 2 +2 ... Inf)[^10];
(1 4 10 22 46 94 190 382 766 1534)

020. Rule: *2 - 1
Double the previous value, and subtract 1:

(1, * * 2 -1 ... Inf)                                                    # 020

The rule looks fare more impressive than the result:

> say (1, * * 2 -1 ... Inf)[^10];
(1 1 1 1 1 1 1 1 1 1)

021. Rule: *2 - 2
Double the previous value, and subtract 2:

> my @a = (1, * * 2 -2 ... Inf)                                         # 021
> say (1, * * 2 -2 ... Inf)[^10];
(1 0 -2 -6 -14 -30 -62 -126 -254 -510)

The Next Part

Part 3: Not True, or Not.