fork(1) download
  1. /**
  2.  * Modular Multiplicative Inverse: given A and m,
  3.  * find x = 1/A mod m, that is -
  4.  * find x such that: (x * A) mod m == 1.
  5.  *
  6.  * Modular Division: given A, B and m
  7.  * find z = A/B mod m, that is -
  8.  * find z such that: (z * B) mod m == A.
  9.  *
  10.  * @see http://e...content-available-to-author-only...a.org/wiki/Modular_multiplicative_inverse#Computation
  11.  *
  12.  * @author Erel Segal http://t...content-available-to-author-only...s.fm/rentabrain
  13.  * @date 2010-11-07
  14.  */
  15.  
  16. #include <iostream>
  17. #include <assert.h>
  18. using namespace std;
  19.  
  20. /**
  21.  * Euclid's extended algorithm:
  22.  * Given a,b, Find gcd,x,y that solve the equation:
  23.  * ax + by = gcd(a,b)
  24.  * @see http://e...content-available-to-author-only...a.org/wiki/Modular_multiplicative_inverse#Computation
  25.  */
  26. void xgcd (int a, int b,
  27. int& gcd, int& x, int& y) {
  28. x=0, y=1;
  29. int u=1, v=0, m, n, q, r;
  30. gcd = b;
  31. while (a!=0) {
  32. q=gcd/a; r=gcd%a;
  33. m=x-u*q; n=y-v*q;
  34. gcd=a; a=r; x=u; y=v; u=m; v=n;
  35. }
  36. }
  37.  
  38. /**
  39.  * Modular multiplicative inverse:
  40.  * Find x such that: x * A mod m == 1
  41.  * @see http://e...content-available-to-author-only...a.org/wiki/Modular_multiplicative_inverse#Computation
  42.  */
  43. int inverse (int A, int m) {
  44. assert (0 <= A && A < m);
  45. int gcd, x, y;
  46. xgcd (A, m, gcd, x, y); // x A + y m = gcd
  47. if (gcd==1) { // x A + y m = 1
  48. return (x+m) % m;
  49. } else {
  50. throw "no inverse";
  51. }
  52. }
  53.  
  54. /**
  55.  * Modular division:
  56.  * @return z such that: z * B mod m == A.
  57.  * If there is more than one (i.e. when gcd(A,m)>1) - returns the smaller (??)
  58.  */
  59. int divide (int A, int B, int m) {
  60. assert (0 <= A && A<m);
  61. assert (0 <= B && B<m);
  62.  
  63. int gcd, x, y;
  64. xgcd (B, m, gcd, x, y); // x B + y m = gcd(B,m)
  65. if (A%gcd == 0) {
  66. int q = A / gcd; // x q B + y q m = q gcd = A
  67. return ((x + m)*q) % (m/gcd); // Return the smallest result possible
  68. } else {
  69. throw "no quotient";
  70. }
  71. }
  72.  
  73.  
  74.  
  75.  
  76.  
  77.  
  78. void assertInverse(int Y, int m, int expected) {
  79. int a = inverse(Y, m);
  80. if (a!=expected) {
  81. cerr << "ERROR: " << 1 << " / " << Y << " [mod " << m << "] == " << expected << " but got " << a << endl;
  82. } else {
  83. cout << 1 << " / " << Y << " [mod " << m << "] == " << expected << endl;
  84. }
  85. }
  86.  
  87. void assertDivide(int X, int Y, int m, int expected) {
  88. int a = divide(X, Y, m);
  89. if (a!=expected) {
  90. cerr << "ERROR: " << X << " / " << Y << " [mod " << m << "] == " << expected << " but got " << a << endl;
  91. } else {
  92. cout << X << " / " << Y << " [mod " << m << "] == " << expected << endl;
  93. }
  94. }
  95.  
  96. void assertCycle (int Y, int m) {
  97. for (int Z=1, X=Y; Z<m && X!=0; Z+=1, X=(X+Y)%m) {
  98. assertDivide(X,Y,m,Z);
  99. }
  100. }
  101.  
  102. void assertCycles(int m) {
  103. for (int Y=1; Y<m; ++Y) {
  104. assertCycle(Y, m);
  105. }
  106. }
  107.  
  108.  
  109. int main() {
  110. assertInverse(1, 7, 1);
  111. assertInverse(2, 7, 4);
  112. assertInverse(3, 7, 5);
  113. assertInverse(4, 7, 2);
  114. assertInverse(5, 7, 3);
  115. assertInverse(6, 7, 6);
  116.  
  117. assertCycles(6);
  118. assertCycles(7);
  119. assertCycles(8);
  120. assertCycles(9);
  121. assertCycles(10);
  122. }
  123.  
  124.  
