*This post is part of a series on Mohammad Anwar’s excellent Weekly Challenge, where hackers submit solutions in Perl, Raku, or any other language, to two different challenges every week. (It’s a lot of fun, if you’re into that sort of thing.)*

Task #2 this week comes to us from Robert DiCicco, and Robert demands happiness! Or at least numbers that are happy. Either way, I could use some right about now.

We are to find the first 8 Happy Numbers in base 10. To test whether a number is Happy:

replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1.

Weekly Challenge #164

Those numbers for which this process end in 1 are happy numbers, while those numbers that do not end in 1 are unhappy numbers.

## If You’re Happy and You Know It `return 1`

Using the algorithm exactly as described above, the Perl code is straightforward:

```
sub is_happy(_) {
my $n = shift;
my %seen;
for (my $c = $n; $c != 1; $c = sum map { $_*$_ } split //, $c) {
return if $seen{$c}++;
}
return 1
}
```

`$_ * $_`

is an optimization I make reflexively. Computing powers (i.e., `$_ ** 2`

), even for integers, is relatively slow (~15% on my VM), so for squaring a number, I often write out the multiplication by hand. It’s faster and does not suffer any real lack of clarity.

I achieve the loop detection with the `%seen`

hash. If a number comes up more than once, we are in a loop. We keep computing the sum of squares of the digits and stop when we detect a loop (Not Happy), or when we reach 1 (Happy).

## Outputting the First `$count`

Happy Numbers

Our job would be a little easier if we were asked to output numbers below a given limit. But outputting the first *n* is not much harder. We’ll just loop until we’ve seen `$count`

Happy numbers:

```
my $count = pop // 8;
# Output the first $count Happy Numbers
for (local $_ = 1; $count > 0 ; $_++) {
next unless is_happy;
say;
$count--;
}
```

The highlighted line gives us an increasing number (`$_`

), but the loop termination condition depends on another variable (`$count`

). As much as we love our `foreach`

-style loops, sometimes the good old fashioned C-style `for ( ; ; )`

loop is best!

I decided to prototype `is_happy(_)`

for a bit of syntactic sugar. This was completely unnecessary, of course.

My complete solutions are on GitHub.

That’s it for Week #164! Tune in next week for some fun with graphics…