Chinese remainder theorem: Difference between revisions
Content added Content deleted
m (→congruences sets: added comments and changed whitespace.) |
(added Crystal implementation (translation of Ruby implementation)) |
||
Line 512: | Line 512: | ||
(INVMOD 418 11) |
(INVMOD 418 11) |
||
0] |
0] |
||
</pre> |
|||
=={{Header|Crystal}}== |
|||
{{trans|Ruby}} |
|||
<lang crystal>def extended_gcd(a, b) |
|||
last_remainder, remainder = a.abs, b.abs |
|||
x, last_x, y, last_y = 0, 1, 1, 0 |
|||
until remainder == 0 |
|||
tmp = remainder |
|||
quotient, remainder = last_remainder.divmod(remainder) |
|||
last_remainder = tmp |
|||
x, last_x = last_x - quotient * x, x |
|||
y, last_y = last_y - quotient * y, y |
|||
end |
|||
return last_remainder, last_x * (a < 0 ? -1 : 1) |
|||
end |
|||
def invmod(e, et) |
|||
g, x = extended_gcd(e, et) |
|||
unless g == 1 |
|||
raise "Multiplicative inverse modulo does not exist" |
|||
end |
|||
return x % et |
|||
end |
|||
def chinese_remainder(mods, remainders) |
|||
max = mods.reduce { |acc, i| acc * i } |
|||
series = remainders.zip(mods).map { |r, m| r * max * invmod(max // m, m) // m } |
|||
return series.sum % max |
|||
end |
|||
puts chinese_remainder([3, 5, 7], [2, 3, 2]) |
|||
puts chinese_remainder([5, 7, 9, 11], [1, 2, 3, 4]) |
|||
</lang> |
|||
'''Output:''' |
|||
<pre> |
|||
23 |
|||
1731 |
|||
</pre> |
</pre> |
||