基本情報技術者 2017年 春期 午前(科目A) 問06
問題文
関数が次のとおり定義されているとき、の値は幾らか。ここで、はをで割った余りを返す。
: if y = 0 then return x else return
選択肢
ア:0
イ:31(正解)
ウ:248
エ:527
🔒 解説は解答すると表示されます
ユークリッドの互除法【午前解説】
正解の理由
関数の定義は古典的なユークリッドの互除法です。手順どおりに計算すると次のようになります。
、次に 、さらに となり、余りが 0 になった時点で返される値は 31 です。よって正解は イ(31)です。
、次に 、さらに となり、余りが 0 になった時点で返される値は 31 です。よって正解は イ(31)です。
解法ステップ
- 関数定義を「互除法(gcd)」と認識する。条件分岐は で終了、そうでなければ再帰(交換して剰余)する。
- 具体的に剰余計算を順に行う:。
- 次に 。
- 次に となり、ここで 、関数は (この時点での )を返す。
- したがって答えは 31。
選択肢別の誤答解説
- ア: 0 — 関数が常に 0 を返すと思った誤り。実際は のときにその時点の を返すため、両方が 0 でない限り 0 にはなりません。
- イ: 正解(31) — 正しく互除法を最後まで実行した結果です。
- ウ: 248 — の最初の余りであり途中経過に過ぎません。再帰はさらに続きます。
- エ: 527 — 初期の第二引数 y をそのまま返す誤解です。y が 0 でなければ再帰が行われ、最終結果は変わります。
よくある誤解
- 「最初の余りを答えにしてしまう」: をそのまま答えと誤認する受験者が多いですが、関数はさらに再帰を続けます。
- 「0 を答えにする誤解」:再帰で になった時に返すのは であり、決して常に 0 を返すわけではありません。0 は両方が 0 の特殊ケース以外では現れません。
- 「大きい方(527)をそのまま答える誤り」:初期の y の値をそのまま返すように読み違えるケースがありますが、定義は y が 0 でない限り再帰を行います。
補足コラム
ユークリッドの互除法は最大公約数(GCD)を効率良く求める古典的手法で、計算量はおおよそ入力の桁数に対して対数オーダーです。再帰的定義の他、反復(ループ)で実装する方法や拡張ユークリッド互除法(ax+by = gcd)のように係数も求める拡張があり、暗号理論や数論で重要です。
簡単な Python 実装例(再帰と反復):
# 再帰版(問題と同じ定義)
def f(x, y):
if y == 0:
return x
return f(y, x % y)
# 反復版
def gcd(a, b):
while b != 0:
a, b = b, a % b
return a
print(f(775, 527)) # 31
print(gcd(775, 527)) # 31
FAQ
Q. 関数は必ず最大公約数を返しますか?
A. はい。非負整数に対するこの定義は常に最大公約数を返します。負の数や特殊な mod の定義だと注意が必要ですが、通常の剰余(非負の余り)を想定すれば成り立ちます。
A. はい。非負整数に対するこの定義は常に最大公約数を返します。負の数や特殊な mod の定義だと注意が必要ですが、通常の剰余(非負の余り)を想定すれば成り立ちます。
Q. 片方が 0 の場合はどうなりますか?
A. 定義どおり y=0 のときに x を返すので、gcd(x, 0) = |x|(非負を想定)となります。
A. 定義どおり y=0 のときに x を返すので、gcd(x, 0) = |x|(非負を想定)となります。
Q. なぜ 248 ではなく 31 が答えなのですか?
A. 248 は途中の余りであり、再帰はまだ続きます。最終的に余りが 0 になったときに返される直前の値が GCD(31)です。
A. 248 は途中の余りであり、再帰はまだ続きます。最終的に余りが 0 になったときに返される直前の値が GCD(31)です。
関連キーワード: ユークリッドの互除法、最大公約数、再帰関数、剰余演算、GCD、アルゴリズム分析

\ せっかくなら /
基本情報技術者を
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

