Credit - CS50x 2026

Person holding credit cards

解くべき問題

クレジットカード(またはデビットカード)は、言うまでもなく、商品やサービスの支払いに使用できるプラスチック製のカードです。カードには番号が印字されており、その番号はどこかのデータベースにも保存されています。カードを使って何かを購入すると、債権者は誰に請求すべきかを知ることができます。世界中には多くの人がクレジットカードを持っているため、その番号は非常に長くなっています。American Expressは15桁、MasterCardは16桁、Visaは13桁または16桁の番号を使用しています。これらは2進数ではなく10進数(0から9)であるため、例えばAmerican Expressは、最大で 10^15 = 1,000,000,000,000,000 通りのユニークなカードを発行できることになります!(これは、ええと、1000兆です。)

実際には、これは少し誇張です。なぜなら、クレジットカード番号には実際にはいくつかの構造があるからです。すべてのAmerican Expressの番号は34または37で始まります。ほとんどのMasterCardの番号は51、52、53、54、または55で始まります(これ以外にも開始番号の可能性がありますが、この問題では考慮しません)。そして、すべてのVisaの番号は4で始まります。しかし、クレジットカード番号には「チェックサム」も組み込まれています。これは、少なくとも1つの数字と他の数字との間の数学的な関係です。そのチェックサムにより、コンピュータ(または数学が好きな人間)は、データベースに照会することなく、タイポ(例えば、数字の入れ替わり)や不正な番号を検出することができます。もちろん、不誠実な数学者であれば、数学的な制約を尊重しつつ偽の番号を作成することも可能であるため、より厳密なチェックには依然としてデータベースの検索が必要です。

creditというフォルダの中のcredit.cというファイルに、与えられたクレジットカード番号の有効性をチェックするCのプログラムを実装してください。

ルーンのアルゴリズム (Luhn’s Algorithm)

では、その秘密の公式とは何でしょうか?実は、ほとんどのカードはIBMのHans Peter Luhnによって発明されたアルゴリズムを使用しています。ルーンのアルゴリズムによれば、クレジットカード番号が(構文的に)有効であるかどうかを次のように判断できます。

  1. 番号の末尾から2番目の数字から始めて、1つ飛ばしにすべての数字を2倍し、それらの積の各桁を合計します。
  2. その合計に、2倍されなかった数字の合計を加えます。
  3. 合計の最後の桁が0である場合(より正式に言えば、合計を10で割った余りが0である場合)、その番号は有効です!

これは少し混乱するかもしれないので、DavidのVisaカード 4003600000000014 を例に試してみましょう。

  1. 説明のために、まず末尾から2番目の数字から始めて、1つ飛ばしに数字に下線を引いてみましょう。

    4003600000000014 (実際の下線部は: 400360000000001**4)

    下線を引いた各数字を2倍します。

    1•2 + 0•2 + 0•2 + 0•2 + 0•2 + 6•2 + 0•2 + 4•2

    これにより以下が得られます。

    2 + 0 + 0 + 0 + 0 + 12 + 0 + 8

    次に、これらの積の各桁(積そのものではなく、桁ごとの数字)を合計します。

    2 + 0 + 0 + 0 + 0 + 1 + 2 + 0 + 8 = 13

  2. 次に、その和(13)を、2倍されなかった数字(末尾から開始)の合計に加えます。

    13 + 4 + 0 + 0 + 0 + 0 + 0 + 3 + 0 = 20

  3. はい、その和(20)の最後の桁は0なので、Davidのカードは本物です!

クレジットカード番号の検証は難しくありませんが、手作業で行うと少し退屈です。プログラムを書きましょう。

実装の詳細

creditディレクトリのcredit.cというファイルに、ユーザーにクレジットカード番号の入力を促し、その形式の定義に従って、それが有効なAmerican Express、MasterCard、またはVisaのカード番号であるかどうかを(printfを介して)報告するプログラムを記述してください。プログラムのテストを自動化できるように、プログラムの出力の最後の行は AMEX\nMASTERCARD\nVISA\n、または INVALID\n のいずれかとし、それ以外は何も出力しないでください。簡略化のため、ユーザーの入力は完全に数値(つまり、実際のカードに印字されているようなハイフンは含まない)であり、先頭にゼロはないと仮定してかまいません。ただし、ユーザーの入力が int に収まるとは想定しないでください!ユーザーの入力を取得するには、CS50のライブラリの get_long を使用するのが最善です。(なぜでしょうか?)

有効なクレジットカード番号(ハイフンなし)を渡したときに、プログラムがどのように動作すべきかの代表的な例を以下に示します。

$ ./credit
Number: 4003600000000014
VISA

なお、get_long 自体がハイフン(およびそれ以外の文字)を拒否します。

$ ./credit
Number: 4003-6000-0000-0014
Number: foo
Number: 4003600000000014
VISA

しかし、数値であってもクレジットカード番号ではない入力(例:電話番号)をキャッチするのはあなた次第です。

$ ./credit
Number: 6176292929
INVALID

有効な番号と無効な番号の両方について、さまざまな入力でプログラムをテストしてください(私たちは間違いなくテストします!)。PayPalがテスト用に推奨しているいくつかのカード番号をここに示します。

プログラムがいずれかの入力で正しく動作しない場合(またはコンパイルすらできない場合)は、デバッグの時間です!

ウォークスルー (Walkthrough)

コードのテスト方法

以下を実行して、check50 を使用してコードの正確性を評価することもできます。ただし、必ず自分自身でもコンパイルしてテストしてください。

check50 cs50/problems/2026/x/credit

以下を実行して、style50 を使用してコードのスタイルを評価します。

style50 credit.c

提出方法

ターミナルで以下を実行して、課題を提出してください。

submit50 cs50/problems/2026/x/credit