A-M baby
This commit is contained in:
parent
764da6cbbb
commit
db842d013d
19005 changed files with 197040 additions and 7 deletions
8
Task/Modular-exponentiation/0DESCRIPTION
Normal file
8
Task/Modular-exponentiation/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
Find the last 40 decimal digits of <math>a^b</math>, where
|
||||
|
||||
* <math>a = 2988348162058574136915891421498819466320163312926952423791023078876139</math>
|
||||
* <math>b = 2351399303373464486466122544523690094744975233415544072992656881240319</math>
|
||||
|
||||
A computer is too slow to find the entire value of <math>a^b</math>. Instead, the program must use a fast algorithm for modular exponentiation: <math>a^b \mod m</math>.
|
||||
|
||||
The algorithm must work for any integers <math>a, b, m</math> where <math>b \ge 0</math> and <math>m > 0</math>.
|
||||
26
Task/Modular-exponentiation/Ada/modular-exponentiation.ada
Normal file
26
Task/Modular-exponentiation/Ada/modular-exponentiation.ada
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
with Ada.Text_IO, Ada.Command_Line, Crypto.Types.Big_Numbers;
|
||||
|
||||
procedure Mod_Exp is
|
||||
|
||||
A: String :=
|
||||
"2988348162058574136915891421498819466320163312926952423791023078876139";
|
||||
B: String :=
|
||||
"2351399303373464486466122544523690094744975233415544072992656881240319";
|
||||
|
||||
D: constant Positive := Positive'Max(Positive'Max(A'Length, B'Length), 40);
|
||||
-- the number of decimals to store A, B, and result
|
||||
Bits: constant Positive := (34*D)/10;
|
||||
-- (slightly more than) the number of bits to store A, B, and result
|
||||
package LN is new Crypto.Types.Big_Numbers (Bits + (32 - Bits mod 32));
|
||||
-- the actual number of bits has to be a multiple of 32
|
||||
use type LN.Big_Unsigned;
|
||||
|
||||
function "+"(S: String) return LN.Big_Unsigned
|
||||
renames LN.Utils.To_Big_Unsigned;
|
||||
|
||||
M: LN.Big_Unsigned := (+"10") ** (+"40");
|
||||
|
||||
begin
|
||||
Ada.Text_IO.Put("A**B (mod 10**40) = ");
|
||||
Ada.Text_IO.Put_Line(LN.Utils.To_String(LN.Mod_Utils.Pow((+A), (+B), M)));
|
||||
end Mod_Exp;
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
INSTALL @lib$+"HIMELIB"
|
||||
PROC_himeinit("")
|
||||
|
||||
PROC_hiputdec(1, "2988348162058574136915891421498819466320163312926952423791023078876139")
|
||||
PROC_hiputdec(2, "2351399303373464486466122544523690094744975233415544072992656881240319")
|
||||
PROC_hiputdec(3, "10000000000000000000000000000000000000000")
|
||||
h1% = 1 : h2% = 2 : h3% = 3 : h4% = 4
|
||||
SYS `hi_PowMod`, ^h1%, ^h2%, ^h3%, ^h4%
|
||||
PRINT FN_higetdec(4)
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
( ( mod-power
|
||||
= base exponent modulus result
|
||||
. !arg:(?base,?exponent,?modulus)
|
||||
& !exponent:~<0
|
||||
& 1:?result
|
||||
& whl
|
||||
' ( !exponent:>0
|
||||
& ( ( mod$(!exponent.2):1
|
||||
& mod$(!result*!base.!modulus):?result
|
||||
& -1
|
||||
| 0
|
||||
)
|
||||
+ !exponent
|
||||
)
|
||||
* 1/2
|
||||
: ?exponent
|
||||
& mod$(!base^2.!modulus):?base
|
||||
)
|
||||
& !result
|
||||
)
|
||||
& ( a
|
||||
= 2988348162058574136915891421498819466320163312926952423791023078876139
|
||||
)
|
||||
& ( b
|
||||
= 2351399303373464486466122544523690094744975233415544072992656881240319
|
||||
)
|
||||
& out$("last 40 digits = " mod-power$(!a,!b,10^40))
|
||||
)
|
||||
25
Task/Modular-exponentiation/C/modular-exponentiation.c
Normal file
25
Task/Modular-exponentiation/C/modular-exponentiation.c
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#include <gmp.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
mpz_t a, b, m, r;
|
||||
|
||||
mpz_init_set_str(a, "2988348162058574136915891421498819466320"
|
||||
"163312926952423791023078876139", 0);
|
||||
mpz_init_set_str(b, "2351399303373464486466122544523690094744"
|
||||
"975233415544072992656881240319", 0);
|
||||
mpz_init(m);
|
||||
mpz_ui_pow_ui(m, 10, 40);
|
||||
|
||||
mpz_init(r);
|
||||
mpz_powm(r, a, b, m);
|
||||
|
||||
gmp_printf("%Zd\n", r); /* ...16808958343740453059 */
|
||||
|
||||
mpz_clear(a);
|
||||
mpz_clear(b);
|
||||
mpz_clear(m);
|
||||
mpz_clear(r);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
(defun rosetta-mod-expt (base power divisor)
|
||||
"Return BASE raised to the POWER, modulo DIVISOR.
|
||||
This function is faster than (MOD (EXPT BASE POWER) DIVISOR), but
|
||||
only works when POWER is a non-negative integer."
|
||||
(setq base (mod base divisor))
|
||||
;; Multiply product with base until power is zero.
|
||||
(do ((product 1))
|
||||
((zerop power) product)
|
||||
;; Square base, and divide power by 2, until power becomes odd.
|
||||
(do () ((oddp power))
|
||||
(setq base (mod (* base base) divisor)
|
||||
power (ash power -1)))
|
||||
(setq product (mod (* product base) divisor)
|
||||
power (1- power))))
|
||||
|
||||
(let ((a 2988348162058574136915891421498819466320163312926952423791023078876139)
|
||||
(b 2351399303373464486466122544523690094744975233415544072992656881240319))
|
||||
(format t "~A~%" (rosetta-mod-expt a b (expt 10 40))))
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
;; CLISP provides EXT:MOD-EXPT
|
||||
(let ((a 2988348162058574136915891421498819466320163312926952423791023078876139)
|
||||
(b 2351399303373464486466122544523690094744975233415544072992656881240319))
|
||||
(format t "~A~%" (mod-expt a b (expt 10 40))))
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
(defun mod-expt (a n m)
|
||||
(loop with c = 1 while (plusp n) do
|
||||
(if (oddp n) (setf c (mod (* a c) m)))
|
||||
(setf n (ash n -1))
|
||||
(setf a (mod (* a a) m))
|
||||
finally (return c)))
|
||||
23
Task/Modular-exponentiation/D/modular-exponentiation.d
Normal file
23
Task/Modular-exponentiation/D/modular-exponentiation.d
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import std.stdio, std.bigint;
|
||||
|
||||
BigInt powMod(BigInt base, BigInt exponent, BigInt modulus)
|
||||
in {
|
||||
assert(exponent >= 0);
|
||||
} body {
|
||||
BigInt result = 1;
|
||||
while (exponent > 0) {
|
||||
if (exponent % 2 == 1)
|
||||
result = (result * base) % modulus;
|
||||
exponent /= 2;
|
||||
base = base ^^ 2 % modulus;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void main() {
|
||||
powMod(BigInt("29883481620585741369158914214988194" ~
|
||||
"66320163312926952423791023078876139"),
|
||||
BigInt("235139930337346448646612254452369009" ~
|
||||
"4744975233415544072992656881240319"),
|
||||
BigInt(10) ^^ 40).writeln();
|
||||
}
|
||||
1
Task/Modular-exponentiation/Dc/modular-exponentiation.dc
Normal file
1
Task/Modular-exponentiation/Dc/modular-exponentiation.dc
Normal file
|
|
@ -0,0 +1 @@
|
|||
2988348162058574136915891421498819466320163312926952423791023078876139 2351399303373464486466122544523690094744975233415544072992656881240319 10 40^|p
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(let ((a "2988348162058574136915891421498819466320163312926952423791023078876139")
|
||||
(b "2351399303373464486466122544523690094744975233415544072992656881240319"))
|
||||
;; "$ ^ $$ mod (10 ^ 40)" performs modular exponentiation.
|
||||
;; "unpack(-5, x)_1" unpacks the integer from the modulo form.
|
||||
(message "%s" (calc-eval "unpack(-5, $ ^ $$ mod (10 ^ 40))_1" nil a b)))
|
||||
19
Task/Modular-exponentiation/Go/modular-exponentiation.go
Normal file
19
Task/Modular-exponentiation/Go/modular-exponentiation.go
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
func main() {
|
||||
a, _ := new(big.Int).SetString(
|
||||
"2988348162058574136915891421498819466320163312926952423791023078876139", 10)
|
||||
b, _ := new(big.Int).SetString(
|
||||
"2351399303373464486466122544523690094744975233415544072992656881240319", 10)
|
||||
m := big.NewInt(10)
|
||||
r := big.NewInt(40)
|
||||
m.Exp(m, r, nil)
|
||||
|
||||
r.Exp(a, b, m)
|
||||
fmt.Println(r)
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
-- Private type. Do not use outside of the modPow function
|
||||
newtype ModN = ModN (Integer, Integer) deriving (Eq, Show)
|
||||
instance Num ModN where
|
||||
-- actually only multiplication needs to be implemented
|
||||
-- but we do some of the other ones too for good measure
|
||||
ModN (x, m) + ModN (y, m') | m == m' = ModN ((x + y) `mod` m, m)
|
||||
| otherwise = undefined
|
||||
ModN (x, m) * ModN (y, m') | m == m' = ModN ((x * y) `mod` m, m)
|
||||
| otherwise = undefined
|
||||
negate (ModN (x, m)) = ModN ((- x) `mod` m, m)
|
||||
abs _ = undefined
|
||||
signum _ = undefined
|
||||
fromInteger _ = undefined
|
||||
|
||||
modPow :: Integer -> Integer -> Integer -> Integer
|
||||
modPow _ 0 m = 1 `mod` m
|
||||
modPow a b m = c
|
||||
where a' = ModN (a, m)
|
||||
ModN (c, _) = a' ^ b
|
||||
|
||||
main :: IO ()
|
||||
main = print $ modPow a b m
|
||||
where a = 2988348162058574136915891421498819466320163312926952423791023078876139
|
||||
b = 2351399303373464486466122544523690094744975233415544072992656881240319
|
||||
m = 10 ^ 40
|
||||
17
Task/Modular-exponentiation/Icon/modular-exponentiation.icon
Normal file
17
Task/Modular-exponentiation/Icon/modular-exponentiation.icon
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
procedure main()
|
||||
a := 2988348162058574136915891421498819466320163312926952423791023078876139
|
||||
b := 2351399303373464486466122544523690094744975233415544072992656881240319
|
||||
write("last 40 digits = ",mod_power(a,b,(10^40))
|
||||
end
|
||||
|
||||
procedure mod_power(base, exponent, modulus) # fast modular exponentation
|
||||
if exponent < 0 then runerr(205,m) # added for this task
|
||||
result := 1
|
||||
while exponent > 0 do {
|
||||
if exponent % 2 = 1 then
|
||||
result := (result * base) % modulus
|
||||
exponent /:= 2
|
||||
base := base ^ 2 % modulus
|
||||
}
|
||||
return result
|
||||
end
|
||||
1
Task/Modular-exponentiation/J/modular-exponentiation-1.j
Normal file
1
Task/Modular-exponentiation/J/modular-exponentiation-1.j
Normal file
|
|
@ -0,0 +1 @@
|
|||
m&|@^
|
||||
6
Task/Modular-exponentiation/J/modular-exponentiation-2.j
Normal file
6
Task/Modular-exponentiation/J/modular-exponentiation-2.j
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
a =: 2988348162058574136915891421498819466320163312926952423791023078876139x
|
||||
b =: 2351399303373464486466122544523690094744975233415544072992656881240319x
|
||||
m =: 10^40x
|
||||
|
||||
a m&|@^ b
|
||||
1527229998585248450016808958343740453059
|
||||
13
Task/Modular-exponentiation/Java/modular-exponentiation.java
Normal file
13
Task/Modular-exponentiation/Java/modular-exponentiation.java
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import java.math.BigInteger;
|
||||
|
||||
public class PowMod {
|
||||
public static void main(String[] args){
|
||||
BigInteger a = new BigInteger(
|
||||
"2988348162058574136915891421498819466320163312926952423791023078876139");
|
||||
BigInteger b = new BigInteger(
|
||||
"2351399303373464486466122544523690094744975233415544072992656881240319");
|
||||
BigInteger m = new BigInteger("10000000000000000000000000000000000000000");
|
||||
|
||||
System.out.println(a.modPow(b, m));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
a := 2988348162058574136915891421498819466320163312926952423791023078876139:
|
||||
b := 2351399303373464486466122544523690094744975233415544072992656881240319:
|
||||
a &^ b mod 10^40;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
a = 2988348162058574136915891421498819466320163312926952423791023078876139;
|
||||
b = 2351399303373464486466122544523690094744975233415544072992656881240319;
|
||||
m = 10^40;
|
||||
PowerMod[a, b, m]
|
||||
-> 1527229998585248450016808958343740453059
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
a: 2988348162058574136915891421498819466320163312926952423791023078876139$
|
||||
b: 2351399303373464486466122544523690094744975233415544072992656881240319$
|
||||
power_mod(a, b, 10^40);
|
||||
/* 1527229998585248450016808958343740453059 */
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
$a = '2988348162058574136915891421498819466320163312926952423791023078876139';
|
||||
$b = '2351399303373464486466122544523690094744975233415544072992656881240319';
|
||||
$m = '1' . str_repeat('0', 40);
|
||||
echo bcpowmod($a, $b, $m), "\n";
|
||||
?>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
use bigint;
|
||||
|
||||
my $a = 2988348162058574136915891421498819466320163312926952423791023078876139;
|
||||
my $b = 2351399303373464486466122544523690094744975233415544072992656881240319;
|
||||
my $m = 10 ** 40;
|
||||
print $a->bmodpow($b, $m), "\n";
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
(de **Mod (X Y N)
|
||||
(let M 1
|
||||
(loop
|
||||
(when (bit? 1 Y)
|
||||
(setq M (% (* M X) N)) )
|
||||
(T (=0 (setq Y (>> 1 Y)))
|
||||
M )
|
||||
(setq X (% (* X X) N)) ) ) )
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
: (**Mod
|
||||
2988348162058574136915891421498819466320163312926952423791023078876139
|
||||
2351399303373464486466122544523690094744975233415544072992656881240319
|
||||
10000000000000000000000000000000000000000 )
|
||||
-> 1527229998585248450016808958343740453059
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
a = 2988348162058574136915891421498819466320163312926952423791023078876139
|
||||
b = 2351399303373464486466122544523690094744975233415544072992656881240319
|
||||
m = 10 ** 40
|
||||
print(pow(a, b, m))
|
||||
28
Task/Modular-exponentiation/REXX/modular-exponentiation.rexx
Normal file
28
Task/Modular-exponentiation/REXX/modular-exponentiation.rexx
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*REXX program to show modular exponentation: a**b mod M */
|
||||
parse arg a b mm /*get the arguments (maybe).*/
|
||||
if a=='' | a==',' then a=,
|
||||
2988348162058574136915891421498819466320163312926952423791023078876139
|
||||
|
||||
if b=='' | b==',' then b=,
|
||||
2351399303373464486466122544523690094744975233415544072992656881240319
|
||||
|
||||
if mm=='' then mm=40
|
||||
say 'a=' a; say ' ('length(a) "digits)"
|
||||
say 'b=' b; say ' ('length(b) "digits)"
|
||||
|
||||
do j=1 for words(mm); m=word(mm,j); say copies('─',linesize()-1)
|
||||
say 'a**b (mod 10**'m")=" powerModulated(a,b,10**m)
|
||||
end /*j*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────────POWERMODULATED subroutine───────*/
|
||||
powerModulated: procedure; parse arg x,p,n /*fast modular exponentation*/
|
||||
if p==0 then return 1 /*special case. */
|
||||
if p==1 then return x /*special case. */
|
||||
if p<0 then do; say '***error!*** power is negative:' p; exit 13; end
|
||||
parse value max(x**2,p,n)'E0' with "E" e /*pick biggest of the three.*/
|
||||
numeric digits max(20,e*2) /*big enough to handle A² */
|
||||
_=1
|
||||
do while p\==0; if p//2==1 then _=_*x//n
|
||||
p=p%2; x=x*x // n
|
||||
end /*while*/
|
||||
return _
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
require 'openssl'
|
||||
|
||||
a = 2988348162058574136915891421498819466320163312926952423791023078876139
|
||||
b = 2351399303373464486466122544523690094744975233415544072992656881240319
|
||||
m = 10 ** 40
|
||||
puts a.to_bn.mod_exp(b, m)
|
||||
18
Task/Modular-exponentiation/Ruby/modular-exponentiation-2.rb
Normal file
18
Task/Modular-exponentiation/Ruby/modular-exponentiation-2.rb
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
class Integer
|
||||
def rosetta_mod_exp(exp, mod)
|
||||
exp < 0 and raise ArgumentError, "negative exponent"
|
||||
prod = 1
|
||||
base = self % mod
|
||||
until exp.zero?
|
||||
exp.odd? and prod = (prod * base) % mod
|
||||
exp >>= 1
|
||||
base = (base * base) % mod
|
||||
end
|
||||
prod
|
||||
end
|
||||
end
|
||||
|
||||
a = 2988348162058574136915891421498819466320163312926952423791023078876139
|
||||
b = 2351399303373464486466122544523690094744975233415544072992656881240319
|
||||
m = 10 ** 40
|
||||
puts a.rosetta_mod_exp(b, m)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import scala.math.BigInt
|
||||
|
||||
val a = BigInt(
|
||||
"2988348162058574136915891421498819466320163312926952423791023078876139")
|
||||
val b = BigInt(
|
||||
"2351399303373464486466122544523690094744975233415544072992656881240319")
|
||||
|
||||
println(a.modPow(b, BigInt(10).pow(40)))
|
||||
13
Task/Modular-exponentiation/Tcl/modular-exponentiation-1.tcl
Normal file
13
Task/Modular-exponentiation/Tcl/modular-exponentiation-1.tcl
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
package require Tcl 8.5
|
||||
|
||||
# Algorithm from http://introcs.cs.princeton.edu/java/78crypto/ModExp.java.html
|
||||
# but Tcl has arbitrary-width integers and an exponentiation operator, which
|
||||
# helps simplify the code.
|
||||
proc tcl::mathfunc::modexp {a b n} {
|
||||
if {$b == 0} {return 1}
|
||||
set c [expr {modexp($a, $b / 2, $n)**2 % $n}]
|
||||
if {$b & 1} {
|
||||
set c [expr {($c * $a) % $n}]
|
||||
}
|
||||
return $c
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
set a 2988348162058574136915891421498819466320163312926952423791023078876139
|
||||
set b 2351399303373464486466122544523690094744975233415544072992656881240319
|
||||
set n [expr {10**40}]
|
||||
puts [expr {modexp($a,$b,$n)}]
|
||||
10
Task/Modular-exponentiation/Tcl/modular-exponentiation-3.tcl
Normal file
10
Task/Modular-exponentiation/Tcl/modular-exponentiation-3.tcl
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package require Tcl 8.5
|
||||
proc modexp {a b n} {
|
||||
for {set c 1} {$b} {set a [expr {$a*$a % $n}]} {
|
||||
if {$b & 1} {
|
||||
set c [expr {$c*$a % $n}]
|
||||
}
|
||||
set b [expr {$b >> 1}]
|
||||
}
|
||||
return $c
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
set a 2988348162058574136915891421498819466320163312926952423791023078876139
|
||||
set b 2351399303373464486466122544523690094744975233415544072992656881240319
|
||||
set n [expr {10**40}]
|
||||
puts [modexp $a $b $n]
|
||||
Loading…
Add table
Add a link
Reference in a new issue