1. x=3 -> (3+1)*2 = 8
  2. x=0 -> 2
  3. x=5 -> 12
  4. x=-1 -> 0
  5. x=10 -> 22
  6. x=-5 -> -8
コース一覧
コンピューターサイエンス上級:アルゴリズムとデータ構造
関数合成

コンピューターサイエンス上級:アルゴリズムとデータ構造

探索、ソート、木、グラフ、動的計画法、貪欲法など、競技プログラミングや技術面接で問われる高度なアルゴリズムとデータ構造を学べるコースです。基本的な CS の知識を持ち、アルゴリズム力を伸ばしたい学習者や、外資・大手の技術面接対策をしたい方を対象としています。約 13 時間 (1 日 30 分 × 26 日) で 50 レッスンを修了でき、修了後はコーディング面接の実装問題を構造的に解けるようになります。

1
連結リスト
01. リンクリスト構築と長さの計算5分
02. リンクリストの反転5分
03. リンクリストのサイクル検出5分
04. ソート済みリンクリストの merge5分
05. リンクリストの中央ノード取得5分
06. ソート済みリストの重複削除5分
07. 第1章まとめクイズ5分
2
二分木
01. 二分木の in-order 走査5分
02. 二分木の pre-order 走査5分
03. 二分木の post-order 走査5分
04. 二分木の幅優先走査 (BFS)5分
05. 二分木の高さ5分
06. 二分木の平衡判定5分
07. 第2章まとめクイズ — 二分木5分
3
探索木 (BST)
01. BST に値を挿入する5分
02. BST から値を検索する5分
03. BST の最小値と最大値5分
04. BST 妥当性チェック5分
05. BST で k 番目に小さい値5分
06. BST から値を削除する5分
07. 第 3 章 まとめクイズ5分
4
ハッシュとセット
01. hashmap で頻度集計5分
02. キーでグループ化5分
03. two sum (hash で O(n))5分
04. 部分配列の和 = k の個数5分
05. 最長連続部分列5分
06. 集合の積 (intersection)5分
07. 第4章まとめクイズ5分
5
グラフ
01. グラフ BFS で連結成分サイズを求める5分
02. グラフ DFS で連結成分の数を数える5分
03. グラフのパス存在判定5分
04. BFS で最短経路の長さを求める5分
05. トポロジカルソート5分
06. 2 部グラフ判定5分
07. ダイクストラ法 — 重み付きグラフの最短経路15分
08. 第5章まとめクイズ — グラフ5分
6
動的計画法 (上級)
01. 編集距離 (レーベンシュタイン距離)5分
02. 最長増加部分列(LIS)の解法 ── AOJ 2430 対応の動的計画法5分
03. 最大部分配列和 (Kadane)5分
04. 隣り合わない最大値 (House Robber)5分
05. グリッド経路数 (Unique Paths)5分
06. 単語分割可能か (Word Break)5分
07. 第6章まとめクイズ — 動的計画法 (上級)5分
7
総合データ構造と関数型
01. map と filter を組み合わせる5分
02. reduce で積を計算5分
03. 関数合成5分
04. カリー化5分
05. trie の単純検索 (prefix マッチ)5分
06. Union-Find (連結成分数)5分
07. 最終総まとめクイズ5分

関数合成

途中の結果に、毎回名前をつけている

記事のタイトルから URL 用の文字列を作るとします。前後の空白を落として、小文字にして、残った空白をハイフンに変える。素直に書くと、途中の結果に名前をつけ続けることになります。

JavaScript

const trimmed = trim(title); const lowered = toLower(trimmed); const slug = hyphenate(lowered);

trimmed にも lowered にも、それ自体の意味はありません。次の関数に渡すためだけの名前です。かといって入れ子にすると、今度は読む向きが逆になります。

JavaScript

hyphenate(toLower(trim(title)));

実際に動く順番は内側の trim からですが、目に入るのは外側の hyphenate からです。関数が 3 つならまだしも、5 つ 6 つと増えると、括弧の対応を数えながら内側へ潜ることになります。

