See also: The Introduction | Part 1: Raku
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.
(1 .. Inf) # 001
(0 .. Inf) # 002
-1
to -Inf
. Now we have to use
a Sequence.
(-1 ... -Inf) # 003
(0 ... -Inf) # 004
(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)
(0, 2 ... Inf) # 006
(-2, -4 ... -Inf) # 007
(0, -2 ... -Inf) # 008
(1, 3 ... Inf) # 009
(-1, -3 ... -Inf) # 010
(-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)
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)
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.
(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)
(1, 3, 9 ... Inf) # 014
> say (1, 3, 9 ... Inf)[^10];
(1 3 9 27 81 243 729 2187 6561 19683)
(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
(1, 5, 25 ... Inf) # 016a
With a rule:
(1, * * 5 ... Inf) # 016b
(1, 6, 36 ... Inf) # 017a
With a rule:
(1, * * 6 ... Inf) # 017b
This goes on quite a bit, but I'll stop here.
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)
(1, * * 2 +2 ... Inf) # 019
> say (1, * * 2 +2 ... Inf)[^10];
(1 4 10 22 46 94 190 382 766 1534)
(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)
> my @a = (1, * * 2 -2 ... Inf) # 021
> say (1, * * 2 -2 ... Inf)[^10];
(1 0 -2 -6 -14 -30 -62 -126 -254 -510)