See also: The Introduction | Part 1: Raku Part 2: Arithmetic and Geometric Sequences | Part 3: Not True, or Not | Part 4: Primes and Fibonacci | Part 5: Divisors and Factors | Part 6: Binary and Palindrome | Part 7: Every Tom, Dick, and Harry
The Look-and-Say Sequences are formed by splitting the previous number into blocks of the same digit, and reading them out: «999 🡲 3 of 9 🡲 39».
An example:
1
.
1
as input. We have one of that digit (one of
one; one one), so the result is 11
11
as input. We have two of that digit (two of
one; two one), so the result is 21
2
and 1
as input. We have one of
the first digit (one of two; one two), and one of the second digit (one of one; one
one), so the result is 1211
This is suitable for a program:
File: look-and-say
unit sub MAIN (Int $start = 1, Int $limit = 10);
my @look-and-say = ($start, { look-and-say($_) } ... Inf);
say @look-and-say[^$limit];
sub look-and-say ($input)
{
my $return = "";
for $input.comb: / (.) $0* / -> $batch
{
$return ~= $batch.chars ~ $batch.substr(0,1);
}
return $return;
}
The start value is the first argument, and the number of values to print is the second.
The canonical Look-and-Say Sequence starts with the value 1
:
$ ./look-and-say 1 8 # 096
(1 11 21 1211 111221 312211 13112221 1113213211)
2
:
$ ./look-and-say 2 8 # 097
(2 12 1112 3112 132112 1113122112 311311222112 13211321322112)
The OEIS Foundation, which collect sequences for a living, has given this one the ID A006751.
3
:
$ ./look-and-say 3 8 # 098
(3 13 1113 3113 132113 1113122113 311311222113 13211321322113)
> put ('A' .. 'Z');
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
> my $a = 'A'; $a++; say $a; # -> B
The uppercase latin letters are used as «digits». Carrying is supported:
> my $a = 'Z'; $a++; say $a;
AA
The sentient computer «HAL» in the classic 1968 movie 2001: A Space Odyssey is a play on «IBM».
Let us have a go at morphing «HAL» into «IBM»:
('HAL' ... 'IBM') # 099a
> say ('HAL' ... 'IBM');
(HAL HAM HBL HBM IAL IAM IBL IBM)
> say ('HAL' ... 'IBM').elems;
8
Oops!
If we specify a specific upper limit, as done here, the character at that position will not iterate to a higher value than the one specified (nor lower). So the legal digits, from the left are: H and I, A and B, L and M.
If you want the scenic detour using all the uppercase letters, use an infinite sequence like this:
('HAL' ... Inf)[^704] # 099b
> say ('HAL' ... Inf)[703];
IBM
This infinite sequence treats the letters [A-Z] as the base digits (so to speak), and 'HAL' and 'IBM' are numbers in a base 26 number system. Except that the concept of zero is missing, so be careful if trying to use them as numbers.
We can use the succ
(successor) method to get the explicit next value:
> say 'ABZ'.succ; # -> ACA
The number 703 is the result of trial and error.
Or we can write a program:
File: text-seq-diff
unit sub MAIN (Str $from, Str $to);
say $to.comb.reverse.map({ $_.ord - 'A'.ord })
.map({ state $exp = 0; $_ * 26 ** $exp++ }).sum -
$from.comb.reverse.map({ $_.ord - 'A'.ord })
.map({ state $exp = 0; $_ * 26 ** $exp++ }).sum;
$ ./text-diff HAL IBM
703
It works the other way round as well, but the result will be negative:
$ ./text-seq-diff IBM HAL
-703
If you are more interested in current American life, consider this one:
('TRUMP' ... 'BIDEN') # 100a
> say ('TRUMP' ... 'BIDEN').elems;
92340
$ ./text-seq-diff BIDEN TRUMP
8395454
('TRUMP' ... Inf)[^8395455] # 100b
> say ('TRUMP' ... Inf)[8395454];
BIDEN
Note that the last one takes a long time to compute; about 9.5 minutes on my pc.
92340 is the Zip code for the city of Hesperia in San Bernadino County, outside Los Angeles in California.
But 8303114 (8395454 - 92340) is more interesting. It is the official US Gene ID of the «Bacillus subtilis subsp. subtilis str. 168» bacteria. Not COVID-19, not even a virus, but nevertheless...
And that's it; 100 Sequences…