这是一个实现多种特征数筛选的perl脚本,有点意思。
主要功能如下:
1.给定一个整数范围,筛选其中的素数;
2.分析给定的数字是否为素数;
3.筛选给定数范围内的梅森素数;
4.获取两个或多个数的最大公约数和最小公倍数;
5.获取给定范围的孪生素数;
6.求排列公式值;
7.求组合公式值;
8.获得二项式系数,展示杨辉三角;
9......
#! /usr/bin/perl -w
=head1 name
obtain_some_special_integer.pl
=head1 Description
1.get the prime numbers from the given range;
2.check the given number whether it is a prime number or not;
3.get the special range mersenne prime numbers;
4.get max common divisor and min multiple between the given two numbers or more;
5.get the twin prime numbers from the given range;
6.get the max number of permutations;
7.get the max number of combinations;
8.get the binomial coefficients;
9.to be expected......
=head1 Version
Original from: li Xiangfeng,xflee0608@163.com
Version: 2.4, Date: 2014-3-8
=head1 usage
perl obtain_some_special_integer.pl [options]
-p, --prime <int> The range from which you want to obtain prime numbers ,must be a pair arguments;
-c, --check <int> Input a number you want to check whether it is a prime number or not;
-m, --mersenne <int> The range you want to grep mersenne prime numbesr ,range from 2 to the number you give;
-d, --div <int> Input the two number,you will get theirs max common divisor number and min multiple number.you must be a pair arguments;
-t, --twin <int> The range from which you want to obtain twin prime numbers ,must be a pair arguments;
-per,--permutation <int> Get the max number of permutations;
-com,--combination <int> Get the max number of combinations;
-n, --binomial <int> Get the binomial coefficients;
-h, --help Print help info;
-v, --version Print script info.
=head1 Example
perl obtain_some_special_integer.pl -p 1 -p 100 #grep prime numbers from 1 to 100;
perl obtain_some_special_integer.pl -c 986 #check 986's attribute;
perl obtain_some_special_integer.pl -m 600000 #grep mersenne prime numbers from 2 to 600000;
perl obtain_some_special_integer.pl -d 24 -d 36 #get max common divisor number and min multiple number of 24 and 36;
perl obtain_some_special_integer.pl -t 1 -t 100 #grep twin prime numbers from 1 to 100;
perl obtain_some_special_integer.pl -per 5 -per 3 #get the max number of permutations when you fetch 3 samples from 5;
perl obtain_some_special_integer.pl -com 5 -com 3 #get the max number of combinations when you fetch 3 samples from 5;
perl obtain_some_special_integer.pl -n 10 #get the binomial coefficients when index n equal 5;
=cut
my $heredoc =<<USAGE;
Original from: li Xiangfeng,xflee0608\@163.com.
Version: 2.4, Date: 2014-3-8.
USAGE
use strict;
use Getopt::Long;
my (@num,$n,$mersenne,@div,@twin,@per,@com,$bino,$help,$version);
GetOptions(
"prime|p:i"=>\@num,
"check|c:i"=>\$n,
"mersenne|m:i"=>\$mersenne,
"div|d:i"=>\@div,
"twin|t:i"=>\@twin,
"permutation|per:i"=>\@per,
"combination|com:i"=>\@com,
"binomial|n:i"=>\$bino,
"help|?" =>\$help,
"version|v"=>\$version,
);
die `pod2text $0` if($help);
die `pod2text $0` unless(@num||$n||$mersenne||@div||@twin||@per||@com||$bino||$version);
die "$heredoc" if($version);
##grep prime number list##
my $num_count=@num;
if($num_count==2){
my @result_grep=&prime(@num);
if($num[0]<$num[1]){
print $_,"\n" foreach @result_grep;
}else{print $_,"\n" foreach sort{$b<=>$a}@result_grep;}
}elsif($num_count==1){
die "please input the correct argument:\n e.g.: -p 1 -p 100\n";
}
##check the given number whether it is a prime number or not##
if($n){
my @set=&check($n);
print "$n is a prime number!\n" if(scalar@set==2);
print "$n is a not composite number,and also not a prime number!\n" if(scalar@set==1);
if(scalar@set>2){
my $j=1;
print"$n is a composite number!\n$n can be exactly divided by these numbers as follows:\n";
foreach(@set){
printf "%12s",$_;
print "\n" if($j%3==0);
$j++;
}
print "\n" if($j%3!=1);
my $num=$n;
my $quotient;
my @grep=grep{scalar&check($_)==2}@set;
my $product=1;
$product*=$_ foreach @grep;
my $check_will=$num/$product;
my @out=@grep;
unless($check_will==1){
my @prime_set=&prime(2,$check_will);
for(my $i=0;;$i++){
if(scalar&check($check_will)==2){
push @out,$check_will;
last;
}
last if(!@prime_set);
my $div=$prime_set[0];
if($check_will % $div==0){
push @out,$div;
$quotient=$check_will/$div;
if(scalar&check($quotient)==2){
push @out,$quotient;
last;
}
$check_will=$quotient;
}else{shift @prime_set}
}
}
my $result;
print "\n";
$result.="$_*" foreach sort{$a<=>$b}@out;
chop$result;
print "$n=$result\n";
}
}
##grep mersenne prime number##
if($mersenne){
my @prime_set=&prime(2,$mersenne);
my %ha=map{$_=>1}@prime_set;
for(my $i=2;;$i++){
my $num=2**$i-1;
print "$num is the mersenne prime;\n$num=2**$i-1;\n" if(exists $ha{$num} && exists $ha{$i});
last if($num>=$prime_set[-1]);
}
}
##get max common divisor and min multiple##
my $div_count=@div;
if($div_count==2){
my $result_div=&max_common_divisor_min_multiple(@div);
}elsif($div_count>=3){
my $result_div=&max_common_divisor_min_multiple_more(@div);
}elsif($div_count==1){ die "please input the correct argument:\n e.g.: -d 24 -d 36\n";}
##grep twin prime number list##
my $twin_count=@twin;
if($twin_count==2){
my @prime_grep=&prime(@twin);
my @prime_twin;
for(my $i=1;$i<@prime_grep;$i++){
my $out=$prime_grep[$i]-$prime_grep[$i-1];
if($out==2){
push @prime_twin,$prime_grep[$i],$prime_grep[$i-1];
print "($prime_grep[$i-1],$prime_grep[$i])\n";
}
}
}elsif($twin_count==1 || $twin_count>=3){ die "please input the correct argument:\n e.g.: -t 1 -t 100\n";}
##get max permutation number##
if(scalar@per==2){
my ($n,$m)=@per;
if($n>=$m){
my $result_per=&fac($n)/&fac($m);
print "The result of P($n,$m) is :$result_per\n";
}else{die "please make sure the correct input!"}
}elsif(scalar@per==1){ die "please input the correct argument:\n e.g.:-per 5 -per 3\n";}
##get max permutation number##
if(scalar@com==2){
my ($n,$m)=@com;
if($n>=$m){
my $result_com=&fac($n)/(&fac($m)*(&fac($n-$m)));
print "The result of C($n,$m) is :$result_com\n";
}else{die "please make sure the correct input!"}
}elsif(scalar@com==1){ die "please input the correct argument:\n e.g.:-com 5 -com 3\n";}
##get binomial coefficient##
if($bino){
for(my $i=0;$i<$bino;$i++){
my $out=&fac($bino-1)/(&fac($i)*(&fac($bino-$i-1)));
print "$out," if($i<$bino-1);
print "$out\n" if($i==$bino-1);
}
for(my $i=1;$i<=$bino;$i++){
print " " x (3*($bino-$i));
for(my $j=0;$j<$i;$j++){
my $out=&fac($i-1)/(&fac($j)*(&fac($i-$j-1)));
printf "%5s ", $out;
}
print "\n";
}
}
##sub##
sub prime{
my ($start,$end)=sort{$a<=>$b}@_;
my @set;
for(my $i=$start;$i<=$end;$i++){
push @set,$i if($i==2);
push @set,$i if($i==3);
next if($i%6!=1 && $i%6!=5);
my $flag=1;
for(my $j=3;$j<=$i/2;$j+=2){
if($i%$j==0){
$flag=0;
last;
}
}
push @set,$i if($flag && $i>1);
}
return @set;
}
##sub##
sub check{
my $num=shift@_;
my @p;
for(my $i=1;$i<=$num;$i++){
if($num % $i==0){
push @p,$i;
}
}
return @p;
}
##sub##
sub max_common_divisor_min_multiple{
my ($num1,$num2)=@_;
my (@p,@q);
for(my $i=1;$i<=$num1;$i++){
if($num1 % $i==0){
push @p,$i;
}
}
for(my $j=1;$j<=$num2;$j++){
if($num2 % $j==0){
push @q,$j;
}
}
my %hash;
my @inter=grep{$hash{$_}++>0}@p,@q;
@inter=sort{$b<=>$a}@inter;
print "$inter[0] is $num1 and $num2 's max commom divisor\n";
print $num1*$num2/$inter[0]," is $num1 and $num2 's min commom multiple\n";
}
##sub##
sub max_common_divisor_min_multiple_more{
my @p=@_;
my $flag=0;
my $out=0;
foreach(my $i=0;;$i++){
my %ha;
my @q=grep{$ha{$_}++<1}@p;
if(scalar@q==1){
$out=$q[0];
print "$out\n";
last;
}
@q=sort{$a<=>$b}@q;
my $num=shift@q;
if($num==1){
$flag=1;
last;
}
my @k;
foreach(@q){
push @k,($_-$num);
}
push @k,$num;
@p=@k;
}
if($flag){
print "max division is 1\n";
}else{print "max division is $out\n"}
}
##sub##
sub fac{
my ($a)=@_;
my $out=1;
for(my $i=1;$i<=$a;$i++){
$out*=$i;
}
return $out;
}
my @timelst=times;
print "\n##########\n";
print "Elapsed time:\n";
print "User:$timelst[0] seconds.\n";
print "System:$timelst[1] seconds.\n";
print "##########\n";
__END__