# ETOOBUSY ðŸš€ minimal blogging for the impatient

# PWC191 - Cute List

**TL;DR**

On with TASK #2 from The Weekly Challenge #191. Enjoy!

# The challenge

You are given an integer,

`0 < $n <= 15`

.Write a script to find the number of orderings of numbers that form a cute list.

With an input

`@list = (1, 2, 3, .. $n)`

for positive integer`$n`

, an ordering of`@list`

is cute if for every entry, indexed with a base of 1, either`1) $list[$i] is evenly divisible by $i or 2) $i is evenly divisible by $list[$i]`

Example`Input: $n = 2 Ouput: 2 Since $n = 2, the list can be made up of two integers only i.e. 1 and 2. Therefore we can have two list i.e. (1,2) and (2,1). @list = (1,2) is cute since $list[1] = 1 is divisible by 1 and $list[2] = 2 is divisible by 2.`

# The questions

I guess the input says it all (apart, maybe, what is an *ordering of a
list*, but it seems pretty clear).

# The solution

The brute force approach in this case would have us enumerate all possible permutations and filter the ones that comply with the definition.

Problem is that the number of permutations *literally* goes factorially
with the number of items. That is, a starting list with 15 items would
include $15! = 1307674368000 \approx 1.31 \cdot 10^{12}$ permutations,
which is *a tad too many*.

On the other hand, itâ€™s possible to do a lot of pruning in our search by
considering that anything of the type `x 3 y z ...`

is not going
anywhere, because neither 2 divides 3, nor the contrary. Hence, thereâ€™s
no point considering all those permutations (or generating them, for
what matters).

This leads us to the following recursive implementation, which bails out early as soon as it finds something fishy, avoiding to expand all sub-permutations that are not worth the effort.

```
#!/usr/bin/env perl
use v5.24;
use warnings;
use experimental 'signatures';
no warnings 'experimental::signatures';
say cute_list(shift // 2);
sub cute_list ($n) {
state sub cute_list_r ($count, $i, @items) {
++$count unless @items;
my @pre = ();
while (@items) {
my $v = shift @items;
if (! ($v % $i && $i % $v)) {
$count = __SUB__->($count, $i + 1, @pre, @items);
}
push @pre, $v;
}
return $count;
};
cute_list_r(0, 1, 1 .. $n);
}
```

Itâ€™s been an interesting occasion to use Lexical Subroutines! And
`__SUB__`

!

The same approach can be easily translated in Raku:

```
#!/usr/bin/env raku
use v6;
sub MAIN (Int $n where 0 < * <= 15 = 2) { put cute-list($n) }
sub cute-list ($n) {
sub cute-list-r ($count is copy, $i, *@items) {
++$count unless @items;
my @pre;
while @items {
my $v = @items.shift;
if ($v %% $i) || ($i %% $v) {
$count = cute-list-r($count, $i + 1, @pre.Slip, @items.Slip);
}
@pre.push: $v;
}
return $count;
};
return cute-list-r(0, 1, 1 .. $n);
}
```

Stay safe!

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