トラック2・🧭プログラミング的思考

日常の問題をアルゴリズム化する

読む目安 約12分・ゴール:身近な問題を、抜けのない手順として書き下せるようになる

アプリでこのトピックを学ぶ(無料・登録不要)

このトピックの要点

道具は4つ揃いました。分解・パターン・抽象化・アルゴリズムです。ここでは実際に、日常の問題を機械が実行できる手順に落としてみます。これができれば、あとは文法を覚えるだけという段階に入ります。

例題1: 自動販売機のおつり

1000円を入れて150円の飲み物を買ったとき、850円のおつりを枚数が最も少なくなるように返す手順を考えます。

  1. おつり ← 投入金額 − 商品の値段
  2. 大きい硬貨から順に(500円、100円、50円、10円)次を繰り返す
  3. その硬貨でおつりを割った商の枚数だけ、その硬貨を出す
  4. おつり ← おつりを、その硬貨で割った余り
  5. おつりが0になったら終了

850円なら、500円が1枚(残り350)、100円が3枚(残り50)、50円が1枚(残り0)。合計5枚です。大きいものから順に取れるだけ取るというこの考え方には、貪欲法という名前が付いています。

ビット名前がついてるってことは、みんなが何度も使ってきた型ってことだよ。

例題2: じゃんけんの勝敗

自分と相手の手を受け取り、勝敗を返します。素直に書くと、組み合わせを9通り全部書くことになります。でもパターンを探すと、こう縮みます。

  1. 2つの手が同じなら「あいこ」
  2. 自分がグーで相手がチョキ、自分がチョキで相手がパー、自分がパーで相手がグー、のいずれかなら「勝ち」
  3. それ以外は「負け」

9通りが3通りになりました。先に例外(あいこ)を片づけると、残りが単純になる——これは実務でもよく効く型です。

例題3: 朝の準備を最短にする

ここには新しい観点が入ります。同時にできるかです。

順にやれば12分ですが、「お湯を沸かす」と「パンを焼く」を先に始めて、待つ間に顔を洗えば5分で済みます。プログラムの世界でも、待ち時間の間に別の仕事をする考え方があります(並行処理)。今は「順番の付け方で、かかる時間が変わる」ことだけ知っておいてください。

書けたら、必ず変な入力で試す

手順ができたら、意地の悪い入力を自分で当ててみてください。おつりの例なら「ちょうどの金額を入れた(おつり0円)」「1円足りない」「両替できる硬貨が切れている」。じゃんけんなら「グーとしか書かれていない入力」。普通の入力で動くのは当たり前で、変な入力で壊れないかが品質です。この習慣は、のちのセキュリティの話にまっすぐつながります。

共通する進め方

どの例題でも、やったことは同じです。

  1. 入力と出力をはっきりさせる(何をもらって、何を返すか)
  2. 大きい流れを分解する
  3. 繰り返せる部分・共通部分を見つける
  4. 例外(0円のとき、あいこ、在庫切れ)を洗い出す
  5. 擬似コードに落とす

この順番は、これから何度も使います。困ったら1に戻ってください。

アプリでこのトピックを学ぶ(無料・登録不要)

確認問題

確認問題 1

じゃんけんの勝敗を、9通りを全部書かずに3つの手順へ縮められたのは、どんな考え方によるものでしょう。

  1. 先に例外(あいこ)を片づけて、残りを「勝つ3パターン」と「それ以外」に分けた
  2. 勝ちのパターンだけを9通り書き、負けとあいこは書かないことにした
  3. 手の名前を数字に置き換えて、9通りを81通りに増やしてから整理した
  4. あいこは起こらないものとして無視した
答えを見る

正解:A(先に例外(あいこ)を片づけて、残りを「勝つ3パターン」と「それ以外」に分けた)

「同じ手ならあいこ」で3通りを先に取り除くと、残りは6通り。そのうち勝つ3パターンだけを書けば、残りは自動的に負けになります。これで9通りが3手順に縮みました。先に例外を片づけると残りが単純になる、という実務でもよく効く型です。ほかの選択肢は、場合を減らしていない(増やしている)か、判定できない場合を残してしまうので誤りです。

確認問題 2

「お湯を沸かす(5分・待つだけ)」「顔を洗う(3分・手が要る)」「パンを焼く(4分・待つだけ)」の3つを、待ち時間を活かして進めます。全部終わるまで最短で何分かかるでしょう。

  1. 12分
  2. 5分
  3. 7分
  4. 3分
答えを見る

正解:B(5分)

待つだけの2つ(お湯5分・パン4分)を先に始めてしまい、その待ち時間に顔を洗います(3分)。3分で顔が終わり、4分でパンが焼き上がり、5分でお湯が沸くので、いちばん長いお湯の5分ですべて終わります。1つずつ順にやれば 5 + 3 + 4 = 12分(選択肢の12分)ですが、それは待ち時間を捨てた場合です。7分・3分になる進め方はありません。順番の付け方しだいでかかる時間が変わる、というのがこの例題の要点です。

「プログラミング的思考」の目次

  1. 問題を分解する(Decomposition)
  2. パターンを見つける(Pattern Recognition)
  3. 抽象化——捨てる勇気
  4. アルゴリズム——手順を組み立てる
  5. 擬似コードで書いてみる
  6. フローチャート入門
  7. 日常の問題をアルゴリズム化する
  8. 良い手順・悪い手順——効率の予感

もっと先へ:ポインタ・メモリ・ファイル入出力・セキュアコーディングを含む全26トラックと、段位検定・模試のフルセットは完全版に収録しています。

完全版の販売ページは準備中です。

ほかのトラック

📚 姉妹教材:手を動かして覚える Linux 教材 — Linuxとインフラの仕組みを地図で学ぶ

Web版