Success #stdin #stdout 0s 2728KB
stdin
Standard input is empty
stdout
1 / 1 [mod 7] == 1
1 / 2 [mod 7] == 4
1 / 3 [mod 7] == 5
1 / 4 [mod 7] == 2
1 / 5 [mod 7] == 3
1 / 6 [mod 7] == 6
1 / 1 [mod 6] == 1
2 / 1 [mod 6] == 2
3 / 1 [mod 6] == 3
4 / 1 [mod 6] == 4
5 / 1 [mod 6] == 5
2 / 2 [mod 6] == 1
4 / 2 [mod 6] == 2
3 / 3 [mod 6] == 1
4 / 4 [mod 6] == 1
2 / 4 [mod 6] == 2
5 / 5 [mod 6] == 1
4 / 5 [mod 6] == 2
3 / 5 [mod 6] == 3
2 / 5 [mod 6] == 4
1 / 5 [mod 6] == 5
1 / 1 [mod 7] == 1
2 / 1 [mod 7] == 2
3 / 1 [mod 7] == 3
4 / 1 [mod 7] == 4
5 / 1 [mod 7] == 5
6 / 1 [mod 7] == 6
2 / 2 [mod 7] == 1
4 / 2 [mod 7] == 2
6 / 2 [mod 7] == 3
1 / 2 [mod 7] == 4
3 / 2 [mod 7] == 5
5 / 2 [mod 7] == 6
3 / 3 [mod 7] == 1
6 / 3 [mod 7] == 2
2 / 3 [mod 7] == 3
5 / 3 [mod 7] == 4
1 / 3 [mod 7] == 5
4 / 3 [mod 7] == 6
4 / 4 [mod 7] == 1
1 / 4 [mod 7] == 2
5 / 4 [mod 7] == 3
2 / 4 [mod 7] == 4
6 / 4 [mod 7] == 5
3 / 4 [mod 7] == 6
5 / 5 [mod 7] == 1
3 / 5 [mod 7] == 2
1 / 5 [mod 7] == 3
6 / 5 [mod 7] == 4
4 / 5 [mod 7] == 5
2 / 5 [mod 7] == 6
6 / 6 [mod 7] == 1
5 / 6 [mod 7] == 2
4 / 6 [mod 7] == 3
3 / 6 [mod 7] == 4
2 / 6 [mod 7] == 5
1 / 6 [mod 7] == 6
1 / 1 [mod 8] == 1
2 / 1 [mod 8] == 2
3 / 1 [mod 8] == 3
4 / 1 [mod 8] == 4
5 / 1 [mod 8] == 5
6 / 1 [mod 8] == 6
7 / 1 [mod 8] == 7
2 / 2 [mod 8] == 1
4 / 2 [mod 8] == 2
6 / 2 [mod 8] == 3
3 / 3 [mod 8] == 1
6 / 3 [mod 8] == 2
1 / 3 [mod 8] == 3
4 / 3 [mod 8] == 4
7 / 3 [mod 8] == 5
2 / 3 [mod 8] == 6
5 / 3 [mod 8] == 7
4 / 4 [mod 8] == 1
5 / 5 [mod 8] == 1
2 / 5 [mod 8] == 2
7 / 5 [mod 8] == 3
4 / 5 [mod 8] == 4
1 / 5 [mod 8] == 5
6 / 5 [mod 8] == 6
3 / 5 [mod 8] == 7
6 / 6 [mod 8] == 1
4 / 6 [mod 8] == 2
2 / 6 [mod 8] == 3
7 / 7 [mod 8] == 1
6 / 7 [mod 8] == 2
5 / 7 [mod 8] == 3
4 / 7 [mod 8] == 4
3 / 7 [mod 8] == 5
2 / 7 [mod 8] == 6
1 / 7 [mod 8] == 7
1 / 1 [mod 9] == 1
2 / 1 [mod 9] == 2
3 / 1 [mod 9] == 3
4 / 1 [mod 9] == 4
5 / 1 [mod 9] == 5
6 / 1 [mod 9] == 6
7 / 1 [mod 9] == 7
8 / 1 [mod 9] == 8
2 / 2 [mod 9] == 1
4 / 2 [mod 9] == 2
6 / 2 [mod 9] == 3
8 / 2 [mod 9] == 4
1 / 2 [mod 9] == 5
3 / 2 [mod 9] == 6
5 / 2 [mod 9] == 7
7 / 2 [mod 9] == 8
3 / 3 [mod 9] == 1
6 / 3 [mod 9] == 2
4 / 4 [mod 9] == 1
8 / 4 [mod 9] == 2
3 / 4 [mod 9] == 3
7 / 4 [mod 9] == 4
2 / 4 [mod 9] == 5
6 / 4 [mod 9] == 6
1 / 4 [mod 9] == 7
5 / 4 [mod 9] == 8
5 / 5 [mod 9] == 1
1 / 5 [mod 9] == 2
6 / 5 [mod 9] == 3
2 / 5 [mod 9] == 4
7 / 5 [mod 9] == 5
3 / 5 [mod 9] == 6
8 / 5 [mod 9] == 7
4 / 5 [mod 9] == 8
6 / 6 [mod 9] == 1
3 / 6 [mod 9] == 2
7 / 7 [mod 9] == 1
5 / 7 [mod 9] == 2
3 / 7 [mod 9] == 3
1 / 7 [mod 9] == 4
8 / 7 [mod 9] == 5
6 / 7 [mod 9] == 6
4 / 7 [mod 9] == 7
2 / 7 [mod 9] == 8
8 / 8 [mod 9] == 1
7 / 8 [mod 9] == 2
6 / 8 [mod 9] == 3
5 / 8 [mod 9] == 4
4 / 8 [mod 9] == 5
3 / 8 [mod 9] == 6
2 / 8 [mod 9] == 7
1 / 8 [mod 9] == 8
1 / 1 [mod 10] == 1
2 / 1 [mod 10] == 2
3 / 1 [mod 10] == 3
4 / 1 [mod 10] == 4
5 / 1 [mod 10] == 5
6 / 1 [mod 10] == 6
7 / 1 [mod 10] == 7
8 / 1 [mod 10] == 8
9 / 1 [mod 10] == 9
2 / 2 [mod 10] == 1
4 / 2 [mod 10] == 2
6 / 2 [mod 10] == 3
8 / 2 [mod 10] == 4
3 / 3 [mod 10] == 1
6 / 3 [mod 10] == 2
9 / 3 [mod 10] == 3
2 / 3 [mod 10] == 4
5 / 3 [mod 10] == 5
8 / 3 [mod 10] == 6
1 / 3 [mod 10] == 7
4 / 3 [mod 10] == 8
7 / 3 [mod 10] == 9
4 / 4 [mod 10] == 1
8 / 4 [mod 10] == 2
2 / 4 [mod 10] == 3
6 / 4 [mod 10] == 4
5 / 5 [mod 10] == 1
6 / 6 [mod 10] == 1
2 / 6 [mod 10] == 2
8 / 6 [mod 10] == 3
4 / 6 [mod 10] == 4
7 / 7 [mod 10] == 1
4 / 7 [mod 10] == 2
1 / 7 [mod 10] == 3
8 / 7 [mod 10] == 4
5 / 7 [mod 10] == 5
2 / 7 [mod 10] == 6
9 / 7 [mod 10] == 7
6 / 7 [mod 10] == 8
3 / 7 [mod 10] == 9
8 / 8 [mod 10] == 1
6 / 8 [mod 10] == 2
4 / 8 [mod 10] == 3
2 / 8 [mod 10] == 4
9 / 9 [mod 10] == 1
8 / 9 [mod 10] == 2
7 / 9 [mod 10] == 3
6 / 9 [mod 10] == 4
5 / 9 [mod 10] == 5
4 / 9 [mod 10] == 6
3 / 9 [mod 10] == 7
2 / 9 [mod 10] == 8
1 / 9 [mod 10] == 9