正整数のゲーデル数化?
Posted feedbacks - Perl
もうちょっと簡単に出来そう
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | use strict;
use warnings;
use Math::Prime::XS qw(is_prime);
use List::Util qw(reduce);
use List::MoreUtils qw(pairwise);
sub primes {
my $number = shift;
my @primes = (2);
my $i = 3;
while ( @primes < $number ) {
push( @primes, $i ) if is_prime($i);
$i++;
}
return @primes;
}
sub goedel {
my $number = shift;
my @num = split //, $number;
my @primes = primes( scalar(@num) );
reduce { $a * $b } pairwise { $a**$b } @primes, @num;
}
print goedel(9);
print goedel(81);
print goedel(230);
|
goedel_number()の二番目の引数にnonzeroを指定することで#4657で指摘した「仕様バグ」にも対応しています。
Dan the Goedel Numberer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #!/usr/local/bin/perl
use strict;
use warnings;
my @primes = ( 2, 3 );
sub fill_primes {
my $nprimes = shift;
ODD:
for ( my $n = $primes[ @primes - 1 ] + 2 ; @primes < $nprimes ; $n += 2 ) {
for my $d (@primes) {
last if $d * $d > $n;
next ODD unless $n % $d;
}
push @primes, $n;
}
}
sub goedel_number {
my $n = shift;
my $offset = shift || 0;
my @d = ( $n =~ /(\d)/g );
fill_primes( scalar @d );
use bigint;
my $result = 1;
$result *= $primes[$_]**( $d[$_] + $offset ) for ( 0 .. @d - 1 );
$result;
}
local $\ = "\n";
local $, = ", ";
print goedel_number( $ARGV[0] || 1234567890, $ARGV[1] );
|


nobsun
#4420()
Rating2/2=1.00
see: ゲーデル数
[ reply ]