use utf8;
use strict;
use warnings;
use feature 'say';
use List::Util 'uniq';

sub prime_factors {
    my ($n, $d, @factors) = (shift, 1);
    while ($n > 1 and $d++) {
        $n /= $d, push @factors, $d until $n % $d;
    }
    @factors
}

sub  {
    my @p = prime_factors(shift);
    @p == uniq(@p) ? 0 == @p%2 ? 1 : -1 : 0
}

sub progressive_sum {
    my @sum = shift @_;
    push @sum, $sum[-1] + $_ for @_;
    @sum
}

my($upto, $show, @mebius) = (1000, 199, ());
push @mebius, ($_) for 1..$upto;
my @mertens = progressive_sum @mebius;

say "Mertens sequence - First $show terms:\n" .
    (' 'x4 . sprintf "@{['%4d' x $show]}", @mertens[0..$show-1]) =~ s/((.){80})/$1\n/gr .
    sprintf("\nEquals zero%3d times between 1 and $upto", scalar grep { ! $_ } @mertens) .
    sprintf "\nCrosses zero%3d times between 1 and $upto", scalar grep { ! $mertens[$_-1] and $mertens[$_] } 1 .. @mertens;