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.