Project Euler 87
ストレートにx^2 + y^3 + z^4を総当りでとけばよい。
どうせそれぞれの変数に入る素数の値候補は多くは無いので、
最初にリストにしてしまって、リストの3重ループで回す。
当然xのとりうる範囲は50000000の平方根より少ない。
yのとりうる範囲は50000000の立方根より少ない。
zのとりうる範囲は50000000の4乗根より少ない。
#project euler 87 use strict; use warnings; use POSIX qw( ceil ); sub isprime{ my $target = $_[0]; return 0 if( $target <= 1 ); return 1 if( $target == 2 ); return 0 if( $target % 2 == 0 ); for( my $i = 3; $i <= ceil( sqrt( $target ) ); $i+=2 ){ if( $target % $i == 0){ return 0; } } return 1; } sub get_primearray{ my $limit = $_[0]; my @prime; return 0 if ( $limit < 1 ); foreach( 1..$limit){ if( isprime( $_ ) == 1 ){ push( @prime, $_ ); } } return @prime; } my $limit = 50000000; my $sq_lim = ceil( $limit ** ( 1 / 2) ); my $cb_lim = ceil( $limit ** ( 1 / 3) ); my $fr_lim = ceil( $limit ** ( 1 / 4) ); print "square : calcurate to $sq_lim\n"; print "cube : calcurate to $cb_lim\n"; print "forth power : calcurate to $fr_lim\n"; my @sqarr = get_primearray( $sq_lim ); my @cbarr = get_primearray( $cb_lim ); my @frarr =get_primearray( $fr_lim ); my %expr; print "for sqare : @sqarr\n"; print "for cube : @cbarr\n"; print "for fourth power : @frarr\n"; foreach my $x(@sqarr){ foreach my $y( @cbarr ){ foreach my $z( @frarr ){ my $key = $x ** 2 + $y ** 3 + $z ** 4; if( $key >= $limit ){ next; } else { $expr{$key} = 1; } } } } my $count = keys( %expr ); print "$count\n";
このあたりの問題の難易度差が激しい気がする。