I’ve been doing the Weekly
Challenges. The
latest
involved lots of number-string conversions. (Note that this is open
until 7 August 2022.)
Task 1: Permuted Multiples
Write a script to find the smallest integer x such that x, 2x, 3x,
4x, 5x and 6x are permuted multiples of each other.
Which the old hand will immediately recognise as 142857
, but let's
pretend we don't know that and work it out from first principles.
My approach is to build a function which will depermute a number, to
either a sorted string or a sorted array. Which of those I use depends
on the language: some can't readily compare the contents of arrays,
others can't readily sort the contents of strings. (And some can only
sort in place rather than returning a sorted copy.) Calculate the
value of that function for each candidate, and check that each
multiple of the candidate also matches.
Kotlin:
fun permutable(): Int {
var n = 0
while (true) {
n += 1
Here's the important bit:
val base = n.toString().toCharArray().toList().sorted()
so 142857
will become [ "1", "2", "4", "5", "7", "8" ]
.
Then I just compare each multiple, bailing out on a non-match.
var q = true
for (k in 2..6) {
val tt = (n*k).toString().toCharArray().toList().sorted()
if (tt != base) {
q = false
break
}
}
if (q) {
return n
}
}
}
Task 2: Reversible Numbers
Write a script to find out all Reversible Numbers below 100.
A number is said to be a reversible if sum of the number and its reverse had only odd digits.
So again the crunchy bit is reversing the number, which means
converting it to a string, maybe converting that to an array,
reversing the elements, and going back up the chain to get a number.
At least in the typed languages! While I do get irked by the Perl/Raku
approach to typing, it does make this very easy. In Raku here:
sub reversible($mx) {
my @o;
for (1..$mx) -> $n {
That flip
and sloppy typing together are doing a lot of work,
anchored by +
being a numerical operator (versus ~
for string
concatenation).
my Int $t = $n + flip($n);
Then we just check for no even digits, which could be a regex but I
did it this way instead because it's more portable across the other
languages. Check whether the last digit is even; if not, divide by ten
dropping remainder.
my Bool $q = True;
while ($t > 0) {
if ($t % 2 == 0) {
$q = False;
last;
}
$t div= 10;
}
if ($q) {
@o.push($n);
}
}
return @o;
}
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.