use strict;
use warnings;
use feature 'say';

sub evil {
    my $i = 0;
    sub { $i++ while population_count($i) % 2; $i++ }
}

sub odious {
    my $i = 0;
    sub { $i++ until population_count($i) % 2; $i++ }
}

sub population_count { 
    my $n = shift;
    my $c;
    for ($c = 0; $n; $n >>= 1) { $c += $n & 1 } 
    $c
}

say join ' ', map { population_count 3**$_ } 0 .. 30 - 1;

my (@evil, @odious);
my ($evil, $odious) = (evil, odious);
push( @evil, $evil->() ), push @odious, $odious->() for 1 .. 30;

say "Evil   @evil";
say "Odious @odious";