일차부정방정식 ax + by = c의 계수를 입력해 주세요. 아래 수식은 입력란과 연동되어 있어서 숫자 부분을 직접 고쳐도 계산할 수 있습니다. ‘구할 해의 범위’를 바꾸면 양의 정수해만 골라낼 수도 있습니다.
이 페이지에서 할 수 있는 것
- 정수 계수 \(a,\ b,\ c\)를 넣기만 하면 \(ax + by = c\)를 만족하는 정수의 쌍 \(x,\ y\)(정수해)를 구할 수 있습니다
- \(c\)가 \(a\)와 \(b\)의 최대공약수의 배수가 아니면 정수해가 없습니다. 그 판정과 왜 없는지에 대한 이유도 보여 줍니다
- 유클리드 호제법의 나눗셈 표와, 나머지를 거꾸로 따라가 특수해를 만드는 표를 한 줄씩 그대로 볼 수 있습니다
- 답은 1쌍만이 아니라 \(x = x_0 + \dfrac{b}{g}t,\ y = y_0 - \dfrac{a}{g}t\)(\(t\)는 정수)의 일반해와, \(t\)를 바꿔 가며 구한 정수해의 목록으로 보여 줍니다
- ‘양의 정수해만’, ‘0 이상의 정수해만’으로 좁힐 수 있습니다. 50 g짜리 추와 80 g짜리 추로 딱 1,000 g을 맞추는 조합을 구하는 문제를 그대로 풀 수 있습니다
이 계산은 어디에 쓰일까요?
50 g짜리와 80 g짜리 추만으로 딱 1,000 g을 맞추기, 두 종류의 쿠폰만으로 정해진 금액을 딱 맞추기, 정해진 길이의 자재만으로 딱 맞는 길이 만들기. 이런 ‘정해진 크기의 것을 조합해 목표에 딱 맞추는’ 문제는 그대로 \(ax + by = c\)의 정수해를 구하는 문제가 됩니다.
개수는 음수가 될 수 없으므로, 실제로는 양의 정수해를 골라내는 데까지 해야 비로소 답이 됩니다.
6개들이와 10개들이 상자만 있을 때 주문받은 개수를 딱 맞출 수 있는지는 \(6x + 10y = c\)에 0 이상의 정수해가 있는지로 정해집니다. 6과 10의 최대공약수는 2이므로, 홀수 개의 주문은 어떻게 조합해도 만들 수 없습니다.
식품이나 부품의 상자 포장에서는 이 ‘만들 수 있는 개수’를 가려내는 것이 주문을 받을 수 있는지, 어떤 크기의 상자를 갖춰야 하는지의 판단으로 바로 이어집니다.
5 L와 3 L 그릇만으로 4 L를 재는 유명한 문제는 \(5x + 3y = 4\)의 정수해에 대응합니다(\(x\), \(y\)는 각 그릇으로 붓은 횟수와 덜어 낸 횟수를 부호를 붙여 나타낸 것입니다). \(\gcd(5,\ 3) = 1\)이므로 이 두 그릇이 있으면 1 L 단위로 어떤 양이든 잴 수 있다는 것을 식으로 먼저 판정할 수 있습니다.
실험이나 요리에서 ‘가진 도구만으로 필요한 양을 만들 수 있을까’를 생각할 때 그대로 쓰이는 수학입니다.
인터넷 뱅킹과 온라인 쇼핑을 떠받치는 RSA 암호에서는 공개 키의 값 \(e\)로 비밀 키의 값 \(d\)를 만들 때 \(e d + \varphi k = 1\)이라는 일차부정방정식을 풉니다(\(\varphi\)는 키마다 정해지는 정수). 여기에 쓰이는 것이 이 페이지와 같은 확장 유클리드 호제법입니다.
몇백 자리나 되는 수라도 이 방법이라면 순식간에 풀 수 있다는 것이 암호를 실용적으로 만드는 토대 가운데 하나입니다.
1개에 재료를 \(a\) g 쓰는 제품 A와 \(b\) g 쓰는 제품 B를 만들어, 준비한 재료 \(c\) g을 딱 다 쓰고 싶다고 합시다. 이 계획은 \(ax + by = c\)의 0 이상의 정수해를 구하는 문제입니다. 제품을 0.5개만 만들 수는 없으므로 답은 정수여야 합니다.
이처럼 ‘답이 정수로 한정되는 계획 문제’를 다루는 분야를 정수 계획법이라고 하며, 생산 계획, 근무표 작성, 배송 계획 등에 쓰입니다.
공식과 그래프
용어·기호 해설
기호
| \(a,\ b\) | 에이, 비 | \(x\)와 \(y\)에 곱해진 계수입니다. 정해진 수를 나타낼 때는 알파벳 앞쪽의 문자 \(a,\ b,\ c\)를 쓰는 관례가 있습니다. 이 페이지에서는 둘 다 정수입니다. |
| \(c\) | 시 | 방정식 우변의 상수입니다. constant(상수)의 머리글자입니다. ‘만들고 싶은 합계’에 해당하는 수로, 이것이 최대공약수의 배수인지에 따라 해가 있는지가 정해집니다. |
| \(x,\ y\) | 엑스, 와이 | 구하려는 미지수입니다. 모르는 수를 알파벳 뒤쪽의 문자로 나타내는 방법은 데카르트가 널리 퍼뜨렸다고 합니다. 이 페이지에서는 정수 값만 답으로 다룹니다. |
| \(\gcd(a,\ b)\) | 지시디 에이 비 | \(a\)와 \(b\)의 최대공약수입니다. greatest common divisor(가장 큰 공약수)의 머리글자입니다. 정수론 책에서는 \((a,\ b)\)로 줄여 쓰기도 합니다. |
| \(g\) | 지 | 최대공약수 \(\gcd(a,\ b)\)를 짧게 쓴 기호입니다. greatest(가장 큰)의 머리글자입니다. 일반해의 \(\dfrac{b}{g}\), \(\dfrac{a}{g}\)처럼 식이 길어지지 않게 하려고 씁니다. |
| \(x_0,\ y_0\) | 엑스 영, 와이 영 | 특수해, 즉 처음 찾은 1쌍의 정수해입니다. ‘기준이 되는 0번째 해’라는 뜻으로 오른쪽 아래에 0을 붙입니다. 여기를 출발점으로 모든 정수해를 나타냅니다. |
| \(x_1,\ y_1\) | 엑스 일, 와이 일 | 호제법을 거꾸로 따라가면 찾을 수 있는 정수의 쌍으로, \(a x_1 + b y_1 = g\)를 만족합니다. 이것을 \(\dfrac{c}{g}\)배 하면 특수해 \((x_0,\ y_0)\)이 됩니다. |
| \(t\) | 티 | 정수라면 무엇이든 되는 변수(매개변수)입니다. 모든 정수해를 하나의 식으로 묶어 나타내려고 씁니다. \(t\)에 정수를 넣을 때마다 다른 정수해가 1쌍 나타납니다. |
| \(m\) | 엠 | ‘\(c\)가 \(g\)의 몇 배인지’를 나타내는 정수입니다. 정수를 나타내는 문자로는 \(m\), \(n\), \(k\)를 자주 쓰며, \(m\)은 multiple(배수)의 머리글자에서 왔다고 합니다. \(c = g \times m\)으로 쓸 수 있을 때, 그리고 그때에만 정수해가 있습니다. |
| \(q\) | 큐 | 나눗셈의 몫입니다. quotient(몫)의 머리글자입니다. 호제법의 표에서는 \(13 = 5 \times 2 + 3\)의 \(2\)에 해당합니다. |
| \(r\) | 알 | 나눗셈의 나머지입니다. remainder(나머지)의 머리글자입니다. 호제법의 표에서는 \(13 = 5 \times 2 + 3\)의 \(3\)에 해당합니다. 이 나머지가 0이 되었을 때 계산이 끝납니다. |
| \(\ge\) | 크거나 같다(이상) | ‘좌변이 우변 이상’임을 나타내는 부등호입니다. \(x \ge 1\)은 ‘\(x\)는 1 이상’이라는 뜻입니다. 짝이 되는 \(\le\)는 ‘작거나 같다(이하)’를 나타냅니다. |
용어
| 일차부정방정식 | \(ax + by = c\)처럼 미지수가 2개인데 식이 하나뿐인 일차방정식입니다. ‘부정’은 해가 하나로 정해지지 않는다는 뜻으로, 실수 범위라면 직선 위의 모든 점이 해가 됩니다. 정수해로 한정해도 보통은 무수히 많습니다. |
| 디오판토스 방정식 | 정수해만을 답으로 하는 방정식을 통틀어 부르는 이름입니다. 고대 그리스의 수학자 디오판토스의 이름에서 왔습니다. 이 페이지에서 다루는 일차부정방정식은 그중에서 가장 기본적인 것입니다. |
| 정수해 | 방정식을 만족하는 해 중에서 \(x\)도 \(y\)도 정수인 것입니다. 개수나 사람 수처럼 ‘딱 떨어지지 않을 수 없는 양’을 구하는 문제에서는 정수해만 의미가 있습니다. |
| 특수해 | 무수히 많은 정수해 중에서 처음 찾은 1쌍입니다. 어느 1쌍을 골라도 상관없습니다. 여기를 출발점으로 일반해의 꼴로 모든 해를 나타냅니다. |
| 일반해 | 모든 정수해를 정수 \(t\)를 써서 하나의 식으로 묶어 나타낸 것입니다. \(t\)에 정수를 넣으면 그때마다 다른 해를 1쌍 꺼낼 수 있습니다. |
| 최대공약수 | 2개 이상의 정수를 모두 나누어떨어지게 하는 자연수 중 가장 큰 수입니다. 일차부정방정식에서는 이 값이 ‘해가 있는지’와 ‘해와 해 사이의 간격’을 모두 정합니다. |
| 유클리드 호제법 | 큰 수를 작은 수로 나누고, 나누는 수와 나머지의 쌍으로 바꾸는 조작을 되풀이해 최대공약수를 구하는 방법입니다. 나머지가 0이 되었을 때의 나누는 수가 최대공약수입니다. 기원전 3세기쯤의 책 《원론》에 실려 있어 세계에서 가장 오래된 알고리즘이라고도 불립니다. |
| 확장 유클리드 호제법 | 호제법의 나눗셈 식을 아래부터 차례로 다시 대입해 최대공약수를 \(a x_1 + b y_1\)의 꼴로 나타내는 방법입니다. 일차부정방정식의 특수해를 만들 때 씁니다. |
| 베주 항등식 | \(a x_1 + b y_1 = \gcd(a,\ b)\)를 만족하는 정수 \(x_1,\ y_1\)이 반드시 있다는 정리입니다. 프랑스의 수학자 베주의 이름이 붙어 있습니다. 일차부정방정식을 풀 수 있다는 근거입니다. |
| 서로소 | 두 정수의 최대공약수가 1인 것입니다. 예를 들어 3과 4는 서로소입니다. \(\dfrac{a}{g}\)와 \(\dfrac{b}{g}\)는 반드시 서로소가 되며, 이것이 ‘해가 같은 간격으로 늘어선다’는 것의 결정적인 이유입니다. |
| 배수 | 어떤 정수를 정수배 해서 만들 수 있는 수입니다. \(10\)의 배수는 \(\dots,\ -20,\ -10,\ 0,\ 10,\ 20,\ \dots\)입니다. 0이나 음수도 배수에 넣습니다. |
| 나머지 | 정수의 나눗셈에서 나누어떨어지지 않고 남는 수입니다. \(13 \div 5\)는 몫이 \(2\), 나머지가 \(3\)입니다. 호제법은 이 나머지만을 써서 진행합니다. |
| 몫 | 정수의 나눗셈에서 ‘나누는 수가 몇 번 들어가는지’를 나타내는 정수입니다. \(13 = 5 \times 2 + 3\)의 \(2\)가 몫입니다. |
| 격자점 | 좌표평면 위에서 \(x\)좌표도 \(y\)좌표도 정수인 점입니다. 모눈종이의 칸이 만나는 점에 해당합니다. 일차부정방정식의 정수해는 직선 \(ax + by = c\) 위에 있는 격자점 그 자체입니다. |
| 매개변수 | 해의 모임 전체를 하나의 식으로 나타내려고 두는, 자유롭게 바꿀 수 있는 변수입니다. 이 페이지의 \(t\)가 그것입니다. 파라미터라고도 합니다. |
| 계수 | 문자 앞에 붙어 있는 수입니다. \(3x\)의 \(3\)이 계수입니다. 수가 쓰여 있지 않은 \(x\)의 계수는 1로 생각합니다. |
| 부등식 | \(t \ge 0\)처럼 두 값의 크기 관계를 나타내는 식입니다. 양의 정수해를 골라낼 때 씁니다. |
먼저 알아 두면 좋은 내용
이 페이지의 계산을 ‘뜻을 이해하고’ 쓸 수 있도록 먼저 알아 두면 좋은 내용을 정리했습니다.
막히면 이 표의 내용으로 돌아가 복습하는 것이 지름길입니다.
| 정수의 나눗셈과 나머지(초등학교 3학년~중학교 1학년, 8~13세) |
|
| 약수·배수·최대공약수(초등학교 5학년~중학교 1학년, 10~13세) |
|
| 문자와 식, 일차방정식(중학교 1학년, 12~13세) |
|
| 미지수가 2개인 일차방정식과 그 그래프(중학교 2학년, 13~14세) |
|
| 부등식(중학교 2학년~고등학교, 13~16세) |
|
| 분수의 계산(초등학교 5학년~중학교 1학년, 10~13세) |
|
Excel로 계산하는 방법
| x의 계수 a | 50 |
| y의 계수 b | 80 |
| 우변의 상수 c | 1000 |
| 최대공약수 g | =GCD(B1,B2) |
| c를 g로 나눈 나머지 | =MOD(B3,B4) |
| 정수해가 있는가 | =IF(B5=0,"정수해가 있음","정수해가 없음") |
| x의 계수 a | 50 |
| y의 계수 b | 80 |
| 호제법으로 찾은 x1 | -3 |
| 호제법으로 찾은 y1 | 2 |
| a×x1 + b×y1 | =B1*B3+B2*B4 |
| 최대공약수 g | =GCD(B1,B2) |
| x의 계수 a | 50 |
| y의 계수 b | 80 |
| 우변의 상수 c | 1000 |
| 최대공약수 g | =GCD(B1,B2) |
| 특수해 x0 | 4 |
| 특수해 y0 | 10 |
| 정수 t | 1 |
| x = x0 + (b/g)×t | =B5+(B2/B4)*B7 |
| y = y0 − (a/g)×t | =B6-(B1/B4)*B7 |
| 검산 a×x + b×y | =B1*B8+B2*B9 |
| x의 계수 a | 50 |
| y의 계수 b | 80 |
| 최대공약수 g | =GCD(B1,B2) |
| 특수해 x0 | 4 |
| 특수해 y0 | 10 |
| t의 하한(x ≥ 1에서) | =-INT((B4-1)/(B2/B3)) |
| t의 상한(y ≥ 1에서) | =INT((B5-1)/(B1/B3)) |
| 양의 정수해의 개수 | =MAX(0,B7-B6+1) |
첫 번째 표는 50x + 80y = 1000의 예로, 최대공약수는 10, 1000을 10으로 나눈 나머지는 0이므로 ‘정수해가 있음’이 표시됩니다. 여기를 1001로 바꾸면 ‘정수해가 없음’으로 바뀝니다.
두 번째 표는 호제법을 거꾸로 따라가 얻은 x1 = −3, y1 = 2가 정말로 베주 항등식을 만족하는지 확인하는 표입니다. 50×(−3) + 80×2 = 10이 되어 최대공약수와 같습니다.
세 번째 표는 일반해에서 해를 1쌍 꺼내는 표입니다. t에 1을 넣으면 x = 12, y = 5가 되고, 검산 행은 1000으로 돌아옵니다. t를 여러 정수로 바꿔 보세요.
네 번째 표는 양의 정수해를 골라내는 표입니다. t의 하한은 0, 상한은 1로 나오므로 양의 정수해는 2쌍(t = 0과 t = 1)임을 알 수 있습니다. 이 두 식은 a와 b가 모두 양수인 경우의 식이므로, 음수 계수를 넣을 때는 부등호의 방향이 바뀌는 점에 주의하세요.
Google 스프레드시트로 계산하는 방법
| x의 계수 a | 50 |
| y의 계수 b | 80 |
| 우변의 상수 c | 1000 |
| 최대공약수 g | =GCD(B1,B2) |
| c를 g로 나눈 나머지 | =MOD(B3,B4) |
| 정수해가 있는가 | =IF(B5=0,"정수해가 있음","정수해가 없음") |
| x의 계수 a | 50 |
| y의 계수 b | 80 |
| 호제법으로 찾은 x1 | -3 |
| 호제법으로 찾은 y1 | 2 |
| a×x1 + b×y1 | =B1*B3+B2*B4 |
| 최대공약수 g | =GCD(B1,B2) |
| x의 계수 a | 50 |
| y의 계수 b | 80 |
| 우변의 상수 c | 1000 |
| 최대공약수 g | =GCD(B1,B2) |
| 특수해 x0 | 4 |
| 특수해 y0 | 10 |
| 정수 t | 1 |
| x = x0 + (b/g)×t | =B5+(B2/B4)*B7 |
| y = y0 − (a/g)×t | =B6-(B1/B4)*B7 |
| 검산 a×x + b×y | =B1*B8+B2*B9 |
| x의 계수 a | 50 |
| y의 계수 b | 80 |
| 최대공약수 g | =GCD(B1,B2) |
| 특수해 x0 | 4 |
| 특수해 y0 | 10 |
| t의 하한(x ≥ 1에서) | =-INT((B4-1)/(B2/B3)) |
| t의 상한(y ≥ 1에서) | =INT((B5-1)/(B1/B3)) |
| 양의 정수해의 개수 | =MAX(0,B7-B6+1) |
Python으로 계산하는 방법
from math import gcd
# ax + by = c의 계수(정수)
a, b, c = 50, 80, 1000
def extended_gcd(x, y):
# 확장 유클리드 호제법: gcd와, x*s + y*t = gcd를 만족하는 s, t를 돌려준다
if y == 0:
return x, 1, 0
g, s, t = extended_gcd(y, x % y)
return g, t, s - (x // y) * t
g = gcd(a, b)
if c % g != 0:
print(f"우변 {c}: {g}의 배수가 아니므로 정수해가 없습니다")
else:
_, s, t = extended_gcd(a, b)
x0, y0 = s * (c // g), t * (c // g) # 특수해(정수해 1쌍)
step_x, step_y = b // g, a // g # x가 바뀌는 간격과 y가 바뀌는 간격
# x가 0 이상에서 가장 작아질 때까지 옮겨서 보기 쉬운 특수해로 고친다
n = x0 // step_x
x0, y0 = x0 - n * step_x, y0 + n * step_y
print(f"특수해: (x, y) = ({x0}, {y0})")
print(f"일반해: x = {x0} + {step_x}t, y = {y0} - {step_y}t (t는 정수)")
for k in range(-2, 3):
print(f" t = {k:2}: (x, y) = ({x0 + step_x * k}, {y0 - step_y * k})")
# 양의 정수해(x >= 1이고 y >= 1)만 꺼낸다
t_low = -((1 - x0) // -step_x)
t_high = (y0 - 1) // step_y
print("양의 정수해:", [(x0 + step_x * k, y0 - step_y * k)
for k in range(t_low, t_high + 1)])
LaTeX 등 수식 언어로 쓰는 법(복사 가능)
c = gcd(a, b) × m
c = \gcd(a, b) \times m
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<mrow>
<mi>c</mi>
<mo>=</mo>
<mi>gcd</mi><mo>(</mo><mi>a</mi><mo>,</mo><mi>b</mi><mo>)</mo>
<mo>×</mo>
<mi>m</mi>
</mrow>
</math>
c = gcd(a, b) * m
Mod[c, GCD[a, b]] == 0
irem(c, igcd(a, b)) = 0;
mod(c, gcd(a, b)) == 0
c = gcd(a,b) × m
a·x₁ + b·y₁ = gcd(a, b)
a x_1 + b y_1 = \gcd(a, b)
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<mrow>
<mi>a</mi><msub><mi>x</mi><mn>1</mn></msub>
<mo>+</mo>
<mi>b</mi><msub><mi>y</mi><mn>1</mn></msub>
<mo>=</mo>
<mi>gcd</mi><mo>(</mo><mi>a</mi><mo>,</mo><mi>b</mi><mo>)</mo>
</mrow>
</math>
a*x_1 + b*y_1 = gcd(a, b)
ExtendedGCD[a, b]
igcdex(a, b, x1, y1);
[g, x1, y1] = gcd(a, b);
a x_1 + b y_1 = gcd(a,b)
x = x₀ + (b/g)t, y = y₀ − (a/g)t
x = x_0 + \frac{b}{g} t, \quad y = y_0 - \frac{a}{g} t
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<mrow>
<mi>x</mi><mo>=</mo><msub><mi>x</mi><mn>0</mn></msub>
<mo>+</mo>
<mfrac><mi>b</mi><mi>g</mi></mfrac><mi>t</mi>
<mo>,</mo><mspace width="1em"/>
<mi>y</mi><mo>=</mo><msub><mi>y</mi><mn>0</mn></msub>
<mo>−</mo>
<mfrac><mi>a</mi><mi>g</mi></mfrac><mi>t</mi>
</mrow>
</math>
x = x_0 + (b/g)t, y = y_0 - (a/g)t
Solve[a x + b y == c, {x, y}, Integers]
isolve(a*x + b*y = c);
S = solve(a*x + b*y == c, [x y], 'Integer', true);
x = x_0 + (b/g)t, y = y_0 - (a/g)t
x₀ + (b/g)t ≥ 1, y₀ − (a/g)t ≥ 1
x_0 + \frac{b}{g} t \ge 1, \quad y_0 - \frac{a}{g} t \ge 1
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<mrow>
<msub><mi>x</mi><mn>0</mn></msub>
<mo>+</mo>
<mfrac><mi>b</mi><mi>g</mi></mfrac><mi>t</mi>
<mo>≥</mo><mn>1</mn>
<mo>,</mo><mspace width="1em"/>
<msub><mi>y</mi><mn>0</mn></msub>
<mo>−</mo>
<mfrac><mi>a</mi><mi>g</mi></mfrac><mi>t</mi>
<mo>≥</mo><mn>1</mn>
</mrow>
</math>
x_0 + (b/g)t >= 1 and y_0 - (a/g)t >= 1
Solve[a x + b y == c && x >= 1 && y >= 1, {x, y}, Integers]
isolve({a*x + b*y = c, x >= 1, y >= 1});
S = solve([a*x + b*y == c, x >= 1, y >= 1], [x y], 'Integer', true);
x_0 + (b/g)t ≥ 1, y_0 − (a/g)t ≥ 1
ChatGPT 에게 물어서 계산하는 방법
당신은 수학(정수의 성질) 계산 도우미입니다. 다음 계산을 반드시 Python 코드를 실제로 실행해서 하고, 실행 결과의 수치만을 근거로 답해 주세요(암산이나 추측으로 답하지 마세요). 일차부정방정식 50x + 80y = 1000의 정수해를 구해 주세요. 다음 내용을 각각 보여 주세요. 1. 50과 80의 최대공약수와, 1000이 그 배수인지 아닌지 2. 유클리드 호제법의 나눗셈 식(나머지가 0이 될 때까지)과, 그것을 거꾸로 따라가 얻는 50×x1 + 80×y1 = 최대공약수의 x1, y1 3. 특수해 (x0, y0)와 일반해 x = x0 + (b/g)t, y = y0 − (a/g)t 4. x와 y가 모두 1 이상인 정수해 전부 Python에서는 math.gcd와 확장 유클리드 호제법을 써서 정확하게 계산하고, 계산에 쓴 식과 실행 결과의 수치를 보여 주세요.
사용법
-
1숫자 입력계산하고 싶은 숫자를 입력란에 입력합니다
-
2계산‘계산’ 버튼을 누릅니다
-
3결과 확인계산 결과가 바로 표시됩니다. 계산의 원리와 공식 해설도 같은 페이지에서 확인할 수 있습니다
DataChef의 특징
전문 지식 없이도 직관적이고 간단하게 사용
개인정보를 등록하지 않고도 이용할 수 있습니다
"다운로드"를 누르면 파일이 자동으로 삭제됩니다
출처 표기 불필요
상업적 이용 허가 연락도 필요 없습니다