약수·배수, 소수, 진법, 모듈로 — 도구 네 가지를 암기하면 시험에서 시간을 버는 구간이 됩니다.
지문 신호“나누어떨어지는”“N진법”“나머지”
0/6 해결
1
눈으로 보기
재생을 누르고 단계별로 동작을 따라가세요
a
48
b
18
1/5유클리드 호제법으로 gcd(48, 18)를 구합니다. 원리: gcd(a, b) = gcd(b, a % b) — 나머지로 문제가 급격히 작아집니다.
막대 길이 = 수의 크기gcd(a, b) = gcd(b, a % b) 반복 — 수학 유형의 대표 도구
2
개념 이해
핵심 패턴 코드는 손으로 따라 쳐 보는 것을 권장
1 / 8
비유로 이해하기
가로 12cm, 세로 8cm짜리 종이를 똑같은 크기의 정사각형으로 빈틈없이 자르려면 한 변을 몇 cm로 해야 할까요. 4cm로 자르면 가로 3장, 세로 2장으로 딱 맞습니다. 이때 4를 손으로 하나씩 세어 찾지 않고, "긴 쪽에서 짧은 쪽을 계속 떼어내고 남은 조각만 다시 본다"는 규칙 하나로 찾아냅니다. 코테의 수학은 이런 식으로 직접 세는 대신 규칙으로 크기를 줄이는 일입니다.
코테 수학은 고등 수학이 아니라 정수론 기본기(약수·배수, 소수, 진법, 모듈로) + 규칙 발견입니다.
12 × 8 종이 → 8 × 8 정사각형을 떼면 → 4 × 8 조각이 남는다
4 × 8 조각 → 4 × 4를 두 번 떼면 → 남는 것이 없다 → 답은 4
위 종이를 자르는 규칙이 그대로 유클리드 호제법입니다. gcd(12, 8)을 손으로 따라가 봅니다.
단계
a
b
a % b
다음 상태
1
12
8
4
gcd(8, 4)
2
8
4
0
gcd(4, 0)
3
4
0
—
b가 0이므로 답은 4
두 번 만에 끝났습니다. 12부터 1까지 내려가며 나눠떨어지는지 확인했다면 12번 봐야 했을 일입니다. 수가 커질수록 이 차이가 그대로 시간 차이가 됩니다.
최소공배수도 같은 결과를 재활용합니다. lcm(12, 8) = (12 / 4) × 8 = 24 — 12와 8이 처음으로 다시 만나는 지점입니다.
나머지로 줄입니다 — 두 수의 최대공약수는 재귀 한 줄입니다.
const gcd = (a: number, b: number): number => (b === 0 ? a : gcd(b, a % b));
최소공배수는 나눗셈을 먼저 합니다 — a * b를 먼저 계산하면 값이 넘칠 수 있습니다.
const lcm = (a: number, b: number) => (a / gcd(a, b)) * b; // 오버플로 방지 순서
소수 판정은 √N까지만 봅니다 — i * i <= n 조건이 그 의미입니다.
function isPrime(n: number): boolean { if (n < 2) return false; for (let i = 2; i * i <= n; i++) if (n % i === 0) return false; return true;}
약수는 쌍으로 모읍니다 — i를 찾으면 n / i도 같이 얻습니다.
for (let i = 1; i * i <= n; i++) { if (n % i === 0) { divisors.push(i); if (i * i !== n) divisors.push(n / i); }}
전체 코드 — "두 톱니바퀴가 몇 바퀴 뒤에 처음 상태로 다시 맞물리는가":
function solution(a: number, b: number): { gcd: number; lcm: number; turnsA: number } { // 1단계: 나머지로 줄여 최대공약수 const gcd = (x: number, y: number): number => (y === 0 ? x : gcd(y, x % y)); const g = gcd(a, b); // 2단계: 나눗셈 먼저 하여 최소공배수 const l = (a / g) * b; // 두 톱니가 다시 맞물리는 이빨 수 = lcm, a는 그 사이 lcm / a 바퀴 돈다 return { gcd: g, lcm: l, turnsA: l / a };}
"몇 바퀴 뒤에 다시 만나는가", "동시에 출발한 두 신호가 겹치는 시점" — 최소공배수 신호입니다.
"똑같이 나눠 담기", "가장 큰 정사각형으로 자르기", "남김없이 묶기" — 최대공약수 신호입니다.
"N 이하의 소수", "약수의 개수", "완전수" — 소수·약수 도구를 그대로 씁니다.
"1,000,000,007로 나눈 나머지를 반환" — 답이 커진다는 뜻이며, 매 연산마다 모듈로를 적용하라는 지시입니다.
"원형으로 배치", "요일", "시계 방향으로 k칸" — 모듈로 순환 신호입니다.
입력 범위가 10억, 1조처럼 크고 반복문으로는 도저히 못 도는 경우 — 세지 말고 식으로 줄이라는 뜻입니다.
필수 도구 네 가지는 외워두면 이 유형이 시간 벌이 구간이 됩니다.
// 1) 최대공약수 — 유클리드 호제법const gcd = (a: number, b: number): number => (b === 0 ? a : gcd(b, a % b));const lcm = (a: number, b: number) => (a / gcd(a, b)) * b; // 오버플로 방지 순서
// 2) 소수 판정 — √N까지만function isPrime(n: number): boolean { if (n < 2) return false; for (let i = 2; i * i <= n; i++) if (n % i === 0) return false; return true;}// 범위 내 모든 소수 → 에라토스테네스의 체 O(N log log N)
// 3) 약수 나열 — √N까지 쌍으로for (let i = 1; i * i <= n; i++) { if (n % i === 0) { divisors.push(i); if (i * i !== n) divisors.push(n / i); }}