RabbitFarm

2022-03-20

Persnickety Pernicious and Weird

The examples used here are from The Weekly Challenge problem statement and demonstrate the working solution.

Part 1

Write a script to generate the first 10 Pernicious Numbers.

Solution


use strict;
use warnings;

use Math::Primality qw/is_prime/;

sub count_bits{
    my($n) = @_;
    my $total_count_set_bit = 0;
    while($n){
        my $b = $n & 1;
        $total_count_set_bit++ if $b;
        $n = $n >> 1;
    }
    return $total_count_set_bit;
}

sub first_n_pernicious{
    my($n) = @_;
    my @pernicious;
    my $x = 1;
    do{
        my $set_bits = count_bits($x);
        push @pernicious, $x if is_prime($set_bits);
        $x++;
    }while(@pernicious < $n);
    return @pernicious;
}

MAIN:{
    print join(", ", first_n_pernicious(10)) . "\n";
}

Sample Run


$ perl perl/ch-1.pl
3, 5, 6, 7, 9, 10, 11, 12, 13, 14

Notes

Number Theory was one of my favorite classes as an undergraduate. This sort of challenge is fun, especially if you dive into the background of these sequences and try to learn more about them. Computing them is fairly straightforward, especially here where the two functions are largely drawn from past TWCs.

Part 2

You are given number, $n > 0. Write a script to find out if the given number is a Weird Number.

Solution


use strict;
use warnings;

use boolean;
use Data::PowerSet q/powerset/;

sub factor{
    my($n) = @_;
    my @factors = (1);
    foreach  my $j (2 .. sqrt($n)){
        push @factors, $j if $n % $j == 0;
        push @factors, ($n / $j) if $n % $j == 0 && $j ** 2 != $n;
    }
    return @factors;  
}

sub is_weird{
    my($x) = @_;
    my @factors = factor($x); 
    my $sum = unpack("%32I*", pack("I*",  @factors));
    for my $subset (@{powerset(@factors)}){
        return false if unpack("%32I*", pack("I*",  @{$subset})) == $x;
    }  
    return boolean($sum > $x);
}

MAIN:{
    print is_weird(12) . "\n";
    print is_weird(70) . "\n";
}

Sample Run


$ perl perl/ch-2.pl
0
1

Notes

This task kind of bothered me, not because of the complexity of the task itself; the code was overall not extremely demanding. Rather anytime when I want to make use of Data::PowerSet I get a bit anxious that there may be a far more elegant way of proceeding! After coming up blank on alternatives I just went with this, but I'll probably still have this in the back of my mind for a few more days.

References

Challenge 156

Pernicious Number

Weird Number

posted at: 18:29 by: Adam Russell | path: /perl | permanent link to this entry