ITパスポート 令和4年度 問78:アルゴリズム・プログラミングに関する問題
関数checkDigitは、10進9桁の整数の各桁の数字が上位の桁から順に格納された整数型の配列originalDigitを引数として、次の手順で計算したチェックデジットを戻り値とする。プログラム中のaに入れる字句として、適切なものはどれか。ここで、配列の要素番号は1から始まる。 [手順] (1) 配列originalDigitの要素番号1〜9の要素の値を合計する。 (2) 合計した値が9より大きい場合は、合計した値を10進の整数で表現したときの各桁の数字を合計する。この操作を、合計した値が9以下になるまで繰り返す。 (3) (2)で得られた値をチェックデジットとする。 [プログラム] ○整数型:checkDigit(整数型の配列:originalDigit) 整数型:i、j、k j ← 0 for (i を 1 から originalDigitの要素数 まで 1 ずつ増やす) j ← j + originalDigit[i] endfor while (j が 9 より大きい) k ← j ÷ 10 の商 [a] endwhile return j
- aj ← j - 10 × k
- bj ← k + (j - 10 × k)正答
- cj ← k + (j - 10) × k
- dj ← k + j
AI解説(初心者・標準・上級)
理解度に合わせて3レベルの解説を無料で読めます。
答えは b です。
このプログラムは「2桁の数を、十の位と一の位にバラして足し合わせる」のがゴール。たとえば47なら、4+7=11、とする作業です。
`k ← j ÷ 10 の商` で、まず“十の位”だけ取り出します(47÷10の商=4)。残りの“一の位”は `j - 10×k`(47−40=7)で取れます。だから足すべきは「十の位 + 一の位」= `k + (j - 10×k)`。これが b です。
👉 覚え方:「÷10の商=十の位、引き算した残り=一の位、その2つを足す」。
なぜこれが正解か
正解は b。手順(2)は「合計値が9より大きい間、各桁の数字を足し直す」処理。whileループ内で `k ← j ÷ 10 の商` により十の位(kは商)を取り出している。一の位は `j - 10 × k`(元の値から十の位×10を引いた余り)で求まる。求める新しいjは「十の位+一の位」= `k + (j - 10 × k)` なので、aに入るのはb。
各選択肢の検討(例:j=47, k=4)
- a `j - 10×k` =7:一の位だけで十の位kを足し忘れ。誤り。
- b `k + (j - 10×k)` =4+7=11→正しく桁の和。
- c `k + (j-10)×k` =4+(37×4)=152:式が不正。
- d `k + j` =4+47=51:jを丸ごと足しており誤り。
覚え方・ひっかけ注意
「÷10の商=上位桁、−10×商=下位桁(=剰余)」。2桁の桁和は『商+剰余』。aは剰余だけ、dは商を二重カウントするひっかけ。
理論的背景
本問はチェックデジット計算アルゴリズムのプログラム穴埋め問題であり、正解bは「j ← k + (j - 10 × k)」である。アルゴリズムの目的は「10進9桁の各桁の数字の合計を計算し、合計が9より大きい場合は各桁に分解して再度合計する操作を9以下になるまで繰り返す」ことで、デジタルルート(Digital Root)とも呼ばれる数学的操作を実装している。
アルゴリズムの数学的根拠を分析する。jが9より大きい場合、kはj÷10の商(十の位以上の部分)、j - 10×kはjの一の位の数字(j mod 10)を表す。したがって「k + (j - 10 × k)」はjの十の位(k)と一の位(j - 10×k)を加算する処理であり、これが「各桁の数字の合計」の計算に相当する。具体例で確認すると、j=15の場合、k=15÷10=1(商)、j - 10×k=15 - 10=5(一の位)、k + (j-10×k)=1+5=6。さらにj=27の場合、k=2、j-10×k=7、2+7=9。これで正しく各桁の和が計算できる。
選択肢aの「j ← j - 10 × k」はjから十の位を除いた一の位のみ(余り)を新たなjとする処理であり、十の位の数値kを加算していないため誤り。選択肢dの「j ← k + j」はjに商を加えるだけで元のjの桁分解を行っていないため誤り(jが減少しない場合が生じる)。
実務での使われ方
チェックデジット(Check Digit)は誤り検出のために数値列の末尾に付加する検証用の数値であり、入力ミスや読み取りエラーを検出するために広く使われている。代表的な実用例として以下がある。①ISBN(国際標準図書番号):ISBN-13はGS1のLuhnアルゴリズム変形(奇数桁は1倍、偶数桁は3倍で重み付け合計し、10の補数)でチェックデジットを計算する。②JAN/EANバーコード:商品バーコードのチェックデジットもISBN-13と同じGS1アルゴリズムを使用。③Luhnアルゴリズム(1954年IBMのHans Luhnが考案):クレジットカード番号・社会保障番号等の検証に使われる最も普及したチェックデジットアルゴリズム。④マイナンバー(個人番号):日本の個人番号にもチェックデジットが組み込まれており、官公庁システムでの入力ミス検出に使われる。
本問のデジタルルート計算は「クレジットカード番号のLuhn検証前段階」「ISBN計算の変形版」として教育的に出題されており、プログラミングのアルゴリズム理解・ループ処理・変数の役割理解を総合的に問う設計になっている。
試験での位置づけ
ITパスポートのアルゴリズム・プログラミング分野でプログラムトレース問題(空欄に入る字句を選択)は最難度の問題類型の一つである。本問のアプローチとして「具体的な数値で選択肢a〜dを代入してトレース実行し、正しい結果が得られるものを選ぶ」という戦略が最も確実である。例えばj=15でトレースすると、a:j←15-10×1=5(次ループでj≦9となるが、15の桁の和は1+5=6なので誤り)、b:j←1+(15-10×1)=1+5=6(正しい桁の和)、と確認できる。
基本情報技術者(FE)ではより複雑なアルゴリズム問題(二分探索・ソートアルゴリズム・再帰処理・スタック・キュー・連結リスト等のデータ構造操作)と擬似言語(Pseudo-code)のトレース問題が大問として出題される。アルゴリズムの時間計算量(O記法:O(1)・O(log n)・O(n)・O(n log n)・O(n²))の理解も基本情報以上では必須となる知識である。
選択肢の発展補足
選択肢cの「j ← k + (j - 10) × k」は数式として「k + k×j - 10k」=「k(1+j-10)」「k(j-9)」となり、例えばj=15の場合k=1で1×(15-9)=6となって偶然正しい値が出る場合があるが、j=27の場合k=2で2×(27-9)=36となり全く正しくない。このように「特定の入力では偶然正しい値を出す誤ったアルゴリズム」を排除するためには複数のテストケースでトレースを行うことが重要であり、テスト設計の観点からも本問は良質な教育的内容を持つ。
デジタルルート(Digital Root)の数学的性質として「n のデジタルルートは n mod 9(ただし n が 9 の倍数のとき結果は 9)」という定理がある。これは9の剰余(剰余算術)の性質から導かれ、数秘術(Numerology)でも使われる古典的な数の性質である。プログラムで実装する際にこの性質を利用すれば「while ループなしの O(1) 計算」も可能だが、本問の問いはプログラムの空欄補充であるため、ループを使った逐次計算の理解が求められている。
出典:IPA(情報処理推進機構)公式 ITパスポート試験 令和4年度 問78/ 公的機関配布資料につき出典明記の上引用。解説は合格ナビによる独自AI解説です。