I’ve been doing the Weekly
Challenges. The
latest
involved more mathematical tests. (Note that this is open until 17
July 2022.)
Task 1: Esthetic Number
You are given a positive integer, $n.
Write a script to find out if the given number is Esthetic Number.
I.e. each digit differs from its predecessor by 1.
When this is touched on elsewhere, the number base seems to be
important, so I wrote a base-10 wrapper. Raku:
sub esthetic10($n) {
return esthetic($n,10);
}
sub esthetic($n0,$base) {
my $n = $n0;
Set up previous digit and check flag.
my $pdigit;
my $ch = False;
while ($n > 0) {
Extract the rightmost remaining digit of the number.
my $digit = $n % $base;
If the check flag is set (which it won't be for the first time through
the loop), compare it with the previous digit, and return false if
they aren't 1 apart.
if ($ch && abs($digit - $pdigit) != 1) {
return False;
}
Set the check flag, store the digit as previous digit, and divide $n
for the next pass.
$ch = True;
$pdigit = $digit;
$n = floor($n / $base);
}
If all the tests passed, the number as a whole passes.
return True;
}
The other languages are more or less the same: some of them relegate
abs()
to a maths library.
Task 2: Sylvester's sequence
Write a script to generate first 10 members of Sylvester's sequence.
which starts with 2, and x(n+1)
is the product of x(0)
to x(n)
,
plus 1.
Which offers an optimisation, because x(n)
is itself the product of
all previous values plus 1, so we only need one multiplication per
term:
x(n+1) = x(n) * (x(n) - 1) + 1
Since the tenth value is something like 2^346, this needs some sort of
arbitrary-sized integer support. PostScript and Lua don't offer it at
all (there are various third-party libraries for Lua), so I'm not
writing code for them. Ruby, Python and Raku transparently use large
integers as needed, and Perl can be told to. JavaScript has recently
(ES2020) gained the BigInt type which just needs an "n" at the end of
the literal, and can't be readily mixed with standard integers. Kotlin
has BigInteger, which works similarly. And Rust has several options,
but num_bigint
seems to be the most widely used.
Once that's been resolved, the rest is easy. Ruby:
def sylvester(ct)
o = [ 2 ]
2.upto(ct) do
o.push(1 + (o[-1] * (o[-1] - 1)))
end
return o
end
Full code on
github.
Comments on this post are now closed. If you have particular grounds for adding a late comment, comment on a more recent post quoting the URL of this one.