Skip to content

Commit 7640353

Browse files
committed
docs: 확장 유클리드 알고리즘 설명 수정
1 parent 45118a1 commit 7640353

File tree

1 file changed

+36
-36
lines changed

1 file changed

+36
-36
lines changed

_posts/2024-03-06-modular-arithmetic.md

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -78,37 +78,41 @@ $3⁻¹\,mod\;11 = 3¹¹⁻²\,mod\;11=3⁹\,mod\;11=19683\,mod\;11=4$
7878

7979
확장 유클리드 알고리즘(Extended Euclidean Algorithm)을 활용하여 모듈러 역원을 구할 수 있습니다.
8080

81-
$a\times x+m\times y=gcd(a,m)$ 에서 <b>gcd가 1일 때(=a와 m이 서로소)</b>의 x 값이 a의 역원입니다.
81+
$a\times x+m\times y=gcd(a,m)$ 에서 <b>gcd가 1일 때(=a와 m이 서로소)의 x 값이 a의 역원</b>입니다.
8282

8383
$3x+11y=1$
8484

8585
$x=-7,\,y=2$
8686

87+
$x=4,\,y=-1$
88+
8789
$(-7)\,mod\;11=4\,mod\;11=4$
8890

8991
```javascript
90-
const modInverse = (a, m) => {
91-
if (m === 1) {
92-
return 0;
93-
}
92+
const extendedGCD = (a, b) => {
93+
if (b === 0) {
94+
return { gcd: a, x: 1, y: 0 };
95+
} else {
96+
const { gcd, x: x1, y: y1 } = extendedGCD(b, a % b);
9497

95-
const m0 = m;
96-
let x0 = 0;
97-
let x1 = 1;
98+
const x = y1;
99+
const y = x1 - Math.floor(a / b) * y1;
98100

99-
while (a > 1) {
100-
const q = Math.floor(a / m);
101-
[a, m] = [m, a % m];
102-
[x0, x1] = [x1 - q * x0, x0];
101+
return { gcd, x, y };
103102
}
103+
};
104104

105-
if (x1 < 0) {
106-
x1 += m0;
105+
const modInverse = (a, m) => {
106+
const { gcd, x } = extendedGCD(a, m);
107+
108+
// 모듈러 역원이 존재하지 않는 경우 -1 리턴.
109+
if (gcd !== 1) {
110+
return -1;
107111
}
108-
return x1;
109-
};
110112

111-
console.log(modInverse(3, 11)); // 4
113+
// 음수인 경우 양수로 조정.
114+
return ((x % m) + m) % m;
115+
};
112116
```
113117

114118
## Example
@@ -164,36 +168,32 @@ console.log(modInverse(3, 11)); // 4
164168
// 1 <= A < N
165169
const [N, A] = input.split(" ").map(Number);
166170

167-
const gcd = (a, b) => {
171+
const extendedGCD = (a, b) => {
168172
if (b === 0) {
169-
return a;
173+
return { gcd: a, x: 1, y: 0 };
170174
} else {
171-
return gcd(b, a % b);
175+
const { gcd, x: x1, y: y1 } = extendedGCD(b, a % b);
176+
177+
const x = y1;
178+
const y = x1 - Math.floor(a / b) * y1;
179+
180+
return { gcd, x, y };
172181
}
173182
};
174183

175184
const modInverse = (a, m) => {
176-
if (m === 1) {
177-
return 0;
178-
}
179-
180-
const m0 = m;
181-
let x0 = 0;
182-
let x1 = 1;
185+
const { gcd, x } = extendedGCD(a, m);
183186

184-
while (a > 1) {
185-
const q = Math.floor(a / m);
186-
[a, m] = [m, a % m];
187-
[x0, x1] = [x1 - q * x0, x0];
187+
// 모듈러 역원이 존재하지 않는 경우 -1 리턴.
188+
if (gcd !== 1) {
189+
return -1;
188190
}
189191

190-
if (x1 < 0) {
191-
x1 += m0;
192-
}
193-
return x1;
192+
// 음수인 경우 양수로 조정.
193+
return ((x % m) + m) % m;
194194
};
195195

196-
console.log(N - A, gcd(A, N) === 1 ? modInverse(A, N) : -1);
196+
console.log(N - A, extendedGCD(A, N).gcd === 1 ? modInverse(A, N) : -1);
197197
```
198198

199199
## 참고 자료

0 commit comments

Comments
 (0)