See also: The Introduction | Part 1: Raku Part 2: Arithmetic and Geometric Sequences | Part 3: Not True, or Not
Adding a grep
clause using the is-prime
method
does the trick:
(1 ... Inf).grep( *.is-prime ) # 033
> say (1 ... Inf).grep( *.is-prime )[^20];
(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71)
Note that 1 is not a prime number.
(1 ... Inf).grep( *.is-prime ).map( *.chars ) # 034
> (1 ... Inf).grep( *.is-prime ).map( *.chars )[^30]
(1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3)
> say (1 ... Inf).grep( *.is-prime ).map( *.chars )[^30].Bag;
Bag(1(4) 2(21) 3(5))
We have 4 primes with 1 digit, 21 with 2 digits and 5 with 3 digits - in the sample (of 30 values).
This works as we have chosen a selection (the 30 first values) of the infinite sequence. This will not work otherwise.
A Bag is a hash variety where the keys are the numbers we add, and the values are their frequency.
We can fix this with gather
/take
:
unit sub MAIN (Int $start, Int $count = 8); # 035
my $pnl := (1 ... Inf).grep( *.is-prime ).map( *.chars );
my $pnlg := gather
{
my $count = 1;
my $current = 1;
for $pnl -> $value
{
if $value > $current
{
take $count;
$count = 1;
$current = $value;
}
else
{
$count++;
}
}
}
put $pnlg[^$count];
$ ./prime-number-length-grouping 6
(5 21 143 1061 8363 68906)
unit sub MAIN (Int $count = 20); # 036
my $primes := (1 ... Inf).grep( *.is-prime );
my $pnd := gather
{
my $prev = 0;
for $primes -> $current
{
take $current - $prev;
$prev = $current;
}
}
put $pnd[^$count];
$ ./prime-number-difference 30
2 1 2 2 4 2 4 2 4 6 2 6 4 2 4 6 6 2 6 4 2 6 4 6 8 4 2 4 2 4
A Circular Prime is a prime number where all the cyclically permutations of the number (in base 10) are also primes. E.g. 1193 is a Circular Prime, since 1931, 9311 and 3119 all are also primes.
Raku does not have a builtin function for Cyclical Permutations, but it is easy to write one.
sub cyclical-permutations ($number)
{
(1..$number.chars).map({ $number.comb.rotate($_).join });
}
Note that the original value is included at the end of the list.
(1..Inf).grep({ $_.is-prime && # 037a
all( cyclical-permutations($_)>>.is-prime ) })
> say (1..Inf).grep({ $_.is-prime &&
all( cyclical-permutations($_)>>.is-prime ) })[^20]
(2 3 5 7 11 13 17 31 37 71 73 79 97 113 131 197 199 311 337 373)
I have included the program «circular-primes» in the zip file.
We can inline the «cyclical-permutations» function:
(1..Inf).grep({ $_.is-prime && # 037b
all( (1..$_.chars).map( -> $i { $_.comb.rotate($i).join })>>.is-prime ) })
We can skip the first part, as the original value is included in the Cyclical Permutations (and will be checked for primeness anyway).
(1..Inf).grep({ # 037c
all( (1..$_.chars).map( -> $i { $_.comb.rotate($i).join })>>.is-prime ) })
A prime number p
is a
Sophie
Germain Prime if the number 2p + 1
is also a prime:
(1..Inf).grep({ $_.is-prime && ($_ * 2 + 1).is-prime }) # 038
> say (1..Inf).grep({ $_.is-prime && ($_ * 2 + 1).is-prime })[^20];
(2 3 5 11 23 29 41 53 83 89 113 131 173 179 191 233 239 251 281 293)
The primes we get from 2p + 1
in the «Sophie Germain Primes» (see above):
(1..Inf).grep({ $_.is-prime && ($_ * 2 + 1).is-prime }).map(* * 2 +1) # 039
> say (1..Inf)
.grep({ $_.is-prime && ($_ * 2 + 1).is-prime })
.map(* * 2 +1)[^20];
(5 7 11 23 47 59 83 107 167 179 227 263 347 359 383 467 479 503 563 587)
The Fibonacci Numbers is this sequence:
(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233 ...)
Raku is not capable of detecting the pattern, which is: The first value is 0, the second is 1, and all the other values are the sum of the two values to the left of it.
We can specify the rule like this:
(0, 1, * + * ... Inf) # 040a
> say (1, 1, * + * ... Inf).grep( *.is-prime )[^20];
(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181)
If you don't like the *
placeholders, named positional parameters
can be used instead - inside a {}
block:
(0, 1, { $^a + $^b } ... Inf) # 040b
(1, 1, * + * ... Inf) # 041
> say (1, 1, * + * ... Inf)[^10];
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765)
The Fibonacci Primes are the Fibonacci Numbers that are primes.
(1, 1, * + * ... Inf).grep( *.is-prime ) # 042
> say (1, 1, * + * ... Inf).grep( *.is-prime )[^10];
(2 3 5 13 89 233 1597 28657 514229 433494437)
The Leonardo Numbers are similar to the Fibonacci Numbers. The first two values are 1, and after that the value is the sum of the two values to the left of it - in addition to 1.
(1, 1, ( * + * +1 ) ... Inf) # 043
> say (1, 1, ( * + * +1 ) ... Inf)[^20];
(1 1 3 5 9 15 25 41 67 109 177 287 465 753 1219 1973 3193 5167 8361 13529)
We can compute the difference between the Leonardo and Fibonacci (1 based) Numbers; for each index, we take Leonardo - Fibonacci.
File: leonardo-vs-fibonacci
unit sub MAIN (Int $count = 10); # 044
my $fib := (1, 1, * + * ... Inf);
my $leo := (1, 1, ( * + * +1 ) ... Inf);
my $diff := gather
{
my $count = 0;
loop
{
take $leo[$count] - $fib[$count];
$count++;
}
}
say $diff[^$count];
$ ./leonardo-vs-fibonacci 20
(0 0 1 2 4 7 12 20 33 54 88 143 232 376 609 986 1596 2583 4180 6764))
The Lucas Numbers are also similar to the Fibonacci Numbers. The first two values are 2 and 1, and after that the value is the sum of the two values to the left of it.
(2, 1, ( * + * ) ... Inf) # 045
> say (2, 1, ( * + * ) ... Inf)[^20];
(2 1 3 4 7 11 18 29 47 76 123 199 322 521 843 1364 2207 3571 5778 9349)
The difference between the Lucas and Fibonacci Numbers:
File: lucas-vs-fibonacci
unit sub MAIN (Int $count = 10); # 046
my $fib := (1, 1, * + * ... Inf);
my $luc := (2, 1, * + * ... Inf);
my $diff := gather
{
my $count = 0;
loop
{
take $luc[$count] - $fib[$count];
$count++;
}
}
say $diff[^$count];
$ ./lucas-vs-fibonacci 20
(1 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584)
The difference between the Lucas and Leonardo Numbers:
File: leonardo-vs-lucas
unit sub MAIN (Int $count = 10); # 047
my $leo := (1, 1, ( * + * +1 ) ... Inf);
my $luc := (2, 1, * + * ... Inf);
my $diff := gather
{
my $count = 0;
loop
{
take $leo[$count] - $luc[$count];
$count++;
}
}
say $diff[^$count];
./leonardo-vs-lucas 20
(-1 0 0 1 2 4 7 12 20 33 54 88 143 232 376 609 986 1596 2583 4180)
The difference between the Fibonacci, Lucas and Leonardo Numbers:
File: fibonacci-lucas-leonardo
unit sub MAIN (Int $count = 10); # 048
my $fib := (1, 1, * + * ... Inf);
my $luc := (2, 1, * + * ... Inf);
my $leo := (1, 1, ( * + * +1 ) ... Inf);
my $diff := gather
{
my $count = 0;
loop
{
take $fib[$count] + $luc[$count] - $leo[$count];
$count++;
}
}
say $diff[^$count];
$ ./fibonacci-lucas-leonardo 20
(2 1 2 2 3 4 6 9 14 22 35 56 90 145 234 378 611 988 1598 2585)
The Tribonacci Numbers start with the numbers 0,0,1. After that the numbers are the sum of the three numbers to the left of it:
(0, 0, 1, { $^a + $^b + $^c } ... Inf) # 049
Placeholder *
does not work here, but we can use named placeholders.
> say (0, 0, 1, { $^a + $^b + $^c } ... Inf)[^20];
(0 0 1 1 2 4 7 13 24 44 81 149 274 504 927 1705 3136 5768 10609 19513)
The Padovan Sequence
has 1
as the first three values, and after that the values are the
sum of the two numbers before the number to the left of the current one (i.e.
skipping on number)
We have to access a third named placeholder, so that the first two get the correct values. We are ignoring the third one, by multiplying it with zero:
(1, 1, 1, { $^a + $^b + 0 * $^c } ... Inf) # 050
> say (1, 1, 1, { $^a + $^b + 0 * $^c } ... Inf)[^25];
(1 1 1 2 2 3 4 5 7 9 12 16 21 28 37 49 65 86 114 151 200 265 351 465 616)
The plus sign (+
) in the middle can be exchanged for any
other binary operator.
*
) looks nice. Or perhaps not...
(1, 2, * * * ... Inf) # 051
> say (1, 2, * * * ... Inf)[^11];
(1 2 2 4 8 32 256 8192 2097152 17179869184 36028797018963968)
**
) turns out to be a disappointment:
(1, 2, * ** * ... Inf) # 052
> say (1, 2, * ** * ... Inf)[^25];
(1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1)
-
) gives a strange looking sequence:
(0, 1, { $^a - $^b }... Inf) # 053
> say (1, 1, { $^a - $^b } ... Inf)[^20];
(1 1 0 1 -1 2 -3 5 -8 13 -21 34 -55 89 -144 233 -377 610 -987 1597)
(0, 1, { $^b - $^a }... Inf) # 054
The repeating pattern looks nice:
> say (1, 1, { $^b - $^a } ... Inf)[^20];
(1 1 0 -1 -1 0 1 1 0 -1 -1 0 1 1 0 -1 -1 0 1 1)
> (1, 2, * max * ... Inf) # 055
The definition looks more impressive than the result:
> say (1, 2, * max * ... Inf)[^10];
(1 2 2 2 2 2 2 2 2 2)
(1, 2, * / * ... Inf) # 056
> say (1, 2, * / * ... Inf)[^10]
(1, 2, 0.5, 4, 0.125, 32, 0.003906, 8192, 0.00000048, 17179869184)
This essentially gives us two sequences; the values with even indices are counting down towards zero, and the ones with odd indices are counting up towards infinity. But the values depend on each other, so we cannot split the sequence in two.