ETOOBUSY 🚀 minimal blogging for the impatient
PWC173 - Esthetic Number
TL;DR
Here we are with TASK #1 from The Weekly Challenge #173. Enjoy!
The challenge
You are given a positive integer,
$n
.Write a script to find out if the given number is
Esthetic Number
.An esthetic number is a positive integer where every adjacent digit differs from its neighbour by 1.
For example,
5456 is an esthetic number as |5 - 4| = |4 - 5| = |5 - 6| = 1 120 is not an esthetic numner as |1 - 2| != |2 - 0| != 1
The questions
There might be some nit-picking here: which base to consider? It would be a moot question, though, because there’s still ample space for a base-2 number to NOT be esthetic (think ‘11`, for example), so there is no outsmarting our fine host here.
The other question I would have asked a long time ago would be the output format. I came from experiences in which my output would have been tested against some reference; here, though, there’s the pleasure of cracking challenges without the annoyance of getting the exact result as initially thought. I see this as an application of TIMTOWTDI spirit.
The solution
We’ll have to compare adjacent pairs of digits, so I thought to toss in some generalization and code a function to perform generic tests on adjacent pair of elements in an array. Raku:
sub test-adjacents (&test, *@input) {
for 1 ..^ @input -> $i {
return False unless &test(|@input[$i - 1, $i]);
}
return True;
}
Perl:
sub test_adjacents ($test, @input) {
for my $i (1 .. $#input) {
return 0 unless $test->(@input[$i - 1, $i]);
}
return 1;
}
At this point, it’s just a matter of feeding these functions with the right inputs, i.e. a test function and the list of digits. Raku:
#!/usr/bin/env raku
use v6;
sub MAIN (*@candidates) {
put is-esthetic($_) ?? "$_ is esthetic" !! "$_ is NOT esthetic"
for @candidates;
return 0;
}
sub is-esthetic ($candidate) {
test-adjacents(-> $x, $y { abs($x - $y) == 1 }, $candidate.comb());
}
Perl:
#!/usr/bin/env perl
use v5.24;
use warnings;
use experimental 'signatures';
no warnings 'experimental::signatures';
say is_esthetic($_) ? "$_ is esthetic" : "$_ is NOT esthetic"
for @ARGV;
sub is_esthetic ($candidate) {
test_adjacents(
sub ($x, $y) { use integer; abs($x - $y) == 1 },
split m{}mxs, $candidate
);
}
I tried to look for something already baked into Raku, but without much luck. I’m curious to look at others’ solutions!
Stay safe and change the right amount every day!