Chinese remainder theorem: Difference between revisions
Content added Content deleted
(add bqn) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 53: | Line 53: | ||
=={{header|11l}}== |
=={{header|11l}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang=11l>F mul_inv(=a, =b) |
||
V b0 = b |
V b0 = b |
||
V x0 = 0 |
V x0 = 0 |
||
Line 77: | Line 77: | ||
V n = [3, 5, 7] |
V n = [3, 5, 7] |
||
V a = [2, 3, 2] |
V a = [2, 3, 2] |
||
print(chinese_remainder(n, a))</ |
print(chinese_remainder(n, a))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
Line 83: | Line 83: | ||
=={{header|360 Assembly}}== |
=={{header|360 Assembly}}== |
||
{{trans|REXX}} |
{{trans|REXX}} |
||
< |
<syntaxhighlight lang=360asm>* Chinese remainder theorem 06/09/2015 |
||
CHINESE CSECT |
CHINESE CSECT |
||
USING CHINESE,R12 base addr |
USING CHINESE,R12 base addr |
||
Line 126: | Line 126: | ||
NOSOL DC CL17'no solution found' |
NOSOL DC CL17'no solution found' |
||
YREGS |
YREGS |
||
END CHINESE</ |
END CHINESE</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 133: | Line 133: | ||
=={{header|Action!}}== |
=={{header|Action!}}== |
||
< |
<syntaxhighlight lang=Action!>INT FUNC MulInv(INT a,b) |
||
INT b0,x0,x1,q,tmp |
INT b0,x0,x1,q,tmp |
||
Line 179: | Line 179: | ||
res=ChineseRemainder(n,a,3) |
res=ChineseRemainder(n,a,3) |
||
PrintI(res) |
PrintI(res) |
||
RETURN</ |
RETURN</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Chinese_remainder_theorem.png Screenshot from Atari 8-bit computer] |
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Chinese_remainder_theorem.png Screenshot from Atari 8-bit computer] |
||
Line 190: | Line 190: | ||
Using the package Mod_Inv from [[http://rosettacode.org/wiki/Modular_inverse#Ada]]. |
Using the package Mod_Inv from [[http://rosettacode.org/wiki/Modular_inverse#Ada]]. |
||
< |
<syntaxhighlight lang=Ada>with Ada.Text_IO, Mod_Inv; |
||
procedure Chin_Rema is |
procedure Chin_Rema is |
||
Line 209: | Line 209: | ||
end loop; |
end loop; |
||
Ada.Text_IO.Put_Line(Integer'Image(Sum mod Prod)); |
Ada.Text_IO.Put_Line(Integer'Image(Sum mod Prod)); |
||
end Chin_Rema;</ |
end Chin_Rema;</syntaxhighlight> |
||
=={{header|Arturo}}== |
=={{header|Arturo}}== |
||
< |
<syntaxhighlight lang=rebol>mulInv: function [a0, b0][ |
||
[a b x0]: @[a0 b0 0] |
[a b x0]: @[a0 b0 0] |
||
result: 1 |
result: 1 |
||
Line 245: | Line 245: | ||
] |
] |
||
print chineseRemainder [3 5 7] [2 3 2]</ |
print chineseRemainder [3 5 7] [2 3 2]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 254: | Line 254: | ||
{{trans|C}} |
{{trans|C}} |
||
We are using the split-function to create both arrays, thus the indices start at 1. This is the only difference to the C version. |
We are using the split-function to create both arrays, thus the indices start at 1. This is the only difference to the C version. |
||
< |
<syntaxhighlight lang=awk># Usage: GAWK -f CHINESE_REMAINDER_THEOREM.AWK |
||
BEGIN { |
BEGIN { |
||
len = split("3 5 7", n) |
len = split("3 5 7", n) |
||
Line 290: | Line 290: | ||
x1 += b0 |
x1 += b0 |
||
return x1 |
return x1 |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
Line 298: | Line 298: | ||
Multiplicative Modular inverse function taken from BQNcrate. |
Multiplicative Modular inverse function taken from BQNcrate. |
||
< |
<syntaxhighlight lang=bqn>MulInv←⊣|·⊑{0=𝕨?1‿0;(⌽-(0⋈𝕩⌊∘÷𝕨)⊸×)𝕨𝕊˜𝕨|𝕩} |
||
ChRem←{ |
ChRem←{ |
||
num 𝕊 rem: |
num 𝕊 rem: |
||
Line 306: | Line 306: | ||
•Show 3‿5‿7 ChRem 2‿3‿2 |
•Show 3‿5‿7 ChRem 2‿3‿2 |
||
•Show 10‿4‿9 ChRem 11‿22‿19</ |
•Show 10‿4‿9 ChRem 11‿22‿19</syntaxhighlight><syntaxhighlight lang=text>23 |
||
172</ |
172</syntaxhighlight> |
||
=={{header|Bracmat}}== |
=={{header|Bracmat}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang=bracmat>( ( mul-inv |
||
= a b b0 q x0 x1 |
= a b b0 q x0 x1 |
||
. !arg:(?a.?b:?b0) |
. !arg:(?a.?b:?b0) |
||
Line 348: | Line 348: | ||
& 2 3 2:?a |
& 2 3 2:?a |
||
& put$(str$(chinese-remainder$(!n.!a) \n)) |
& put$(str$(chinese-remainder$(!n.!a) \n)) |
||
);</ |
);</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>23</pre> |
<pre>23</pre> |
||
Line 354: | Line 354: | ||
=={{header|C}}== |
=={{header|C}}== |
||
When n are not pairwise coprime, the program crashes due to division by zero, which is one way to convey error. |
When n are not pairwise coprime, the program crashes due to division by zero, which is one way to convey error. |
||
< |
<syntaxhighlight lang=c>#include <stdio.h> |
||
// returns x where (a * x) % b == 1 |
// returns x where (a * x) % b == 1 |
||
Line 392: | Line 392: | ||
printf("%d\n", chinese_remainder(n, a, sizeof(n)/sizeof(n[0]))); |
printf("%d\n", chinese_remainder(n, a, sizeof(n)/sizeof(n[0]))); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang=csharp>using System; |
||
using System.Linq; |
using System.Linq; |
||
Line 447: | Line 447: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
< |
<syntaxhighlight lang=cpp>// Requires C++17 |
||
#include <iostream> |
#include <iostream> |
||
#include <numeric> |
#include <numeric> |
||
Line 502: | Line 502: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
Line 508: | Line 508: | ||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
Modeled after the Python version http://rosettacode.org/wiki/Category:Python |
Modeled after the Python version http://rosettacode.org/wiki/Category:Python |
||
< |
<syntaxhighlight lang=lisp>(ns test-p.core |
||
(:require [clojure.math.numeric-tower :as math])) |
(:require [clojure.math.numeric-tower :as math])) |
||
Line 549: | Line 549: | ||
(println (chinese_remainder n a)) |
(println (chinese_remainder n a)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Output:''' |
'''Output:''' |
||
Line 557: | Line 557: | ||
=={{header|Coffeescript}}== |
=={{header|Coffeescript}}== |
||
< |
<syntaxhighlight lang=coffeescript>crt = (n,a) -> |
||
sum = 0 |
sum = 0 |
||
prod = n.reduce (a,c) -> a*c |
prod = n.reduce (a,c) -> a*c |
||
Line 576: | Line 576: | ||
x1 |
x1 |
||
print crt [3,5,7], [2,3,2]</ |
print crt [3,5,7], [2,3,2]</syntaxhighlight> |
||
'''Output:''' |
'''Output:''' |
||
<pre> |
<pre> |
||
Line 584: | Line 584: | ||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
Using function ''invmod'' from [[http://rosettacode.org/wiki/Modular_inverse#Common_Lisp]]. |
Using function ''invmod'' from [[http://rosettacode.org/wiki/Modular_inverse#Common_Lisp]]. |
||
< |
<syntaxhighlight lang=lisp> |
||
(defun chinese-remainder (am) |
(defun chinese-remainder (am) |
||
"Calculates the Chinese Remainder for the given set of integer modulo pairs. |
"Calculates the Chinese Remainder for the given set of integer modulo pairs. |
||
Line 594: | Line 594: | ||
:do |
:do |
||
(incf sum (* a (invmod (/ mtot m) m) (/ mtot m))))) |
(incf sum (* a (invmod (/ mtot m) m) (/ mtot m))))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Output:''' |
'''Output:''' |
||
Line 625: | Line 625: | ||
{{trans|Ruby}} |
{{trans|Ruby}} |
||
< |
<syntaxhighlight lang=crystal>def extended_gcd(a, b) |
||
last_remainder, remainder = a.abs, b.abs |
last_remainder, remainder = a.abs, b.abs |
||
x, last_x = 0, 1 |
x, last_x = 0, 1 |
||
Line 658: | Line 658: | ||
puts chinese_remainder([3, 5, 7], [2, 3, 2]) |
puts chinese_remainder([3, 5, 7], [2, 3, 2]) |
||
puts chinese_remainder([5, 7, 9, 11], [1, 2, 3, 4]) |
puts chinese_remainder([5, 7, 9, 11], [1, 2, 3, 4]) |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Output:''' |
'''Output:''' |
||
Line 668: | Line 668: | ||
=={{header|D}}== |
=={{header|D}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang=d>import std.stdio, std.algorithm; |
||
T chineseRemainder(T)(in T[] n, in T[] a) pure nothrow @safe @nogc |
T chineseRemainder(T)(in T[] n, in T[] a) pure nothrow @safe @nogc |
||
Line 707: | Line 707: | ||
a = [2, 3, 2]; |
a = [2, 3, 2]; |
||
chineseRemainder(n, a).writeln; |
chineseRemainder(n, a).writeln; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
Line 714: | Line 714: | ||
{{libheader| Velthuis.BigIntegers}} |
{{libheader| Velthuis.BigIntegers}} |
||
{{Trans|Java}} |
{{Trans|Java}} |
||
< |
<syntaxhighlight lang=Delphi> |
||
program ChineseRemainderTheorem; |
program ChineseRemainderTheorem; |
||
Line 778: | Line 778: | ||
Writeln(chineseRemainder(n, a).ToString); |
Writeln(chineseRemainder(n, a).ToString); |
||
end.</ |
end.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
Line 785: | Line 785: | ||
=={{header|EasyLang}}== |
=={{header|EasyLang}}== |
||
{{trans|C}} |
{{trans|C}} |
||
<lang>func mul_inv a b . x1 . |
<syntaxhighlight lang=text>func mul_inv a b . x1 . |
||
b0 = b |
b0 = b |
||
x1 = 1 |
x1 = 1 |
||
Line 819: | Line 819: | ||
a[] = [ 2 3 2 ] |
a[] = [ 2 3 2 ] |
||
call remainder n[] a[] h |
call remainder n[] a[] h |
||
print h</ |
print h</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
Line 825: | Line 825: | ||
=={{header|EchoLisp}}== |
=={{header|EchoLisp}}== |
||
'''egcd''' - extended gcd - and '''crt-solve''' - chinese remainder theorem solve - are included in math.lib. |
'''egcd''' - extended gcd - and '''crt-solve''' - chinese remainder theorem solve - are included in math.lib. |
||
< |
<syntaxhighlight lang=scheme> |
||
(lib 'math) |
(lib 'math) |
||
math.lib v1.10 ® EchoLisp |
math.lib v1.10 ® EchoLisp |
||
Line 834: | Line 834: | ||
(crt-solve '(2 3 2) '(7 1005 15)) |
(crt-solve '(2 3 2) '(7 1005 15)) |
||
💥 error: mod[i] must be co-primes : assertion failed : 1005 |
💥 error: mod[i] must be co-primes : assertion failed : 1005 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
Line 840: | Line 840: | ||
{{works with|Elixir|1.2}} |
{{works with|Elixir|1.2}} |
||
Brute-force: |
Brute-force: |
||
< |
<syntaxhighlight lang=elixir>defmodule Chinese do |
||
def remainder(mods, remainders) do |
def remainder(mods, remainders) do |
||
max = Enum.reduce(mods, fn x,acc -> x*acc end) |
max = Enum.reduce(mods, fn x,acc -> x*acc end) |
||
Line 852: | Line 852: | ||
IO.inspect Chinese.remainder([3,5,7], [2,3,2]) |
IO.inspect Chinese.remainder([3,5,7], [2,3,2]) |
||
IO.inspect Chinese.remainder([10,4,9], [11,22,19]) |
IO.inspect Chinese.remainder([10,4,9], [11,22,19]) |
||
IO.inspect Chinese.remainder([11,12,13], [10,4,12])</ |
IO.inspect Chinese.remainder([11,12,13], [10,4,12])</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 863: | Line 863: | ||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
{{trans|OCaml}} |
{{trans|OCaml}} |
||
< |
<syntaxhighlight lang=erlang>-module(crt). |
||
-import(lists, [zip/2, unzip/1, foldl/3, sum/1]). |
-import(lists, [zip/2, unzip/1, foldl/3, sum/1]). |
||
-export([egcd/2, mod/2, mod_inv/2, chinese_remainder/1]). |
-export([egcd/2, mod/2, mod_inv/2, chinese_remainder/1]). |
||
Line 903: | Line 903: | ||
[A*B || {A,B} <- zip(Residues, Inverses)])]), |
[A*B || {A,B} <- zip(Residues, Inverses)])]), |
||
mod(Solution, ModPI) |
mod(Solution, ModPI) |
||
end.</ |
end.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 916: | Line 916: | ||
=={{header|F_Sharp|F#}}== |
=={{header|F_Sharp|F#}}== |
||
===[https://en.wikipedia.org/wiki/Chinese_remainder_theorem#Search_by_sieving sieving]=== |
===[https://en.wikipedia.org/wiki/Chinese_remainder_theorem#Search_by_sieving sieving]=== |
||
< |
<syntaxhighlight lang=fsharp>let rec sieve cs x N = |
||
match cs with |
match cs with |
||
| [] -> Some(x) |
| [] -> Some(x) |
||
Line 938: | Line 938: | ||
| None -> printfn "no solution" |
| None -> printfn "no solution" |
||
| Some(x) -> printfn "result = %i" x |
| Some(x) -> printfn "result = %i" x |
||
)</ |
)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>result = 23 |
<pre>result = 23 |
||
Line 947: | Line 947: | ||
<br> |
<br> |
||
This uses [[Modular_inverse#F.23]] |
This uses [[Modular_inverse#F.23]] |
||
< |
<syntaxhighlight lang=fsharp> |
||
//Chinese Division Theorem: Nigel Galloway: April 3rd., 2017 |
//Chinese Division Theorem: Nigel Galloway: April 3rd., 2017 |
||
let CD n g = |
let CD n g = |
||
Line 953: | Line 953: | ||
|0 -> None |
|0 -> None |
||
|fN-> Some ((Seq.fold2(fun n i g -> n+i*(fN/g)*(MI g ((fN/g)%g))) 0 n g)%fN) |
|fN-> Some ((Seq.fold2(fun n i g -> n+i*(fN/g)*(MI g ((fN/g)%g))) 0 n g)%fN) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 962: | Line 962: | ||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
< |
<syntaxhighlight lang=factor>USING: math.algebra prettyprint ; |
||
{ 2 3 2 } { 3 5 7 } chinese-remainder .</ |
{ 2 3 2 } { 3 5 7 } chinese-remainder .</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 971: | Line 971: | ||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
Tested with GNU FORTH |
Tested with GNU FORTH |
||
< |
<syntaxhighlight lang=forth>: egcd ( a b -- a b ) |
||
dup 0= IF |
dup 0= IF |
||
2drop 1 0 |
2drop 1 0 |
||
Line 1,009: | Line 1,009: | ||
LOOP |
LOOP |
||
crt-residues[] crt-moduli[] n crt-from-array ; |
crt-residues[] crt-moduli[] n crt-from-array ; |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,023: | Line 1,023: | ||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
Partial {{trans|C}}. Uses the code from [[Greatest_common_divisor#Recursive_solution]] as an include. |
Partial {{trans|C}}. Uses the code from [[Greatest_common_divisor#Recursive_solution]] as an include. |
||
< |
<syntaxhighlight lang=freebasic> |
||
#include "gcd.bas" |
#include "gcd.bas" |
||
function mul_inv( a as integer, b as integer ) as integer |
function mul_inv( a as integer, b as integer ) as integer |
||
Line 1,056: | Line 1,056: | ||
dim as integer a(0 to 2) = { 2, 3, 2 } |
dim as integer a(0 to 2) = { 2, 3, 2 } |
||
print chinese_remainder(n(), a())</ |
print chinese_remainder(n(), a())</syntaxhighlight> |
||
{{out}}<pre>23</pre> |
{{out}}<pre>23</pre> |
||
Line 1,065: | Line 1,065: | ||
Input is validated and useful error messages are emitted if the input data is invalid. If a solution cannot be found, this returns the special value <CODE>undef</CODE>. |
Input is validated and useful error messages are emitted if the input data is invalid. If a solution cannot be found, this returns the special value <CODE>undef</CODE>. |
||
< |
<syntaxhighlight lang=frink>/** arguments: |
||
[r, m, d=0] where r and m are arrays of the remainder terms r and the |
[r, m, d=0] where r and m are arrays of the remainder terms r and the |
||
modulus terms m respectively. These must be of the same length. |
modulus terms m respectively. These must be of the same length. |
||
Line 1,106: | Line 1,106: | ||
} |
} |
||
println[ChineseRemainder[[2,3,2],[3,5,7]] ]</ |
println[ChineseRemainder[[2,3,2],[3,5,7]] ]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,113: | Line 1,113: | ||
=={{header|FunL}}== |
=={{header|FunL}}== |
||
< |
<syntaxhighlight lang=funl>import integers.modinv |
||
def crt( congruences ) = |
def crt( congruences ) = |
||
Line 1,119: | Line 1,119: | ||
sum( a*modinv(N/n, n)*N/n | (a, n) <- congruences ) mod N |
sum( a*modinv(N/n, n)*N/n | (a, n) <- congruences ) mod N |
||
println( crt([(2, 3), (3, 5), (2, 7)]) )</ |
println( crt([(2, 3), (3, 5), (2, 7)]) )</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,129: | Line 1,129: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
Go has the Extended Euclidean algorithm in the GCD function for big integers in the standard library. GCD will return 1 only if numbers are coprime, so a result != 1 indicates the error condition. |
Go has the Extended Euclidean algorithm in the GCD function for big integers in the standard library. GCD will return 1 only if numbers are coprime, so a result != 1 indicates the error condition. |
||
< |
<syntaxhighlight lang=go>package main |
||
import ( |
import ( |
||
Line 1,167: | Line 1,167: | ||
} |
} |
||
fmt.Println(crt(a, n)) |
fmt.Println(crt(a, n)) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Two values, the solution x and an error value. |
Two values, the solution x and an error value. |
||
Line 1,176: | Line 1,176: | ||
=={{header|Groovy}}== |
=={{header|Groovy}}== |
||
{{trans|Java}} |
{{trans|Java}} |
||
< |
<syntaxhighlight lang=groovy>class ChineseRemainderTheorem { |
||
static int chineseRemainder(int[] n, int[] a) { |
static int chineseRemainder(int[] n, int[] a) { |
||
int prod = 1 |
int prod = 1 |
||
Line 1,222: | Line 1,222: | ||
println(chineseRemainder(n, a)) |
println(chineseRemainder(n, a)) |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
Line 1,228: | Line 1,228: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
{{trans|Erlang}} |
{{trans|Erlang}} |
||
< |
<syntaxhighlight lang=haskell>import Control.Monad (zipWithM) |
||
egcd :: Int -> Int -> (Int, Int) |
egcd :: Int -> Int -> (Int, Int) |
||
Line 1,260: | Line 1,260: | ||
, ([10, 4, 9], [11, 22, 19]) |
, ([10, 4, 9], [11, 22, 19]) |
||
, ([2, 3, 2], [3, 5, 7]) |
, ([2, 3, 2], [3, 5, 7]) |
||
]</ |
]</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>1000 |
<pre>1000 |
||
Line 1,270: | Line 1,270: | ||
{{trans|Python}} with error check added. |
{{trans|Python}} with error check added. |
||
Works in both languages: |
Works in both languages: |
||
< |
<syntaxhighlight lang=unicon>link numbers # for gcd() |
||
procedure main() |
procedure main() |
||
Line 1,293: | Line 1,293: | ||
} |
} |
||
return if x1 < 0 then x1+b0 else x1 |
return if x1 < 0 then x1+b0 else x1 |
||
end</ |
end</syntaxhighlight> |
||
Output: |
Output: |
||
Line 1,305: | Line 1,305: | ||
=={{header|J}}== |
=={{header|J}}== |
||
'''Solution''' (''brute force''):< |
'''Solution''' (''brute force''):<syntaxhighlight lang=j> crt =: (1 + ] - {:@:[ -: {.@:[ | ])^:_&0@:,:</syntaxhighlight> |
||
'''Example''': < |
'''Example''': <syntaxhighlight lang=j> 3 5 7 crt 2 3 2 |
||
23 |
23 |
||
11 12 13 crt 10 4 12 |
11 12 13 crt 10 4 12 |
||
1000</ |
1000</syntaxhighlight> |
||
'''Notes''': This is a brute force approach and does not meet the requirement for explicit notification of an an unsolvable set of equations (it just spins forever). A much more thorough and educational approach can be found on the [[j:Essays/Chinese%20Remainder%20Theorem|J wiki's Essay on the Chinese Remainder Thereom]]. |
'''Notes''': This is a brute force approach and does not meet the requirement for explicit notification of an an unsolvable set of equations (it just spins forever). A much more thorough and educational approach can be found on the [[j:Essays/Chinese%20Remainder%20Theorem|J wiki's Essay on the Chinese Remainder Thereom]]. |
||
Line 1,315: | Line 1,315: | ||
Translation of [[Chinese_remainder_theorem#Python|Python]] via [[Chinese_remainder_theorem#D|D]] |
Translation of [[Chinese_remainder_theorem#Python|Python]] via [[Chinese_remainder_theorem#D|D]] |
||
{{works with|Java|8}} |
{{works with|Java|8}} |
||
< |
<syntaxhighlight lang=java>import static java.util.Arrays.stream; |
||
public class ChineseRemainderTheorem { |
public class ChineseRemainderTheorem { |
||
Line 1,360: | Line 1,360: | ||
System.out.println(chineseRemainder(n, a)); |
System.out.println(chineseRemainder(n, a)); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
<pre>23</pre> |
<pre>23</pre> |
||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
< |
<syntaxhighlight lang=javascript> |
||
function crt(num, rem) { |
function crt(num, rem) { |
||
let sum = 0; |
let sum = 0; |
||
Line 1,396: | Line 1,396: | ||
} |
} |
||
console.log(crt([3,5,7], [2,3,2]))</ |
console.log(crt([3,5,7], [2,3,2]))</syntaxhighlight> |
||
'''Output:''' |
'''Output:''' |
||
<pre> |
<pre> |
||
Line 1,404: | Line 1,404: | ||
=={{header|jq}}== |
=={{header|jq}}== |
||
This implementation is similar to the one in C, but raises an error if there is no solution, as illustrated in the last example. |
This implementation is similar to the one in C, but raises an error if there is no solution, as illustrated in the last example. |
||
< |
<syntaxhighlight lang=jq># mul_inv(a;b) returns x where (a * x) % b == 1, or else null |
||
def mul_inv(a; b): |
def mul_inv(a; b): |
||
Line 1,434: | Line 1,434: | ||
else . + (remainders[$i] * $mi * $p) |
else . + (remainders[$i] * $mi * $p) |
||
end ) |
end ) |
||
| . % $prod ;</ |
| . % $prod ;</syntaxhighlight> |
||
'''Examples''': |
'''Examples''': |
||
chinese_remainder([3,5,7]; [2,3,2]) |
chinese_remainder([3,5,7]; [2,3,2]) |
||
Line 1,446: | Line 1,446: | ||
{{works with|Julia|1.2}} |
{{works with|Julia|1.2}} |
||
< |
<syntaxhighlight lang=julia>function chineseremainder(n::Array, a::Array) |
||
Π = prod(n) |
Π = prod(n) |
||
mod(sum(ai * invmod(Π ÷ ni, ni) * (Π ÷ ni) for (ni, ai) in zip(n, a)), Π) |
mod(sum(ai * invmod(Π ÷ ni, ni) * (Π ÷ ni) for (ni, ai) in zip(n, a)), Π) |
||
end |
end |
||
@show chineseremainder([3, 5, 7], [2, 3, 2])</ |
@show chineseremainder([3, 5, 7], [2, 3, 2])</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,458: | Line 1,458: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang=scala>// version 1.1.2 |
||
/* returns x where (a * x) % b == 1 */ |
/* returns x where (a * x) % b == 1 */ |
||
Line 1,494: | Line 1,494: | ||
val a = intArrayOf(2, 3, 2) |
val a = intArrayOf(2, 3, 2) |
||
println(chineseRemainder(n, a)) |
println(chineseRemainder(n, a)) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,502: | Line 1,502: | ||
=={{header|Lobster}}== |
=={{header|Lobster}}== |
||
< |
<syntaxhighlight lang=Lobster>import std |
||
def extended_gcd(a, b): |
def extended_gcd(a, b): |
||
Line 1,543: | Line 1,543: | ||
print_crt([11,22,19],[10,4,9]) |
print_crt([11,22,19],[10,4,9]) |
||
print_crt([100,23],[19,0]) |
print_crt([100,23],[19,0]) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>ok 23 |
<pre>ok 23 |
||
Line 1,552: | Line 1,552: | ||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
< |
<syntaxhighlight lang=lua>-- Taken from https://www.rosettacode.org/wiki/Sum_and_product_of_an_array#Lua |
||
function prodf(a, ...) return a and a * prodf(...) or 1 end |
function prodf(a, ...) return a and a * prodf(...) or 1 end |
||
function prodt(t) return prodf(unpack(t)) end |
function prodt(t) return prodf(unpack(t)) end |
||
Line 1,597: | Line 1,597: | ||
n = {3, 5, 7} |
n = {3, 5, 7} |
||
a = {2, 3, 2} |
a = {2, 3, 2} |
||
io.write(chineseRemainder(n, a))</ |
io.write(chineseRemainder(n, a))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
=={{header|M2000 Interpreter}}== |
=={{header|M2000 Interpreter}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang=M2000 Interpreter> |
||
Function ChineseRemainder(n(), a()) { |
Function ChineseRemainder(n(), a()) { |
||
Function mul_inv(a, b) { |
Function mul_inv(a, b) { |
||
Line 1,625: | Line 1,625: | ||
} |
} |
||
Print ChineseRemainder((3,5,7), (2,3,2)) |
Print ChineseRemainder((3,5,7), (2,3,2)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>23 |
<pre>23 |
||
Line 1,633: | Line 1,633: | ||
=={{header|Maple}}== |
=={{header|Maple}}== |
||
This is a Maple built-in procedure, so it is trivial: |
This is a Maple built-in procedure, so it is trivial: |
||
< |
<syntaxhighlight lang=Maple>> chrem( [2, 3, 2], [3, 5, 7] ); |
||
23 |
23 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
||
Very easy, because it is a built-in function: |
Very easy, because it is a built-in function: |
||
< |
<syntaxhighlight lang=Mathematica >ChineseRemainder[{2, 3, 2}, {3, 5, 7}] |
||
23</ |
23</syntaxhighlight> |
||
=={{header|MATLAB}} / {{header|Octave}}== |
=={{header|MATLAB}} / {{header|Octave}}== |
||
< |
<syntaxhighlight lang=MATLAB>function f = chineseRemainder(r, m) |
||
s = prod(m) ./ m; |
s = prod(m) ./ m; |
||
[~, t] = gcd(s, m); |
[~, t] = gcd(s, m); |
||
f = s .* t * r';</ |
f = s .* t * r';</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
< |
<syntaxhighlight lang=MATLAB>>> chineseRemainder([2 3 2], [3 5 7]) |
||
ans = 23</ |
ans = 23</syntaxhighlight> |
||
=={{header|Modula-2}}== |
=={{header|Modula-2}}== |
||
< |
<syntaxhighlight lang=modula2>MODULE CRT; |
||
FROM FormatString IMPORT FormatString; |
FROM FormatString IMPORT FormatString; |
||
FROM Terminal IMPORT WriteString,WriteLn,ReadChar; |
FROM Terminal IMPORT WriteString,WriteLn,ReadChar; |
||
Line 1,720: | Line 1,720: | ||
ReadChar |
ReadChar |
||
END CRT.</ |
END CRT.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
Line 1,726: | Line 1,726: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang=nim>proc mulInv(a0, b0: int): int = |
||
var (a, b, x0) = (a0, b0, 0) |
var (a, b, x0) = (a0, b0, 0) |
||
result = 1 |
result = 1 |
||
Line 1,749: | Line 1,749: | ||
sum mod prod |
sum mod prod |
||
echo chineseRemainder([3,5,7], [2,3,2])</ |
echo chineseRemainder([3,5,7], [2,3,2])</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>23</pre> |
<pre>23</pre> |
||
Line 1,755: | Line 1,755: | ||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
This is without the Jane Street Ocaml Core Library. |
This is without the Jane Street Ocaml Core Library. |
||
< |
<syntaxhighlight lang=ocaml> |
||
exception Modular_inverse |
exception Modular_inverse |
||
let inverse_mod a = function |
let inverse_mod a = function |
||
Line 1,779: | Line 1,779: | ||
with modular_inverse -> None |
with modular_inverse -> None |
||
</syntaxhighlight> |
|||
</lang> |
|||
This is using the Jane Street Ocaml Core library. |
This is using the Jane Street Ocaml Core library. |
||
< |
<syntaxhighlight lang=ocaml>open Core.Std |
||
open Option.Monad_infix |
open Option.Monad_infix |
||
Line 1,821: | Line 1,821: | ||
|> List.reduce_exn ~f:(+) |
|> List.reduce_exn ~f:(+) |
||
|> fun n -> let n' = n mod mod_pi in if n' < 0 then n' + mod_pi else n') |
|> fun n -> let n' = n mod mod_pi in if n' < 0 then n' + mod_pi else n') |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,832: | Line 1,832: | ||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
< |
<syntaxhighlight lang=parigp>chivec(residues, moduli)={ |
||
my(m=Mod(0,1)); |
my(m=Mod(0,1)); |
||
for(i=1,#residues, |
for(i=1,#residues, |
||
Line 1,839: | Line 1,839: | ||
lift(m) |
lift(m) |
||
}; |
}; |
||
chivec([2,3,2], [3,5,7])</ |
chivec([2,3,2], [3,5,7])</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
Pari's chinese function takes a vector in the form <tt>[Mod(a1,n1), Mod(a2, n2), ...]</tt>, so we can do this directly: |
Pari's chinese function takes a vector in the form <tt>[Mod(a1,n1), Mod(a2, n2), ...]</tt>, so we can do this directly: |
||
< |
<syntaxhighlight lang=parigp>lift( chinese([Mod(2,3),Mod(3,5),Mod(2,7)]) )</syntaxhighlight> |
||
or to take the residue/moduli array as above: |
or to take the residue/moduli array as above: |
||
< |
<syntaxhighlight lang=parigp>chivec(residues,moduli)={ |
||
lift(chinese(vector(#residues,i,Mod(residues[i],moduli[i])))) |
lift(chinese(vector(#residues,i,Mod(residues[i],moduli[i])))) |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
Line 1,854: | Line 1,854: | ||
Follows the Perl examples: (1) expresses each solution as a residue class; (2) if the moduli are not pairwise coprime, still finds a solution if there is one. |
Follows the Perl examples: (1) expresses each solution as a residue class; (2) if the moduli are not pairwise coprime, still finds a solution if there is one. |
||
< |
<syntaxhighlight lang=pascal> |
||
// Rosetta Code task "Chinese remainder theorem". |
// Rosetta Code task "Chinese remainder theorem". |
||
program ChineseRemThm; |
program ChineseRemThm; |
||
Line 1,981: | Line 1,981: | ||
ShowSolution([19, 0], [100, 23]); |
ShowSolution([19, 0], [100, 23]); |
||
end. |
end. |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,996: | Line 1,996: | ||
There are at least three CPAN modules for this: ntheory (Math::Prime::Util), Math::ModInt, and Math::Pari. All three handle bigints. |
There are at least three CPAN modules for this: ntheory (Math::Prime::Util), Math::ModInt, and Math::Pari. All three handle bigints. |
||
{{libheader|ntheory}} |
{{libheader|ntheory}} |
||
< |
<syntaxhighlight lang=perl>use ntheory qw/chinese/; |
||
say chinese([2,3], [3,5], [2,7]);</ |
say chinese([2,3], [3,5], [2,7]);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
The function returns undef if no common residue class exists. The combined modulus can be obtained using the <code>lcm</code> function applied to the moduli (e.g. <code>lcm(3,5,7) = 105</code> in the example above). |
The function returns undef if no common residue class exists. The combined modulus can be obtained using the <code>lcm</code> function applied to the moduli (e.g. <code>lcm(3,5,7) = 105</code> in the example above). |
||
< |
<syntaxhighlight lang=perl>use Math::ModInt qw(mod); |
||
use Math::ModInt::ChineseRemainder qw(cr_combine); |
use Math::ModInt::ChineseRemainder qw(cr_combine); |
||
say cr_combine(mod(2,3),mod(3,5),mod(2,7));</ |
say cr_combine(mod(2,3),mod(3,5),mod(2,7));</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>mod(23, 105)</pre> |
<pre>mod(23, 105)</pre> |
||
Line 2,011: | Line 2,011: | ||
=== Non-pairwise-coprime === |
=== Non-pairwise-coprime === |
||
All three modules will also handle cases where the moduli are not pairwise co-prime but a solution exists, e.g.: |
All three modules will also handle cases where the moduli are not pairwise co-prime but a solution exists, e.g.: |
||
< |
<syntaxhighlight lang=perl>use ntheory qw/chinese lcm/; |
||
say chinese( [2328,16256], [410,5418] ), " mod ", lcm(16256,5418);</ |
say chinese( [2328,16256], [410,5418] ), " mod ", lcm(16256,5418);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>28450328 mod 44037504</pre> |
<pre>28450328 mod 44037504</pre> |
||
Line 2,019: | Line 2,019: | ||
{{trans|C}} |
{{trans|C}} |
||
Uses the function mul_inv() from [[Modular_inverse#Phix]] (reproduced below) |
Uses the function mul_inv() from [[Modular_inverse#Phix]] (reproduced below) |
||
<!--< |
<!--<syntaxhighlight lang=Phix>(phixonline)--> |
||
<span style="color: #008080;">function</span> <span style="color: #000000;">mul_inv</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> |
<span style="color: #008080;">function</span> <span style="color: #000000;">mul_inv</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> |
||
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">n</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">n</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
||
Line 2,051: | Line 2,051: | ||
<span style="color: #0000FF;">?</span><span style="color: #000000;">chinese_remainder</span><span style="color: #0000FF;">({</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span><span style="color: #000000;">22</span><span style="color: #0000FF;">,</span><span style="color: #000000;">19</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">})</span> |
<span style="color: #0000FF;">?</span><span style="color: #000000;">chinese_remainder</span><span style="color: #0000FF;">({</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span><span style="color: #000000;">22</span><span style="color: #0000FF;">,</span><span style="color: #000000;">19</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">})</span> |
||
<span style="color: #0000FF;">?</span><span style="color: #000000;">chinese_remainder</span><span style="color: #0000FF;">({</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">23</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">19</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">})</span> |
<span style="color: #0000FF;">?</span><span style="color: #000000;">chinese_remainder</span><span style="color: #0000FF;">({</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">23</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">19</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">})</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,061: | Line 2,061: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang=PicoLisp>(de modinv (A B) |
||
(let (B0 B X0 0 X1 1 Q 0 T1 0) |
(let (B0 B X0 0 X1 1 Q 0 T1 0) |
||
(while (< 1 A) |
(while (< 1 A) |
||
Line 2,089: | Line 2,089: | ||
(chinrem (11 12 13) (10 4 12)) ) |
(chinrem (11 12 13) (10 4 12)) ) |
||
(bye)</ |
(bye)</syntaxhighlight> |
||
=={{header|Prolog}}== |
=={{header|Prolog}}== |
||
Created with SWI Prolog. |
Created with SWI Prolog. |
||
< |
<syntaxhighlight lang=prolog> |
||
product(A, B, C) :- C is A*B. |
product(A, B, C) :- C is A*B. |
||
Line 2,118: | Line 2,118: | ||
foldl(crt_fold, As, Ms, Ps, 0, N0), |
foldl(crt_fold, As, Ms, Ps, 0, N0), |
||
N is N0 mod M. |
N is N0 mod M. |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,135: | Line 2,135: | ||
above. Therefore, I had to write another version of the |
above. Therefore, I had to write another version of the |
||
Chinese Remainder Therorem |
Chinese Remainder Therorem |
||
< |
<syntaxhighlight lang=prolog> |
||
/* Chinese remainder Theorem: Input chinrest([2,3,2], [3,5,7], R). -----> R == 23 |
/* Chinese remainder Theorem: Input chinrest([2,3,2], [3,5,7], R). -----> R == 23 |
||
or chinrest([2,3], [5,13], R). ---------> R == 42 |
or chinrest([2,3], [5,13], R). ---------> R == 42 |
||
Line 2,200: | Line 2,200: | ||
S3 is S1-(Q*S2), |
S3 is S1-(Q*S2), |
||
a_b_p_s_(B,B1,P,S,P2-P3,S2-S3,GCD). |
a_b_p_s_(B,B1,P,S,P2-P3,S2-S3,GCD). |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 2,213: | Line 2,213: | ||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
< |
<syntaxhighlight lang=PureBasic>EnableExplicit |
||
DisableDebugger |
DisableDebugger |
||
DataSection |
DataSection |
||
Line 2,289: | Line 2,289: | ||
PrintData(?LBL_n3,?LBL_a3) |
PrintData(?LBL_n3,?LBL_a3) |
||
PrintN(Str(ChineseRem(?LBL_n3,?LBL_a3))) |
PrintN(Str(ChineseRem(?LBL_n3,?LBL_a3))) |
||
Input()</ |
Input()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>[( 2 . 3 )( 3 . 5 )( 2 . 7 )] |
<pre>[( 2 . 3 )( 3 . 5 )( 2 . 7 )] |
||
Line 2,301: | Line 2,301: | ||
===Procedural=== |
===Procedural=== |
||
====Python 2.7==== |
====Python 2.7==== |
||
< |
<syntaxhighlight lang=python># Python 2.7 |
||
def chinese_remainder(n, a): |
def chinese_remainder(n, a): |
||
sum = 0 |
sum = 0 |
||
Line 2,326: | Line 2,326: | ||
n = [3, 5, 7] |
n = [3, 5, 7] |
||
a = [2, 3, 2] |
a = [2, 3, 2] |
||
print chinese_remainder(n, a)</ |
print chinese_remainder(n, a)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
====Python 3.6==== |
====Python 3.6==== |
||
< |
<syntaxhighlight lang=python># Python 3.6 |
||
from functools import reduce |
from functools import reduce |
||
def chinese_remainder(n, a): |
def chinese_remainder(n, a): |
||
Line 2,359: | Line 2,359: | ||
n = [3, 5, 7] |
n = [3, 5, 7] |
||
a = [2, 3, 2] |
a = [2, 3, 2] |
||
print(chinese_remainder(n, a))</ |
print(chinese_remainder(n, a))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
Line 2,370: | Line 2,370: | ||
{{Trans|Haskell}} |
{{Trans|Haskell}} |
||
{{Works with|Python|3.7}} |
{{Works with|Python|3.7}} |
||
< |
<syntaxhighlight lang=python>'''Chinese remainder theorem''' |
||
from operator import (add, mul) |
from operator import (add, mul) |
||
Line 2,574: | Line 2,574: | ||
# MAIN --- |
# MAIN --- |
||
if __name__ == '__main__': |
if __name__ == '__main__': |
||
main()</ |
main()</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>Chinese remainder theorem: |
<pre>Chinese remainder theorem: |
||
Line 2,588: | Line 2,588: | ||
=={{header|R}}== |
=={{header|R}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang=rsplus>mul_inv <- function(a, b) |
||
{ |
{ |
||
b0 <- b |
b0 <- b |
||
Line 2,631: | Line 2,631: | ||
a <- c(2L, 3L, 2L) |
a <- c(2L, 3L, 2L) |
||
chinese_remainder(n, a)</ |
chinese_remainder(n, a)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
Line 2,641: | Line 2,641: | ||
Take a look in the "math/number-theory" package it's full of goodies! |
Take a look in the "math/number-theory" package it's full of goodies! |
||
URL removed -- I can't be doing the Dutch recaptchas I'm getting. |
URL removed -- I can't be doing the Dutch recaptchas I'm getting. |
||
< |
<syntaxhighlight lang=racket>#lang racket |
||
(require (only-in math/number-theory solve-chinese)) |
(require (only-in math/number-theory solve-chinese)) |
||
(define as '(2 3 2)) |
(define as '(2 3 2)) |
||
(define ns '(3 5 7)) |
(define ns '(3 5 7)) |
||
(solve-chinese as ns)</ |
(solve-chinese as ns)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
Line 2,653: | Line 2,653: | ||
{{trans|C}} |
{{trans|C}} |
||
{{works with|Rakudo|2015.12}} |
{{works with|Rakudo|2015.12}} |
||
<lang |
<syntaxhighlight lang=raku line># returns x where (a * x) % b == 1 |
||
sub mul-inv($a is copy, $b is copy) { |
sub mul-inv($a is copy, $b is copy) { |
||
return 1 if $b == 1; |
return 1 if $b == 1; |
||
Line 2,677: | Line 2,677: | ||
} |
} |
||
say chinese-remainder(3, 5, 7)(2, 3, 2);</ |
say chinese-remainder(3, 5, 7)(2, 3, 2);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
Line 2,683: | Line 2,683: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
===algebraic=== |
===algebraic=== |
||
< |
<syntaxhighlight lang=rexx>/*REXX program demonstrates Sun Tzu's (or Sunzi's) Chinese Remainder Theorem. */ |
||
parse arg Ns As . /*get optional arguments from the C.L. */ |
parse arg Ns As . /*get optional arguments from the C.L. */ |
||
if Ns=='' | Ns=="," then Ns= '3,5,7' /*Ns not specified? Then use default.*/ |
if Ns=='' | Ns=="," then Ns= '3,5,7' /*Ns not specified? Then use default.*/ |
||
Line 2,708: | Line 2,708: | ||
end /*x*/ |
end /*x*/ |
||
say 'no solution found.' /*oops, announce that solution ¬ found.*/</ |
say 'no solution found.' /*oops, announce that solution ¬ found.*/</syntaxhighlight> |
||
{{out|output|text= when using the default inputs:}} |
{{out|output|text= when using the default inputs:}} |
||
<pre> |
<pre> |
||
Line 2,718: | Line 2,718: | ||
===congruences sets=== |
===congruences sets=== |
||
< |
<syntaxhighlight lang=rexx>/*REXX program demonstrates Sun Tzu's (or Sunzi's) Chinese Remainder Theorem. */ |
||
parse arg Ns As . /*get optional arguments from the C.L. */ |
parse arg Ns As . /*get optional arguments from the C.L. */ |
||
if Ns=='' | Ns=="," then Ns= '3,5,7' /*Ns not specified? Then use default.*/ |
if Ns=='' | Ns=="," then Ns= '3,5,7' /*Ns not specified? Then use default.*/ |
||
Line 2,747: | Line 2,747: | ||
end /*x*/ |
end /*x*/ |
||
say 'no solution found.' /*oops, announce that solution ¬ found.*/</ |
say 'no solution found.' /*oops, announce that solution ¬ found.*/</syntaxhighlight> |
||
{{out|output|text= is identical to the 1<sup>st</sup> REXX version.}} <br><br> |
{{out|output|text= is identical to the 1<sup>st</sup> REXX version.}} <br><br> |
||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
Brute-force. |
Brute-force. |
||
< |
<syntaxhighlight lang=ruby> |
||
def chinese_remainder(mods, remainders) |
def chinese_remainder(mods, remainders) |
||
max = mods.inject( :* ) |
max = mods.inject( :* ) |
||
Line 2,761: | Line 2,761: | ||
p chinese_remainder([3,5,7], [2,3,2]) #=> 23 |
p chinese_remainder([3,5,7], [2,3,2]) #=> 23 |
||
p chinese_remainder([10,4,9], [11,22,19]) #=> nil |
p chinese_remainder([10,4,9], [11,22,19]) #=> nil |
||
</syntaxhighlight> |
|||
</lang> |
|||
Similar to above, but working with large(r) numbers. |
Similar to above, but working with large(r) numbers. |
||
< |
<syntaxhighlight lang=ruby> |
||
def extended_gcd(a, b) |
def extended_gcd(a, b) |
||
last_remainder, remainder = a.abs, b.abs |
last_remainder, remainder = a.abs, b.abs |
||
Line 2,792: | Line 2,792: | ||
p chinese_remainder([17353461355013928499, 3882485124428619605195281, 13563122655762143587], [7631415079307304117, 1248561880341424820456626, 2756437267211517231]) #=> 937307771161836294247413550632295202816 |
p chinese_remainder([17353461355013928499, 3882485124428619605195281, 13563122655762143587], [7631415079307304117, 1248561880341424820456626, 2756437267211517231]) #=> 937307771161836294247413550632295202816 |
||
p chinese_remainder([10,4,9], [11,22,19]) #=> nil |
p chinese_remainder([10,4,9], [11,22,19]) #=> nil |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
< |
<syntaxhighlight lang=rust>fn egcd(a: i64, b: i64) -> (i64, i64, i64) { |
||
if a == 0 { |
if a == 0 { |
||
(b, 0, 1) |
(b, 0, 1) |
||
Line 2,835: | Line 2,835: | ||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/9QZvFht/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/njcaS3BFT6GtaWT2cHiwXg Scastie (remote JVM)]. |
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/9QZvFht/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/njcaS3BFT6GtaWT2cHiwXg Scastie (remote JVM)]. |
||
< |
<syntaxhighlight lang=Scala>import scala.util.{Success, Try} |
||
object ChineseRemainderTheorem extends App { |
object ChineseRemainderTheorem extends App { |
||
Line 2,879: | Line 2,879: | ||
println(chineseRemainder(List(11, 22, 19), List(10, 4, 9))) |
println(chineseRemainder(List(11, 22, 19), List(10, 4, 9))) |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Seed7}}== |
=={{header|Seed7}}== |
||
< |
<syntaxhighlight lang=seed7>$ include "seed7_05.s7i"; |
||
include "bigint.s7i"; |
include "bigint.s7i"; |
||
Line 2,905: | Line 2,905: | ||
end for; |
end for; |
||
writeln(sum mod prod); |
writeln(sum mod prod); |
||
end func;</ |
end func;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,914: | Line 2,914: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Raku}} |
{{trans|Raku}} |
||
< |
<syntaxhighlight lang=ruby>func chinese_remainder(*n) { |
||
var N = n.prod |
var N = n.prod |
||
func (*a) { |
func (*a) { |
||
Line 2,924: | Line 2,924: | ||
} |
} |
||
say chinese_remainder(3, 5, 7)(2, 3, 2)</ |
say chinese_remainder(3, 5, 7)(2, 3, 2)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,934: | Line 2,934: | ||
{{works with|SQLite|3.34.0}} |
{{works with|SQLite|3.34.0}} |
||
< |
<syntaxhighlight lang=SQL>create temporary table inputs(remainder int, modulus int); |
||
insert into inputs values (2, 3), (3, 5), (2, 7); |
insert into inputs values (2, 3), (3, 5), (2, 7); |
||
Line 2,993: | Line 2,993: | ||
where |
where |
||
a=1 and multiplicative_inverse.id = inputs.modulus; |
a=1 and multiplicative_inverse.id = inputs.modulus; |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 2,999: | Line 2,999: | ||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
< |
<syntaxhighlight lang=swift>import Darwin |
||
/* |
/* |
||
Line 3,104: | Line 3,104: | ||
let x = crt(a,n) |
let x = crt(a,n) |
||
print(x)</ |
print(x)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,111: | Line 3,111: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang=tcl>proc ::tcl::mathfunc::mulinv {a b} { |
||
if {$b == 1} {return 1} |
if {$b == 1} {return 1} |
||
set b0 $b; set x0 0; set x1 1 |
set b0 $b; set x0 0; set x1 1 |
||
Line 3,128: | Line 3,128: | ||
expr {$sum % $prod} |
expr {$sum % $prod} |
||
} |
} |
||
puts [chineseRemainder {3 5 7} {2 3 2}]</ |
puts [chineseRemainder {3 5 7} {2 3 2}]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23</pre> |
<pre>23</pre> |
||
Line 3,134: | Line 3,134: | ||
=={{header|uBasic/4tH}}== |
=={{header|uBasic/4tH}}== |
||
{{trans|C}} |
{{trans|C}} |
||
<lang>@(000) = 3 : @(001) = 5 : @(002) = 7 |
<syntaxhighlight lang=text>@(000) = 3 : @(001) = 5 : @(002) = 7 |
||
@(100) = 2 : @(101) = 3 : @(102) = 2 |
@(100) = 2 : @(101) = 3 : @(102) = 2 |
||
Line 3,187: | Line 3,187: | ||
Return (c@ % b@) |
Return (c@ % b@) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,198: | Line 3,198: | ||
=={{header|VBA}}== |
=={{header|VBA}}== |
||
Uses the function mul_inv() from [[Modular_inverse#VBA]] |
Uses the function mul_inv() from [[Modular_inverse#VBA]] |
||
{{trans|Phix}}< |
{{trans|Phix}}<syntaxhighlight lang=vb>Private Function chinese_remainder(n As Variant, a As Variant) As Variant |
||
Dim p As Long, prod As Long, tot As Long |
Dim p As Long, prod As Long, tot As Long |
||
prod = 1: tot = 0 |
prod = 1: tot = 0 |
||
Line 3,221: | Line 3,221: | ||
Debug.Print chinese_remainder([{11,22,19}], [{10,4,9}]) |
Debug.Print chinese_remainder([{11,22,19}], [{10,4,9}]) |
||
Debug.Print chinese_remainder([{100,23}], [{19,0}]) |
Debug.Print chinese_remainder([{100,23}], [{19,0}]) |
||
End Sub</ |
End Sub</syntaxhighlight>{{out}} |
||
<pre> 23 |
<pre> 23 |
||
1000 |
1000 |
||
Line 3,229: | Line 3,229: | ||
=={{header|Visual Basic .NET}}== |
=={{header|Visual Basic .NET}}== |
||
{{trans|C#}} |
{{trans|C#}} |
||
< |
<syntaxhighlight lang=vbnet>Module Module1 |
||
Function ModularMultiplicativeInverse(a As Integer, m As Integer) As Integer |
Function ModularMultiplicativeInverse(a As Integer, m As Integer) As Integer |
||
Line 3,266: | Line 3,266: | ||
End Sub |
End Sub |
||
End Module</ |
End Module</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>23 = 2 (mod 3) |
<pre>23 = 2 (mod 3) |
||
Line 3,274: | Line 3,274: | ||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang=ecmascript>/* returns x where (a * x) % b == 1 */ |
||
var mulInv = Fn.new { |a, b| |
var mulInv = Fn.new { |a, b| |
||
if (b == 1) return 1 |
if (b == 1) return 1 |
||
Line 3,305: | Line 3,305: | ||
var n = [3, 5, 7] |
var n = [3, 5, 7] |
||
var a = [2, 3, 2] |
var a = [2, 3, 2] |
||
System.print(chineseRemainder.call(n, a))</ |
System.print(chineseRemainder.call(n, a))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,315: | Line 3,315: | ||
{{trans|Go}} |
{{trans|Go}} |
||
Using the GMP library, gcdExt is the Extended Euclidean algorithm. |
Using the GMP library, gcdExt is the Extended Euclidean algorithm. |
||
< |
<syntaxhighlight lang=zkl>var BN=Import("zklBigNum"), one=BN(1); |
||
fcn crt(xs,ys){ |
fcn crt(xs,ys){ |
||
Line 3,327: | Line 3,327: | ||
} |
} |
||
return(X % p); |
return(X % p); |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang=zkl>println(crt(T(3,5,7), T(2,3,2))); //-->23 |
||
println(crt(T(11,12,13),T(10,4,12))); //-->1000 |
println(crt(T(11,12,13),T(10,4,12))); //-->1000 |
||
println(crt(T(11,22,19), T(10,4,9))); //-->ValueError: 11 not coprime</ |
println(crt(T(11,22,19), T(10,4,9))); //-->ValueError: 11 not coprime</syntaxhighlight> |
||
=={{header|ZX Spectrum Basic}}== |
=={{header|ZX Spectrum Basic}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang=zxbasic>10 DIM n(3): DIM a(3) |
||
20 FOR i=1 TO 3 |
20 FOR i=1 TO 3 |
||
30 READ n(i),a(i) |
30 READ n(i),a(i) |
||
Line 3,357: | Line 3,357: | ||
1060 GO TO 1020 |
1060 GO TO 1020 |
||
1100 IF x1<0 THEN LET x1=x1+b0 |
1100 IF x1<0 THEN LET x1=x1+b0 |
||
1110 RETURN </ |
1110 RETURN </syntaxhighlight> |
||
<pre>23</pre> |
<pre>23</pre> |