# ETOOBUSY ðŸš€ minimal blogging for the impatient

# PWC104 - FUSC Sequence

**TL;DR**

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

# The challenge

Write a script to generate first 50 members of

`FUSC Sequence`

. Please refer to OEIS for more information.The sequence defined as below:

`fusc(0) = 0 fusc(1) = 1 for n > 1: when n is even: fusc(n) = fusc(n / 2), when n is odd: fusc(n) = fusc((n-1)/2) + fusc((n+1)/2)`

# The questions

My main questions here are regarding the inputs and the outputs, so theyâ€™re quite boring:

- is the input bound to be a non-negative integer?
- what is the expected output? Something to be printed or just an array?

# The solution

Weâ€™ll take a look at two solutions, just for fun. Wheeee!

The first one is quite adherent to the definition above: calculate each new
item based on the recursive formula. This does not need to be implemented
*recursively* though, a simple iteration will do:

```
sub fusc ($n) {
return [0 .. $n - 1] if $n <= 2;
my @fusc = (0, 1); # fusc(0), fusc(1)
while (@fusc < $n) {
push @fusc, $fusc[@fusc >> 1];
last if @fusc >= $n;
push @fusc, $fusc[-1] + $fusc[1 + @fusc >> 1];
}
return \@fusc;
}
```

Thereâ€™s a bit to unpack here, because itâ€™s admittedly *not* in the best
interest of the reader (I just felt like this):

- thereâ€™s no explicit index variable for tracking the item we have to add.
Adding an item in a Perl array can be done with
`push`

(so we donâ€™t need it) and its length can be taken by evaluating it in*scalar*context.*Who needs those stinking, readable variables then*?!? - Dividing by 2 in an integer way is the same as a bit shift left of one
position, which accounts for
`@fusc >> 1`

. This expression also provides the*scalar*context we need to get the number of elements in`@fusc`

, yay! - There are two ways to exit from the loop, one for even input
`$n`

and another one for odd values. Try to figure out which is which. - For odd positions, the value in position $(n - 1) / 2$ is (by definition!)
the same as the value in position $(n - 1)$, which in Perl terms
translates into
`$fusc[-1]`

As a twist, I thoughtâ€¦ why not go the other way around? I mean, all (well,
most) elements in the sequence *directly affect* three other elements. In
other terms, for *$k$ sufficiently large*, the $k$-th element affects
elements at positions $(2 k - 1)$, $2k$, and $(2k + 1)$.

There is an important caveat here, because this does not apply for *low*
values of $k$. Actually, `fusc(1)`

does indeed affect `fusc(2)`

and
`fusc(3)`

â€¦ but it *MUST NOT* not affect `fusc(1)`

ðŸ™„

All of this allows us to build a *constructive* solution from the ground up:

```
sub fusc_sieve ($n) {
my @fusc = (0, 1);
for my $i (1 .. $n >> 1) {
$fusc[$i * 2] = $fusc[$i];
$fusc[$i * 2 + 1] += $fusc[$i];
$fusc[$i * 2 - 1] += $fusc[$i];
}
$fusc[1] = 1;
return [@fusc[0 .. $n - 1]];
}
```

Again, weâ€™re using `$n >> 1`

instead of `int($n / 2)`

just to be a bit snob
and stimulate that *WTF?!?* feeling in the reader.

The `1`

-exception is taken care of in two places here:

- the most obvious one is when we (re)set the value of
`fusc(1)`

explicitly just after the loop; - the hidden one lies in the order used to updated the three affected
values. Note that the value
`$fusc[$i * 2 - 1]`

is updated lastâ€¦ this allows us to defer the vicious self-updating of the element`1`

last, so that this glitch does not affect any other element down the line.

Our last attention point is on the returned value: this method tends to
generate elements a bit generously, so we trim the output a bit when we
`return`

it.

All in all, taking this route was a fun sub-challenge, although a perilous one. Which is a lesson in itself: simpler solutions are often better for a reason.

Stay safe everyone!

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