#!perl -w # print the smallest factor of numbers in a compact table (mod 210). # run with no arguments, use built-in (slow) factoring routine. # run with any argument (value of the argument ignored), read a list # of smallest factor from stdin, e.g., pipe the output of this pari/gp # command: # for(n=2,+oo,print(n," ",factor(n)[1,1])) # Copyright 2021 Ken Takusagawa # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . $_=7; # don't need primes 2 3 5 7 because those are the factors of the modulus 210 for$l('a'..'z','A'..'Z'){ $_=&nextprime($_); $l{$_}=$l; print"$l $_\n"; } print"\n"; #numbers X such that gcd(210,X)==1 @gcdlist=qw(1 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 121 127 131 137 139 143 149 151 157 163 167 169 173 179 181 187 191 193 197 199 209 ); # global variables $modulus=2*3*5*7; $chunksize=4; $readstdin=1 if defined($ARGV[0]); &header; $spacer=0; # a complicated control structure: read a line from STDIN only if gcd(210, $x)==1 MAIN: for($x=1;;++$x){ $good=1; for$p(qw/2 3 5 7/){ $good=0 unless $x % $p; } next unless $good; $b=$x%$modulus; $a=$x-$b; die if $a%$modulus; $a/=$modulus; if(1==$b){ printf'%5d',$a; } if(1==$x){ $f=1; }elsif($readstdin){ for(;;){ last MAIN unless defined($_=); die unless ($y,$f)=/^(\d+) (\d+)$/; die if$y>$x; if($y==$x){ last; } } }else{ $f=&factor($x); } die if $x % $f; unless($spacer){ print" "; } ++$spacer; $spacer%=$chunksize; if($f==$x){ print".";#prime }else{ $_=$l{$f}; unless(defined){ $_="*"; $e.=sprintf' %02d:%d',$b,$f; } print; } if($b+1==$modulus){ if($e){ #printf'%4s%s',"",$e; print$e; undef$e; } print"\n"; $spacer=0; } } sub header { print "\\"," "x5,"mod $modulus\n"; for(my$place=100;$place>=1;$place/=10){ my$t; if(100==$place){ $t=''; }elsif(10==$place){ $t='div'; }elsif(1==$place){ $t=$modulus; }else{ die; } printf "%-5s",$t; my$spacer=0; for(@gcdlist){ if(0==$spacer){ print " "; } my$r=$_%$place; my$x=($_-$r)/$place; if($x){ print "",$x%10; }else{ print" "; } ++$spacer; $spacer%=$chunksize; } print"\n"; } } #smallest prime factor sub factor (){ my$d=shift; if($d<4){ return$d } for(my$i=2;;++$i){ if($d%$i==0){ return$i } #optimization if($i*$i>$d){ return$d;#prime } } } #strictly greater than sub nextprime(){ my$n=shift; ++$n; for(;;++$n){ if(&factor($n)==$n){ return$n }}}