1.4.1. 最大公約数

最大公約数とは

Greatest common divisor (Wikipedea)

2つ以上の整数の公約数のうち、最も大きい数のことをいう。
例えば \(12, 18, 24\) の公約数は \(1, 2, 3, 6\) であり、最大公約数は \(6\) である。

法則

最大公約数は交換則と結合則が成り立つ。

  • 交換則 \(\gcd(a, b) = \gcd(b, a)\)

  • 結合則 \(\gcd(a, \gcd(b, c)) = \gcd(\gcd(a, b), c)\)

また、次の法則が成り立つ。これらはユークリッドの互除法の要である。

  • \(\gcd(a, 0) = a\)

  • \(\gcd(a, b) = \gcd(b, a \bmod b) \quad (a > b)\)

ユークリッドの互除法

ユークリッドの互除法は、2つの整数の最大公約数を求めるアルゴリズム。

自然数 \(a, b \quad (a > b)\) について \(\gcd(a, b) = \gcd(b, a \bmod b)\) が成り立つことを利用する。
常に \(a \geq b\) となるよう \(a, b\) を入れ替えつつ上式を再帰的に適用すると、剰余 \(r'\)\(0\)になったときの除数 \(b'\) が最大公約数となる。

例えば、\(\gcd(12, 18)=6\) の導出過程は次の通り。

\[\begin{split}\begin{eqnarray} \gcd(12, 18) &=& \gcd(18, 12) \\ &=& \gcd(12, 18 \bmod 12) = \gcd(12, 6) \\ &=& \gcd(6, 12 \bmod 6) = \gcd(6, 0) \\ &=& 6 \\ \end{eqnarray}\end{split}\]
上式では最初に交換則を適用したが、次式のように剰余をとることでも交換ができる。
これにより、 \(a, b\) の大小関係を考慮する必要がなくなる。
\[\gcd(12, 18) = \gcd(18, 12 \bmod 18) = \gcd(18, 12)\]

実装

概要

複数の整数の最大公約数を求める。

実装のポイント

Python3.8以下では math.gcd が2引数しかとれないため、3引数以上でも計算できるようにした。

計算量

  • gcd(a, b) \(\mathcal{O}(\log{\min(a, b)})\)

コード

[1]:
def gcd(a: int, *args: int) -> int:
    for b in args:
        while b > 0:
            a, b = b, a % b
    return a

使用例

[2]:
g = gcd(12, 18, 24)
print(g)
6