小さい関数を並べて 1 本にする

やりたいのは「この 3 つを、この順に通す」だけです。関数を受け取って関数を返す部品を用意すると、並べた通りの 1 本の関数が手に入ります。

JavaScript

const chain = (...steps) => (value) => steps.reduce((acc, step) => step(acc), value); const slugify = chain(trim, toLower, hyphenate); slugify(" Hello World "); // "hello-world"

chain(...) が返すのは値ではなく関数です。ここで slugify という新しい関数が 1 つ増えたので、別の場所でそのまま呼べますし、map にそのまま渡すこともできます。部品の trim や toLower は単体でも使えるまま残っているので、組み合わせを変えれば別の変換もすぐ作れます。

つなぐときの条件は 1 つだけです。前の関数が返すものを、次の関数がそのまま受け取れること。文字列を返す関数の後ろに、配列を受け取る関数を置くとつながりません。部品を作るときに入口と出口を揃えておくと、後から自由に並べ替えられます。

並べる向きで結果が変わる

順番は飾りではありません。" Hello World " に対して、空白をハイフンに変えてから前後を落とすと --hello-world-- になり、前後を落としてから変えると hello-world になります。同じ 2 つの関数でも、向きが違えば別の結果です。

ここでつまずきやすいのが、向きの流儀が 2 つあることです。数学の記号 f ∘ g は「先に g、後で f」と読み、右から左に進みます。ライブラリの compose はこの記法に合わせてあり、pipe や flow は逆に、左から右へ書いた順に進みます。名前を見たら、どちらの向きかを先に確かめてください。自分で組み立てるときも、どちらの向きで受け取る部品なのかを決めてから中身を書きます。

解説

覚え方 ... compose は右から左、pipe は左から右。迷ったら 2 つの関数で試すと一発で分かる。

要件

  1. compose(f, g)(x) = f(g(x)) のように関数を組み立てる処理を内部に書くこと
  2. addOne(n) = n + 1, double(n) = n * 2 として、double を後に適用した結果を返す
  3. 戻り値は整数 (int)。式は (x + 1) * 2 と等価

入出力例

addOneThenDouble(3) → 8 addOneThenDouble(0) → 2 addOneThenDouble(5) → 12 addOneThenDouble(-1) → 0 addOneThenDouble(10) → 22 addOneThenDouble(-5) → -8

ヒント

compose は関数を返す関数。Python なら lambda v: f(g(v))、JS なら (v) => f(g(v)) を返す

compose(double, addOne) の順序に注意。後に書いた g (addOne) が先に呼ばれる

compose(...)(x) のように呼び出し括弧を忘れずに。compose の戻り値は関数なので、もう一段呼び出す必要がある

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • カリー化

    2 引数の関数を 1 引数の関数のチェーン `f(a)(b)` に変換するカリー化を内部で組み立てて適用する。`add(a, b)` をカリー化して `add(a)(b)` の形で呼び出した結果を返す関数を実装する。

  • trie の単純検索 (prefix マッチ)

    単語の集合に対して `trie` を構築し、与えられたプレフィックスで始まる単語が存在するかを判定する関数を実装する。trie の基本構造とプレフィックスマッチを学ぶ。

  • Union-Find (連結成分数)

    Union-Find (Disjoint Set Union) を使い、辺の集合からグラフの連結成分の数を求める関数を実装する。森のような構造でグループを管理する手法を学ぶ。

  • 最終総まとめクイズ

    cs-system-design コース全体の総まとめクイズ。連結リスト、二分木、BST、ハッシュ、グラフ、動的計画法、関数型の知識を確認する。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • URLページの住所全体
  • 関数処理に名前を付けて再利用できる単位
  • 配列サイズ固定の同型データの集まり
  • 処理計算や代入を表す長方形
  • 戻り値呼び出し元への返答を表す点線矢印
main.py
学習モード
エディタを読み込んでいます

メモ

関数合成

⌘S で保存