# ETOOBUSY ðŸš€ minimal blogging for the impatient

# PWC107 - Self-descriptive Numbers

**TL;DR**

Here we are with TASK #1 from the Perl Weekly Challenge #107. Enjoy!

# The challenge

Write a script to display the first three self-descriptive numbers. As per wikipedia, the definition of Self-descriptive Number is

In mathematics, a self-descriptive number is an integer m that in a given base b is b digits long in which each digit d at position n (the most significant digit being at position 0 and the least significant at position bâˆ’1) counts how many instances of digit n are in m.

# The questions

My first question is about *what do we mean by the first three*? Is the
ordering following from the ascending ordering of the bases, followed by
some kind of ascending order for the numbers in each base?

Another question - this quite *meta*, I admit - wasâ€¦ *didnâ€™t I already
solve this?*. Sure, this is a repeated challengeâ€¦ but I wasnâ€™t
participating into the challenge as of PWC 43, so there had to be something
different.

And last another *meta* question - what are these challenges about? I mean,
what does it mean to *win* the challenge? Is it the fastest to code a
solution? A working solution, or any solution? I admit that I didnâ€™t find
anything to this regard (although I do the challenge for the pure fun of
doing it and learn something).

# The solution

It turns out that I did *indeed* solve a *generalization* of the problem.
About one year ago, I started my Autobiographical Numbers series as a
way to apply a small library about Constraint Programming.

And no, I will not inflict you with another series on the same topic.

This time Iâ€™ll leverage on the fact that only three numbers are requested, and that I hope (/know) that this will only involve little bases. Hence, a brute force attack will do:

```
#!/usr/bin/env perl
use 5.024;
use warnings;
use experimental qw< postderef signatures >;
no warnings qw< experimental::postderef experimental::signatures >;
use List::Util 'sum';
sub nested_loops_iterator {
my ($dims, $opts, $cb, $accumulator) = @_;
return unless scalar @{$dims};
($opts, $cb) = ($cb, $opts) if ref($opts) eq 'CODE';
my @indexes = (-1);
my @accumulator = (undef) x scalar @{$dims};
return sub {
while ((my $level = $#indexes) >= 0) {
my $dimension = $dims->[$level];
my $i = ++$indexes[$level];
if ($i > $#{$dimension}) { pop @indexes }
else {
$accumulator[$level] = $dimension->[$i];
if ($level == $#{$dims}) { return @accumulator }
else { push @indexes, -1 }
}
}
return;
}
}
sub is_self_descriptive (@sequence) {
for my $i (0 .. $#sequence) {
my $count = sum map { $_ == $i ? 1 : 0 } @sequence;
return unless $count == $sequence[$i];
}
return 1;
}
sub three_self_descriptive_numbers {
my ($b, @found) = (1);
while ('necessary') {
my $it = nested_loops_iterator([map { [0 .. ($b - 1)]} 1 .. $b]);
while (my @args = $it->()) {
push @found, join '', @args if is_self_descriptive(@args);
return @found if @found == 3;
}
++$b;
}
return @found[0..2];
}
say join(', ', three_self_descriptive_numbers());
```

Iâ€™m probably killing a mosquito with a cannon, but I had the cannon in the backyard and soâ€¦ why not?

We iterate through the bases and then through the values, looking for numbers that comply. As soon as we find three of them we exitâ€¦ so itâ€™s brute force with a hearth!

Stay safe people!

*Comments? Octodon, Twitter, GitHub, Reddit, or drop me a line!*