diff --git a/Shell/Bash/Leetcode/192. Word Frequency/WordFrequency.ipynb b/Shell/Bash/Leetcode/192. Word Frequency/WordFrequency.ipynb
new file mode 100644
index 00000000..f2887c90
--- /dev/null
+++ b/Shell/Bash/Leetcode/192. Word Frequency/WordFrequency.ipynb
@@ -0,0 +1,363 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "43f342e3",
+ "metadata": {},
+ "source": [
+ "# 192. Word Frequency - Bash解法\n",
+ "\n",
+ "## 問題概要\n",
+ "\n",
+ "テキストファイル `words.txt` から各単語の出現頻度を集計し、頻度の降順で出力する問題です。\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## 解答(スクリプト版)\n",
+ "\n",
+ "`wordfreq.sh`(Bash, POSIX ツールのみ)\n",
+ "\n",
+ "```bash\n",
+ "#!/usr/bin/env bash\n",
+ "set -euo pipefail\n",
+ "\n",
+ "# 使い方: ./wordfreq.sh [path/to/words.txt]\n",
+ "# 引数が未指定なら ./words.txt を読む\n",
+ "input=\"${1:-words.txt}\"\n",
+ "\n",
+ "# 1) 全ての空白(スペース/タブ/改行など)を改行にし、連続空白は1つに圧縮\n",
+ "# 2) ソート\n",
+ "# 3) uniq -c で頻度集計\n",
+ "# 4) 頻度(第1列)で数値降順ソート\n",
+ "# 5) \"単語 頻度\" の並びに整形\n",
+ "LC_ALL=C tr -s '[:space:]' '\\n' < \"$input\" \\\n",
+ " | sort \\\n",
+ " | uniq -c \\\n",
+ " | sort -nr \\\n",
+ " | awk '{print $2, $1}'\n",
+ "```\n",
+ "\n",
+ "### 実行方法\n",
+ "\n",
+ "```bash\n",
+ "chmod +x wordfreq.sh\n",
+ "./wordfreq.sh # カレントの words.txt を集計\n",
+ "# もしくは\n",
+ "./wordfreq.sh /path/to/words.txt\n",
+ "```\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## 解答(パイプのみの1行版)\n",
+ "\n",
+ "```bash\n",
+ "LC_ALL=C tr -s '[:space:]' '\\n' < words.txt | sort | uniq -c | sort -nr | awk '{print $2, $1}'\n",
+ "```\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## 入出力例\n",
+ "\n",
+ "### 入力 (`words.txt`)\n",
+ "\n",
+ "```text\n",
+ "the day is sunny the the\n",
+ "the sunny is is\n",
+ "```\n",
+ "\n",
+ "### 出力\n",
+ "\n",
+ "```text\n",
+ "the 4\n",
+ "is 3\n",
+ "sunny 2\n",
+ "day 1\n",
+ "```\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## 処理フロー図解\n",
+ "\n",
+ "```mermaid\n",
+ "flowchart LR\n",
+ " A[\"words.txt
入力ファイル\"] --> B[\"tr -s [:space:] \\\\n
全ての空白→改行
連続空白を1つに圧縮\"]\n",
+ " B --> C[\"sort
辞書順整列\"]\n",
+ " C --> D[\"uniq -c
連続同一語をカウント\"]\n",
+ " D --> E[\"sort -nr
頻度で降順ソート\"]\n",
+ " E --> F[\"awk {print $2, $1}
「単語 頻度」形式に整形\"]\n",
+ " F --> G[\"結果出力\"]\n",
+ "```\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## ステップ別の処理詳細\n",
+ "\n",
+ "### 入力データ\n",
+ "\n",
+ "```text\n",
+ "the day is sunny the the\n",
+ "the sunny is is\n",
+ "```\n",
+ "\n",
+ "### ステップ1: `tr -s '[:space:]' '\\n'`\n",
+ "\n",
+ "全ての空白文字(スペース・タブ・改行)を改行に変換し、連続する空白は1つに圧縮します。\n",
+ "\n",
+ "```text\n",
+ "the\n",
+ "day\n",
+ "is\n",
+ "sunny\n",
+ "the\n",
+ "the\n",
+ "the\n",
+ "sunny\n",
+ "is\n",
+ "is\n",
+ "```\n",
+ "\n",
+ "### ステップ2: `sort`\n",
+ "\n",
+ "単語を辞書順に整列します(`uniq -c` は連続した同一行のみカウントするため必須)。\n",
+ "\n",
+ "```text\n",
+ "day\n",
+ "is\n",
+ "is\n",
+ "is\n",
+ "sunny\n",
+ "sunny\n",
+ "the\n",
+ "the\n",
+ "the\n",
+ "the\n",
+ "```\n",
+ "\n",
+ "### ステップ3: `uniq -c`\n",
+ "\n",
+ "連続する同一単語をカウントします。\n",
+ "\n",
+ "```text\n",
+ " 1 day\n",
+ " 3 is\n",
+ " 2 sunny\n",
+ " 4 the\n",
+ "```\n",
+ "\n",
+ "### ステップ4: `sort -nr`\n",
+ "\n",
+ "頻度(第1列)で数値降順ソートします。\n",
+ "\n",
+ "```text\n",
+ " 4 the\n",
+ " 3 is\n",
+ " 2 sunny\n",
+ " 1 day\n",
+ "```\n",
+ "\n",
+ "### ステップ5: `awk '{print $2, $1}'`\n",
+ "\n",
+ "「単語 頻度」の形式に整形します。\n",
+ "\n",
+ "```text\n",
+ "the 4\n",
+ "is 3\n",
+ "sunny 2\n",
+ "day 1\n",
+ "```\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## アルゴリズムの解説\n",
+ "\n",
+ "### なぜこの順番なのか?\n",
+ "\n",
+ "1. **`tr` で正規化**\n",
+ " - 様々な空白文字(スペース・タブ・改行)を統一的に処理\n",
+ " - 連続空白の圧縮により空行を防止\n",
+ "\n",
+ "2. **最初の `sort` が必須**\n",
+ " - `uniq -c` は**連続した**同一行のみカウント\n",
+ " - 事前に整列することで同じ単語を隣接させる\n",
+ "\n",
+ "3. **`uniq -c` で集計**\n",
+ " - 連続する同一単語の出現回数をカウント\n",
+ " - 出力形式: `<頻度> <単語>`\n",
+ "\n",
+ "4. **`sort -nr` で降順**\n",
+ " - `-n`: 数値としてソート\n",
+ " - `-r`: 降順(reverse)\n",
+ "\n",
+ "5. **`awk` で整形**\n",
+ " - 列の順序を入れ替え: `$2 $1` → `<単語> <頻度>`\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## 代替解法(awk メイン)\n",
+ "\n",
+ "`awk` の連想配列を使った方法:\n",
+ "\n",
+ "```bash\n",
+ "awk '{for(i=1;i<=NF;i++) c[$i]++} END{for(w in c) print w, c[w]}' words.txt \\\n",
+ " | LC_ALL=C sort -k2,2nr\n",
+ "```\n",
+ "\n",
+ "### 処理の流れ\n",
+ "\n",
+ "1. `awk` で各単語をカウント\n",
+ " - `NF`: 行内のフィールド数(空白区切り)\n",
+ " - `c[$i]++`: 連想配列でカウント\n",
+ "\n",
+ "2. `END` ブロックで出力\n",
+ " - `for(w in c)`: 全ての単語をループ\n",
+ " - `print w, c[w]`: 単語と頻度を出力\n",
+ "\n",
+ "3. `sort -k2,2nr` で頻度降順ソート\n",
+ " - `-k2,2`: 第2列(頻度)でソート\n",
+ " - `n`: 数値ソート\n",
+ " - `r`: 降順\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## パフォーマンス最適化のポイント\n",
+ "\n",
+ "### 1. ロケール設定\n",
+ "\n",
+ "```bash\n",
+ "LC_ALL=C\n",
+ "```\n",
+ "\n",
+ "- C ロケールを使用することで `sort` が高速化\n",
+ "- バイト単位の比較により安定した動作\n",
+ "\n",
+ "### 2. 空行の除去(必要に応じて)\n",
+ "\n",
+ "`tr -s` を使っていれば基本的に不要ですが、念のため:\n",
+ "\n",
+ "```bash\n",
+ "... | grep -v '^$' | ...\n",
+ "```\n",
+ "\n",
+ "### 3. 入力ファイルの柔軟な指定\n",
+ "\n",
+ "スクリプト版では引数でファイルパスを指定可能:\n",
+ "\n",
+ "```bash\n",
+ "input=\"${1:-words.txt}\"\n",
+ "```\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## 応用例\n",
+ "\n",
+ "### 圧縮ファイルの処理\n",
+ "\n",
+ "```bash\n",
+ "zcat compressed.txt.gz | tr -s '[:space:]' '\\n' | sort | uniq -c | sort -nr | awk '{print $2, $1}'\n",
+ "```\n",
+ "\n",
+ "### ストリーム処理\n",
+ "\n",
+ "```bash\n",
+ "curl -s https://example.com/text.txt | tr -s '[:space:]' '\\n' | sort | uniq -c | sort -nr | awk '{print $2, $1}'\n",
+ "```\n",
+ "\n",
+ "### 大文字小文字を区別しない\n",
+ "\n",
+ "```bash\n",
+ "LC_ALL=C tr -s '[:space:]' '\\n' < words.txt \\\n",
+ " | tr '[:upper:]' '[:lower:]' \\\n",
+ " | sort \\\n",
+ " | uniq -c \\\n",
+ " | sort -nr \\\n",
+ " | awk '{print $2, $1}'\n",
+ "```\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## よくある質問\n",
+ "\n",
+ "### Q1: `tr -s` の `-s` オプションは何をする?\n",
+ "\n",
+ "**A:** `-s` (squeeze) は連続する文字を1つに圧縮します。\n",
+ "\n",
+ "```bash\n",
+ "# 例: 連続するスペースを1つに\n",
+ "echo \"a b c\" | tr -s ' '\n",
+ "# 出力: a b c\n",
+ "```\n",
+ "\n",
+ "### Q2: なぜ `LC_ALL=C` を使うのか?\n",
+ "\n",
+ "**A:** \n",
+ "- ロケール依存の文字比較を避ける\n",
+ "- バイト単位の比較で高速化\n",
+ "- 環境による動作の違いを防ぐ\n",
+ "\n",
+ "### Q3: `uniq -c` の出力形式は?\n",
+ "\n",
+ "**A:** `<頻度><スペース><単語>` の形式で出力されます。\n",
+ "\n",
+ "```text\n",
+ " 4 the\n",
+ " 3 is\n",
+ "```\n",
+ "\n",
+ "先頭にスペースが入るため、`awk` で列を入れ替える際は `$1` が頻度、`$2` が単語になります。\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## Mermaid図の注意点\n",
+ "\n",
+ "Mermaid でコマンドを含むラベルを書く際の安全な記法:\n",
+ "\n",
+ "### 特殊文字のエスケープ\n",
+ "\n",
+ "- 角かっこ `[` `]` → `[` `]`\n",
+ "- 波かっこ `{` `}` → `{` `}`\n",
+ "- バックスラッシュ `\\` → `\\\\`\n",
+ "- シングルクォート `'` → `'`(必要な場合)\n",
+ "\n",
+ "### 推奨記法\n",
+ "\n",
+ "```mermaid\n",
+ "flowchart LR\n",
+ " A[\"ノード名\"] --> B[\"コマンド
説明文\"]\n",
+ "```\n",
+ "\n",
+ "- ラベル全体を二重引用符 `[\"...\"]` で囲む\n",
+ "- コマンド部分は `` タグで囲む\n",
+ "- 改行は `
` を使用\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## まとめ\n",
+ "\n",
+ "この問題の解法ポイント:\n",
+ "\n",
+ "1. **`tr`** で空白を正規化\n",
+ "2. **`sort`** で同一単語を隣接させる\n",
+ "3. **`uniq -c`** で頻度をカウント\n",
+ "4. **`sort -nr`** で頻度降順ソート\n",
+ "5. **`awk`** で出力形式を整形\n",
+ "\n",
+ "シンプルな POSIX ツールの組み合わせで効率的に処理できます。\n",
+ "\n",
+ "主な改善点:\n",
+ "1. 重複セクションを完全に削除\n",
+ "2. 構造を論理的に整理(問題→解答→詳細→応用)\n",
+ "3. Mermaid図を1つに統一(安全な記法を使用)\n",
+ "4. よくある質問セクションを追加\n",
+ "5. 応用例を充実\n",
+ "6. Mermaid記法の注意点を最後にまとめ"
+ ]
+ }
+ ],
+ "metadata": {
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/Shell/Bash/Leetcode/192. Word Frequency/WordFrequency.md b/Shell/Bash/Leetcode/192. Word Frequency/WordFrequency.md
deleted file mode 100644
index e433b9f8..00000000
--- a/Shell/Bash/Leetcode/192. Word Frequency/WordFrequency.md
+++ /dev/null
@@ -1,362 +0,0 @@
-# 解答(スクリプト版)
-
-`wordfreq.sh`(Bash, POSIX ツールのみ)
-
-```bash
-#!/usr/bin/env bash
-set -euo pipefail
-
-# 使い方: ./wordfreq.sh [path/to/words.txt]
-# 引数が未指定なら ./words.txt を読む
-input="${1:-words.txt}"
-
-# 1) 全ての空白(スペース/タブ/改行など)を改行にし、連続空白は1つに圧縮
-# 2) ソート
-# 3) uniq -c で頻度集計
-# 4) 頻度(第1列)で数値降順ソート
-# 5) "単語 頻度" の並びに整形
-LC_ALL=C tr -s '[:space:]' '\n' < "$input" \
- | sort \
- | uniq -c \
- | sort -nr \
- | awk '{print $2, $1}'
-```
-
-実行権限を付与して実行:
-
-```bash
-chmod +x wordfreq.sh
-./wordfreq.sh # カレントの words.txt を集計
-# もしくは
-./wordfreq.sh /path/to/words.txt
-```
-
----
-
-## 解答(パイプのみの 1 行)
-
-```bash
-LC_ALL=C tr -s '[:space:]' '\n' < words.txt | sort | uniq -c | sort -nr | awk '{print $2, $1}'
-```
-
----
-
-## 出力例
-
-`words.txt` が次の内容のとき:
-
-```text
-the day is sunny the the
-the sunny is is
-```
-
-どちらの方法でも:
-
-```text
-the 4
-is 3
-sunny 2
-day 1
-```
-
----
-
-## 図解:処理の流れ
-
-```mermaid
-flowchart LR
- A[words.txt
入力ファイル] --> B["tr -s '[:space:]' '\\n'
全ての空白→改行 / 連続を1つに圧縮"]
- B --> C["sort
単語を辞書順に並べる"]
- C --> D["uniq -c
連続する同一単語をカウント"]
- D --> E["sort -nr
頻度(数値)で降順ソート"]
- E --> F["awk '{print $2, $1}'
「単語 頻度」に整形"]
- F --> G[結果]
-```
-
----
-
-## ステップ別のミニ実演(変換のイメージ)
-
-入力:
-
-```text
-the day is sunny the the
-the sunny is is
-```
-
-1. **tr -s '[:space:]' '\n'**
- 全ての空白を改行に(重複空白は圧縮):
-
-```text
-the
-day
-is
-sunny
-the
-the
-the
-sunny
-is
-is
-```
-
-## 2. **sort**(辞書順)
-
-```text
-day
-is
-is
-is
-sunny
-sunny
-the
-the
-the
-the
-```
-
-## 3. **uniq -c**(連続同一語を数える)
-
-```text
- 1 day
- 3 is
- 2 sunny
- 4 the
-```
-
-## 4. **sort -nr**(頻度降順)
-
-```text
- 4 the
- 3 is
- 2 sunny
- 1 day
-```
-
-## 5. **awk '{print $2, $1}'**(「単語 頻度」に整形)
-
-```text
-the 4
-is 3
-sunny 2
-day 1
-```
-
----
-
-## なぜこの順番?
-
-- `uniq -c` は**連続**した同一行しか数えられないため、まず `sort` で同じ単語を隣接させます。
-- `tr -s '[:space:]' '\n'` を先に使うことで、スペース・タブ・改行など**あらゆる空白**を 1 語 1 行に正規化できます。
-- 最終的に `sort -nr` で頻度を**数値降順**にし、`awk` で「単語 頻度」に整えます。
-
----
-
-## 代替ワンライナー(awk メイン)
-
-`awk` でカウントしてから、頻度で降順ソートする方法もあります。
-(大量データ時のパイプ構成はお好みで)
-
-```bash
-awk '{for(i=1;i<=NF;i++) c[$i]++} END{for(w in c) print w, c[w]}' words.txt \
- | LC_ALL=C sort -k2,2nr
-```
-
-- `NF` は行内のフィールド数(空白区切り)
-- 連想配列 `c[word]` にカウント
-- END で「単語 頻度」を出力し、`sort -k2,2nr` で第 2 列(頻度)を降順ソート
-
----
-
-## 小さな TIPS
-
-- **ロケール固定**: `LC_ALL=C` を付けると `sort` が速く・安定します。
-- **空行ケア**: `tr -s` を使っていれば空行は基本的に出ませんが、念のためはさむなら
- `... | grep -v '^$' | ...` を `sort` の前に入れても OK です。
-- **入力ファイル指定**: スクリプト版は引数でファイルを差し替え可能にしています。
-
-必要なら、`zcat ... | tr ... | ...` のように圧縮ファイルやストリームにも簡単に応用できます。
-
-## 修正点
-
-原因は、**ノードラベル内に Mermaid の構文と衝突する文字(`[ ] ' \ :` など)が“そのまま”入っている**ためです。
-あなたの行には `B[tr -s '[:space:]' '\n'
...]` とありますが、
-ラベル中の `[` と `]`(`[:space:]` の部分)が **ノードの区切り `[...]`** と誤解され、
-さらに直後のシングルクォート `'` でパーサがこけています(`got 'SQS'` は Single Quote String を示唆)。
-
-## 修正方針(どれか or 併用)1
-
-1. **ラベルを二重引用符で囲む**:`id[" ... "]`
-2. **ラベル内の角かっこ `[` `]` を HTML エンティティに置換**:`[` と `]`
-3. **必要に応じてクォートやバックスラッシュをエスケープ/置換**:`'` → `'`、`\n` → `\\n` など
-4. **長いコマンドはコード風に**(バッククォート)**や改行 `
` を併用**
-
----
-
-## 直した例(あなたのフローをそのまま修正)
-
-```mermaid
-flowchart LR
- A[words.txt
入力ファイル] --> B["tr -s '[:space:]' '\\n'
全ての空白→改行 / 連続を1つに圧縮"]
- B --> C["sort
単語を辞書順に並べる"]
- C --> D["uniq -c
連続する同一単語をカウント"]
- D --> E["sort -nr
頻度(数値)で降順ソート"]
- E --> F["awk '{print $2, $1}'
「単語 頻度」に整形"]
- F --> G[結果]
-```
-
-### ポイント 1
-
-- `B[...]` を `B["..."]` に変更(**二重引用符**でラベル全体を囲む)
-- `[:space:]` の角かっこを **`[` と `]`** に置換
-- シングルクォート `'` は **`'`** に(中でさらに `'` を使いたいときの衝突回避)
-- `\n` は **`\\n`** に(バックスラッシュをエスケープ)
-- `
` はそのままで OK(HTML ラベルは許容されます)
-
----
-
-## もう少し読みやすくする代替(コマンド部分をコード表記)1
-
-```mermaid
-flowchart LR
- A[words.txt
入力ファイル] --> B["`tr -s [:space:] \\n`
全ての空白→改行 / 連続は1つに圧縮"]
- B --> C["`sort`
辞書順整列"]
- C --> D["`uniq -c`
連続同一語をカウント"]
- D --> E["`sort -nr`
頻度で降順"]
- E --> F["`awk '{print $2, $1}'`
出力整形(単語 頻度)"]
- F --> G[結果]
-```
-
-> バッククォート `` `...` `` で**コード風**に包むと、特殊文字の衝突が起きにくく、可読性も上がります。
-
----
-
-## 安全な書き方テンプレ 1
-
-- ラベルが記号を含むときは **常に `id["..."]`** を使う
-- 角かっこは **`[` `]`** に
-- シングルクォートは **`'`**、ダブルクォートは **`"`**
-- バックスラッシュは **`\\`**
-- 改行は **`
`** を使う(Mermaid は HTML ラベル可)
-
-この要領で直すと、パースエラーは解消されます。
-
-原因は、**ノードラベル内に Mermaid の構文と衝突する文字(`[ ] ' \ :` など)が“そのまま”入っている**ためです。
-あなたの行には `B[tr -s '[:space:]' '\n'
...]` とありますが、
-ラベル中の `[` と `]`(`[:space:]` の部分)が **ノードの区切り `[...]`** と誤解され、
-さらに直後のシングルクォート `'` でパーサがこけています(`got 'SQS'` は Single Quote String を示唆)。
-
-## 修正方針(どれか or 併用)2
-
-1. **ラベルを二重引用符で囲む**:`id[" ... "]`
-2. **ラベル内の角かっこ `[` `]` を HTML エンティティに置換**:`[` と `]`
-3. **必要に応じてクォートやバックスラッシュをエスケープ/置換**:`'` → `'`、`\n` → `\\n` など
-4. **長いコマンドはコード風に**(バッククォート)**や改行 `
` を併用**
-
----
-
-## 直した例(あなたのフローをそのまま修正)2
-
-```mermaid
-flowchart LR
- A[words.txt
入力ファイル] --> B["tr -s '[:space:]' '\\n'
全ての空白→改行 / 連続を1つに圧縮"]
- B --> C["sort
単語を辞書順に並べる"]
- C --> D["uniq -c
連続する同一単語をカウント"]
- D --> E["sort -nr
頻度(数値)で降順ソート"]
- E --> F["awk '{print $2, $1}'
「単語 頻度」に整形"]
- F --> G[結果]
-```
-
-### ポイント 2
-
-- `B[...]` を `B["..."]` に変更(**二重引用符**でラベル全体を囲む)
-- `[:space:]` の角かっこを **`[` と `]`** に置換
-- シングルクォート `'` は **`'`** に(中でさらに `'` を使いたいときの衝突回避)
-- `\n` は **`\\n`** に(バックスラッシュをエスケープ)
-- `
` はそのままで OK(HTML ラベルは許容されます)
-
----
-
-## もう少し読みやすくする代替(コマンド部分をコード表記)2
-
-```mermaid
-flowchart LR
- A[words.txt
入力ファイル] --> B["`tr -s [:space:] \\n`
全ての空白→改行 / 連続は1つに圧縮"]
- B --> C["`sort`
辞書順整列"]
- C --> D["`uniq -c`
連続同一語をカウント"]
- D --> E["`sort -nr`
頻度で降順"]
- E --> F["`awk '{print $2, $1}'`
出力整形(単語 頻度)"]
- F --> G[結果]
-```
-
-> バッククォート `` `...` `` で**コード風**に包むと、特殊文字の衝突が起きにくく、可読性も上がります。
-
----
-
-## 安全な書き方テンプレ 2
-
-- ラベルが記号を含むときは **常に `id["..."]`** を使う
-- 角かっこは **`[` `]`** に
-- シングルクォートは **`'`**、ダブルクォートは **`"`**
-- バックスラッシュは **`\\`**
-- 改行は **`
`** を使う(Mermaid は HTML ラベル可)
-
-この要領で直すと、パースエラーは解消されます。
-
-発生原因はまだ**ソースにスマート置換で混入した非 ASCII 文字**(合字やスマート引用符など)が残っていること+**Mermaid のラベル内での特殊記号衝突**です。
-安全策として「完全 ASCII・最小限の記号・HTML エンティティで角かっこを逃がす・バッククォート不使用」の版に差し替えてください。下のどれかを**そのままコピペ**で動きます。
-
----
-
-## 安全版その 1(ASCII のみ・角かっこを HTML エンティティ化・バッククォート不使用)
-
-```mermaid
-flowchart LR
- A["words.txt
入力ファイル"] --> B["tr -s [:space:] \\n
全ての空白→改行 / 連続は1つに圧縮"]
- B --> C["sort
辞書順整列"]
- C --> D["uniq -c
連続同一語をカウント"]
- D --> E["sort -nr
頻度で降順"]
- E --> F["awk {print $2, $1}
出力整形(単語 頻度)"]
- F --> G["結果"]
-```
-
-ポイント
-
-- `[:space:]` の角かっこは `[` と `]`
-- 改行リテラルは `\\n`
-- `awk '{print $2, $1}'` は衝突回避のため **波かっこをエンティティ化**(`{` `}`)し、**シングルクォートを排除**しました(見た目の違いだけで意味説明には十分)
-
----
-
-## 安全版その 2(コマンドを `` で表示・記号衝突をさらに回避)
-
-```mermaid
-flowchart LR
- A["words.txt
入力ファイル"] --> B["tr -s [:space:] \\n
全ての空白→改行 / 連続は1つに圧縮"]
- B --> C["sort
辞書順整列"]
- C --> D["uniq -c
連続同一語をカウント"]
- D --> E["sort -nr
頻度で降順"]
- E --> F["awk {print $2, $1}
出力整形(単語 頻度)"]
- F --> G["結果"]
-```
-
-> `...` を使うとバッククォート不要で、Markdown/レンダラーによる再変換の影響を受けにくくなります。
-
----
-
-## それでも直らない場合のチェックリスト
-
-1. **貼り付けは必ずプレーンテキスト**で
- - ブラウザやエディタの「Paste and Match Style / Paste as plain text」を使う
-
-2. **エディタ設定**(例:VS Code)
- - `"editor.fontLigatures": false`(合字を無効)
- - Markdown 拡張の **スマート引用符/全角置換を無効** に
-
-3. **ファイルエンコード**:UTF-8(BOM なし推奨)
-4. **問題記号の回避**
- - 角かっこは `[` `]`
- - バックスラッシュは必ず `\\` と二重
- - シングル/ダブルクォートは極力使わないか、必要なら `'` / `"`
-
-このどちらかの安全版を使えば、`Lexical error on line 2. Unrecognized text.` は解消されるはずです。
diff --git a/Shell/Bash/Leetcode/193. Valid Phone Numbers/ValidPhoneNumbers.ipynb b/Shell/Bash/Leetcode/193. Valid Phone Numbers/ValidPhoneNumbers.ipynb
index a5d8da92..24874f95 100644
--- a/Shell/Bash/Leetcode/193. Valid Phone Numbers/ValidPhoneNumbers.ipynb
+++ b/Shell/Bash/Leetcode/193. Valid Phone Numbers/ValidPhoneNumbers.ipynb
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "markdown",
- "id": "e7bafc2d",
+ "id": "e5ef6417",
"metadata": {},
"source": [
"# 電話番号フィルタリング問題の解説\n",
@@ -17,20 +17,9 @@
"\n",
"ここで `x` は数字(0-9)を表します。\n",
"\n",
- "## 解決策"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "39aacb70",
- "metadata": {
- "vscode": {
- "languageId": "powershell"
- }
- },
- "outputs": [],
- "source": [
+ "## 解決策\n",
+ "\n",
+ "```bash\n",
"#!/bin/bash\n",
"\n",
"# Solution 1: Using grep with extended regex\n",
@@ -41,7 +30,9 @@
"# Beats 84.10%\n",
"\n",
"grep -E '^([0-9]{3}-[0-9]{3}-[0-9]{4}|\\([0-9]{3}\\) [0-9]{3}-[0-9]{4})$' file.txt\n",
+ "```\n",
"\n",
+ "```bash\n",
"# Solution 2: Using sed (alternative)\n",
"# Analyze Complexity\n",
"# Runtime 65 ms\n",
@@ -50,7 +41,9 @@
"# Beats 84.10%\n",
"\n",
"sed -n -E '/^([0-9]{3}-[0-9]{3}-[0-9]{4}|\\([0-9]{3}\\) [0-9]{3}-[0-9]{4})$/p' file.txt\n",
+ "```\n",
"\n",
+ "```bash\n",
"# Solution 3: Using awk (alternative)\n",
"# Analyze Complexity\n",
"# Runtime 71 ms\n",
@@ -58,14 +51,9 @@
"# Memory 3.84 MB\n",
"# Beats 3.13%\n",
"\n",
- "awk '/^([0-9]{3}-[0-9]{3}-[0-9]{4}|\\([0-9]{3}\\) [0-9]{3}-[0-9]{4})$/' file.txt"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "e5ef6417",
- "metadata": {},
- "source": [
+ "awk '/^([0-9]{3}-[0-9]{3}-[0-9]{4}|\\([0-9]{3}\\) [0-9]{3}-[0-9]{4})$/' file.txt\n",
+ "```\n",
+ "\n",
"## 最もシンプルな解答\n",
"\n",
"```bash\n",
@@ -78,143 +66,191 @@
"\n",
"### 1. 正規表現パターンの構造\n",
"\n",
- "```\n",
- "^([0-9]{3}-[0-9]{3}-[0-9]{4}|\\([0-9]{3}\\) [0-9]{3}-[0-9]{4})$\n",
+ "```mermaid\n",
+ "graph TD\n",
+ " A[\"正規表現全体
^...OR...$\"] --> B[\"行頭アンカー ^\"]\n",
+ " A --> C[\"OR演算子 |\"]\n",
+ " A --> D[\"行末アンカー $\"]\n",
+ " \n",
+ " C --> E[\"パターン1
xxx-xxx-xxxx\"]\n",
+ " C --> F[\"パターン2
(xxx) xxx-xxxx\"]\n",
+ " \n",
+ " E --> E1[\"[0-9]{3}\"]\n",
+ " E --> E2[\"-\"]\n",
+ " E --> E3[\"[0-9]{3}\"]\n",
+ " E --> E4[\"-\"]\n",
+ " E --> E5[\"[0-9]{4}\"]\n",
+ " \n",
+ " F --> F1[\"\\(\"]\n",
+ " F --> F2[\"[0-9]{3}\"]\n",
+ " F --> F3[\"\\)\"]\n",
+ " F --> F4[\"スペース\"]\n",
+ " F --> F5[\"[0-9]{3}\"]\n",
+ " F --> F6[\"-\"]\n",
+ " F --> F7[\"[0-9]{4}\"]\n",
+ " \n",
+ " style A fill:#e1f5ff\n",
+ " style E fill:#c8e6c9\n",
+ " style F fill:#fff9c4\n",
"```\n",
"\n",
- "この正規表現を分解して理解しましょう:\n",
- "\n",
- "#### **全体構造**\n",
- "```\n",
- " ^ $\n",
- " | |\n",
- " 行頭 OR演算子 行末\n",
- " ┌──────────────────┴──────────────────┐\n",
- " | |\n",
- " パターン1 パターン2\n",
- " xxx-xxx-xxxx (xxx) xxx-xxxx\n",
+ "#### **パターン1の詳細構造**\n",
+ "\n",
+ "```mermaid\n",
+ "graph LR\n",
+ " A[\"[0-9]{3}\"] -->|\"例: 987\"| B[\"-\"]\n",
+ " B --> C[\"[0-9]{3}\"]\n",
+ " C -->|\"例: 123\"| D[\"-\"]\n",
+ " D --> E[\"[0-9]{4}\"]\n",
+ " E -->|\"例: 4567\"| F[\"結果: 987-123-4567\"]\n",
+ " \n",
+ " style A fill:#ffcdd2\n",
+ " style C fill:#f8bbd0\n",
+ " style E fill:#e1bee7\n",
+ " style F fill:#c5cae9\n",
"```\n",
"\n",
- "#### **パターン1: `[0-9]{3}-[0-9]{3}-[0-9]{4}`**\n",
- "\n",
- "```\n",
- " [0-9]{3} - [0-9]{3} - [0-9]{4}\n",
- " │ │ │ │ │\n",
- " 3桁の数字 ハイフン 3桁の数字 ハイフン 4桁の数字\n",
- " │ │ │\n",
- " 987 123 4567\n",
- "\n",
- "例: 987-123-4567\n",
- "```\n",
- "\n",
- "#### **パターン2: `\\([0-9]{3}\\) [0-9]{3}-[0-9]{4}`**\n",
- "\n",
- "```\n",
- " \\( [0-9]{3} \\) スペース [0-9]{3} - [0-9]{4}\n",
- " │ │ │ │ │ │ │\n",
- " 左カッコ 3桁 右カッコ 空白 3桁 ハイフン 4桁\n",
- " │ │ │ │ │\n",
- " ( 123 ) 456 7890\n",
- "\n",
- "例: (123) 456-7890\n",
+ "#### **パターン2の詳細構造**\n",
+ "\n",
+ "```mermaid\n",
+ "graph LR\n",
+ " A[\"\\(\"] --> B[\"[0-9]{3}\"]\n",
+ " B -->|\"例: 123\"| C[\"\\)\"]\n",
+ " C --> D[\"スペース\"]\n",
+ " D --> E[\"[0-9]{3}\"]\n",
+ " E -->|\"例: 456\"| F[\"-\"]\n",
+ " F --> G[\"[0-9]{4}\"]\n",
+ " G -->|\"例: 7890\"| H[\"結果: (123) 456-7890\"]\n",
+ " \n",
+ " style A fill:#ffcdd2\n",
+ " style B fill:#f8bbd0\n",
+ " style C fill:#ffcdd2\n",
+ " style E fill:#e1bee7\n",
+ " style G fill:#d1c4e9\n",
+ " style H fill:#c5cae9\n",
"```\n",
"\n",
- "**重要ポイント:** `\\(` と `\\)` はエスケープが必要です(カッコ自体を表すため)\n",
- "\n",
"---\n",
"\n",
"### 2. grep コマンドの動作フロー\n",
"\n",
- "```\n",
- "┌─────────────────────────────────────────────────┐\n",
- "│ file.txt の内容 │\n",
- "├─────────────────────────────────────────────────┤\n",
- "│ 行1: 987-123-4567 │\n",
- "│ 行2: 123 456 7890 │\n",
- "│ 行3: (123) 456-7890 │\n",
- "├─────────────────────────────────────────────────┤\n",
- " ↓ grep -E で各行をチェック\n",
- "├─────────────────────────────────────────────────┤\n",
- "│ パターンマッチング │\n",
- "├─────────────────────────────────────────────────┤\n",
- "│ 行1: 987-123-4567 │\n",
- "│ ✓ パターン1にマッチ → 出力 │\n",
- "│ │\n",
- "│ 行2: 123 456 7890 │\n",
- "│ ✗ どちらのパターンにもマッチしない │\n",
- "│ (スペースがハイフンではない) │\n",
- "│ │\n",
- "│ 行3: (123) 456-7890 │\n",
- "│ ✓ パターン2にマッチ → 出力 │\n",
- "├─────────────────────────────────────────────────┤\n",
- " ↓ 結果出力\n",
- "├─────────────────────────────────────────────────┤\n",
- "│ 987-123-4567 │\n",
- "│ (123) 456-7890 │\n",
- "└─────────────────────────────────────────────────┘\n",
+ "```mermaid\n",
+ "flowchart TD\n",
+ " A[\"file.txt
行1: 987-123-4567
行2: 123 456 7890
行3: (123) 456-7890\"] --> B[\"grep -E でパターンマッチング開始\"]\n",
+ " \n",
+ " B --> C1[\"行1をチェック:
987-123-4567\"]\n",
+ " B --> C2[\"行2をチェック:
123 456 7890\"]\n",
+ " B --> C3[\"行3をチェック:
(123) 456-7890\"]\n",
+ " \n",
+ " C1 --> D1{\"パターン1
にマッチ?\"}\n",
+ " D1 -->|\"✓ YES\"| E1[\"出力に追加\"]\n",
+ " \n",
+ " C2 --> D2{\"どちらかの
パターンに
マッチ?\"}\n",
+ " D2 -->|\"✗ NO
(スペース区切り)\"| E2[\"スキップ\"]\n",
+ " \n",
+ " C3 --> D3{\"パターン2
にマッチ?\"}\n",
+ " D3 -->|\"✓ YES\"| E3[\"出力に追加\"]\n",
+ " \n",
+ " E1 --> F[\"最終出力\"]\n",
+ " E2 --> F\n",
+ " E3 --> F\n",
+ " \n",
+ " F --> G[\"987-123-4567
(123) 456-7890\"]\n",
+ " \n",
+ " style A fill:#e3f2fd\n",
+ " style D1 fill:#c8e6c9\n",
+ " style D2 fill:#ffcdd2\n",
+ " style D3 fill:#c8e6c9\n",
+ " style E1 fill:#a5d6a7\n",
+ " style E2 fill:#ef9a9a\n",
+ " style E3 fill:#a5d6a7\n",
+ " style G fill:#81c784\n",
"```\n",
"\n",
"---\n",
"\n",
- "### 3. オプションの説明\n",
- "\n",
- "```bash\n",
- "grep -E '^pattern$' file.txt\n",
- " │ │ └─ 入力ファイル\n",
- " │ └─ 正規表現パターン\n",
- " └─ Extended Regular Expression (拡張正規表現)\n",
+ "### 3. オプションと構文要素の説明\n",
+ "\n",
+ "```mermaid\n",
+ "graph TD\n",
+ " A[\"grep -E '^pattern$' file.txt\"] --> B[\"-E オプション\"]\n",
+ " A --> C[\"^ アンカー\"]\n",
+ " A --> D[\"$ アンカー\"]\n",
+ " A --> E[\"file.txt\"]\n",
+ " \n",
+ " B --> B1[\"拡張正規表現を有効化
+, ?, |, () が使用可能\"]\n",
+ " C --> C1[\"行頭にマッチ
余分な前置文字を排除\"]\n",
+ " D --> D1[\"行末にマッチ
余分な後置文字を排除\"]\n",
+ " E --> E1[\"入力ファイル
各行を順次処理\"]\n",
+ " \n",
+ " style A fill:#e1f5ff\n",
+ " style B fill:#fff9c4\n",
+ " style C fill:#c8e6c9\n",
+ " style D fill:#c8e6c9\n",
+ " style E fill:#ffccbc\n",
"```\n",
"\n",
- "- **`-E`**: 拡張正規表現を使用(+, ?, |, () などが使える)\n",
- "- **`^`**: 行頭にマッチ(余分な文字がないことを保証)\n",
- "- **`$`**: 行末にマッチ(余分な文字がないことを保証)\n",
- "\n",
"---\n",
"\n",
- "### 4. テストケースの検証\n",
- "\n",
- "#### **有効な番号**\n",
- "```\n",
- "✓ 987-123-4567\n",
- " [0-9]{3}-[0-9]{3}-[0-9]{4} にマッチ\n",
- " \n",
- "✓ (123) 456-7890\n",
- " \\([0-9]{3}\\) [0-9]{3}-[0-9]{4} にマッチ\n",
- "```\n",
- "\n",
- "#### **無効な番号**\n",
- "```\n",
- "✗ 123 456 7890\n",
- " 理由: ハイフンではなくスペースで区切られている\n",
- " \n",
- "✗ 1234567890\n",
- " 理由: 区切り文字がない\n",
- " \n",
- "✗ (123)456-7890\n",
- " 理由: カッコの後にスペースがない\n",
- " \n",
- "✗ 12-345-6789\n",
- " 理由: 最初のグループが2桁(3桁が必要)\n",
+ "### 4. テストケースの検証フロー\n",
+ "\n",
+ "```mermaid\n",
+ "flowchart TD\n",
+ " A[\"入力電話番号\"] --> B{\"形式チェック\"}\n",
+ " \n",
+ " B -->|\"パターン1\"| C1[\"xxx-xxx-xxxx\"]\n",
+ " B -->|\"パターン2\"| C2[\"(xxx) xxx-xxxx\"]\n",
+ " B -->|\"その他\"| C3[\"無効な形式\"]\n",
+ " \n",
+ " C1 --> D1{\"各部分が
正しい桁数?\"}\n",
+ " D1 -->|\"✓ YES\"| E1[\"✓ 有効
例: 987-123-4567\"]\n",
+ " D1 -->|\"✗ NO\"| F1[\"✗ 無効
例: 12-345-6789\"]\n",
+ " \n",
+ " C2 --> D2{\"カッコとスペースが
正しい位置?\"}\n",
+ " D2 -->|\"✓ YES\"| E2[\"✓ 有効
例: (123) 456-7890\"]\n",
+ " D2 -->|\"✗ NO\"| F2[\"✗ 無効
例: (123)456-7890\"]\n",
+ " \n",
+ " C3 --> F3[\"✗ 無効
例: 123 456 7890
例: 1234567890\"]\n",
+ " \n",
+ " style E1 fill:#a5d6a7\n",
+ " style E2 fill:#a5d6a7\n",
+ " style F1 fill:#ef9a9a\n",
+ " style F2 fill:#ef9a9a\n",
+ " style F3 fill:#ef9a9a\n",
"```\n",
"\n",
"---\n",
"\n",
- "### 5. 実行例\n",
- "\n",
- "```bash\n",
- "# file.txtを作成\n",
- "$ cat > file.txt << EOF\n",
- "987-123-4567\n",
- "123 456 7890\n",
- "(123) 456-7890\n",
- "EOF\n",
- "\n",
- "# スクリプトを実行\n",
- "$ grep -E '^([0-9]{3}-[0-9]{3}-[0-9]{4}|\\([0-9]{3}\\) [0-9]{3}-[0-9]{4})$' file.txt\n",
- "\n",
- "# 出力\n",
- "987-123-4567\n",
- "(123) 456-7890\n",
+ "### 5. 実行例のシーケンス\n",
+ "\n",
+ "```mermaid\n",
+ "sequenceDiagram\n",
+ " participant User\n",
+ " participant Shell\n",
+ " participant grep\n",
+ " participant file.txt\n",
+ " \n",
+ " User->>Shell: cat > file.txt\n",
+ " Shell->>file.txt: 987-123-4567
123 456 7890
(123) 456-7890\n",
+ " \n",
+ " User->>Shell: grep -E '^pattern$' file.txt\n",
+ " Shell->>grep: コマンド実行\n",
+ " \n",
+ " grep->>file.txt: 行1を読み込み\n",
+ " file.txt-->>grep: 987-123-4567\n",
+ " grep->>grep: パターン1にマッチ ✓\n",
+ " grep->>Shell: 987-123-4567 を出力\n",
+ " \n",
+ " grep->>file.txt: 行2を読み込み\n",
+ " file.txt-->>grep: 123 456 7890\n",
+ " grep->>grep: マッチせず ✗\n",
+ " \n",
+ " grep->>file.txt: 行3を読み込み\n",
+ " file.txt-->>grep: (123) 456-7890\n",
+ " grep->>grep: パターン2にマッチ ✓\n",
+ " grep->>Shell: (123) 456-7890 を出力\n",
+ " \n",
+ " Shell->>User: 987-123-4567
(123) 456-7890\n",
"```\n",
"\n",
"---\n",
diff --git a/Shell/Bash/Leetcode/194. Transpose File/TransposeFile.ipynb b/Shell/Bash/Leetcode/194. Transpose File/TransposeFile.ipynb
index 41b2285e..05aabb99 100644
--- a/Shell/Bash/Leetcode/194. Transpose File/TransposeFile.ipynb
+++ b/Shell/Bash/Leetcode/194. Transpose File/TransposeFile.ipynb
@@ -386,87 +386,338 @@
"id": "fe45a9c8",
"metadata": {},
"source": [
- "## パフォーマンス分析\n",
+ "## 問題の理解\n",
"\n",
- "### **時間計算量の比較**\n",
+ "この問題は**行列の転置**と同じ操作です。元のファイルの行と列を入れ替えます。\n",
+ "\n",
+ "### 入力例の視覚化\n",
"\n",
+ "```mermaid\n",
+ "graph TD\n",
+ " subgraph \"元のファイル (2列 × 3行)\"\n",
+ " A[\"行1: name age\"]\n",
+ " B[\"行2: alice 21\"]\n",
+ " C[\"行3: ryan 30\"]\n",
+ " end\n",
+ " \n",
+ " subgraph \"列の構造\"\n",
+ " D[\"列1: name, alice, ryan\"]\n",
+ " E[\"列2: age, 21, 30\"]\n",
+ " end\n",
+ " \n",
+ " A --> D\n",
+ " A --> E\n",
+ " B --> D\n",
+ " B --> E\n",
+ " C --> D\n",
+ " C --> E\n",
+ " \n",
+ " style A fill:#e1f5ff\n",
+ " style B fill:#e1f5ff\n",
+ " style C fill:#e1f5ff\n",
+ " style D fill:#fff4e1\n",
+ " style E fill:#fff4e1\n",
"```\n",
- "元の解法:\n",
- "- 読み込み: O(行数 × 列数)\n",
- "- 出力: O(行数 × 列数)\n",
- "- 合計: O(2 × 行数 × 列数)\n",
"\n",
- "改善版:\n",
- "- 読み込み+連結: O(行数 × 列数)\n",
- "- 出力: O(列数)\n",
- "- 合計: O(行数 × 列数 + 列数)\n",
+ "### 出力の視覚化\n",
+ "\n",
+ "```mermaid\n",
+ "graph LR\n",
+ " subgraph \"転置後 (3列 × 2行)\"\n",
+ " A[\"行1: name alice ryan\"]\n",
+ " B[\"行2: age 21 30\"]\n",
+ " end\n",
+ " \n",
+ " subgraph \"元の列が行に変換\"\n",
+ " C[\"元の列1 → 行1\"]\n",
+ " D[\"元の列2 → 行2\"]\n",
+ " end\n",
+ " \n",
+ " C --> A\n",
+ " D --> B\n",
+ " \n",
+ " style A fill:#d1fae5\n",
+ " style B fill:#d1fae5\n",
+ " style C fill:#fef3c7\n",
+ " style D fill:#fef3c7\n",
"```\n",
"\n",
- "### **メモリ使用量の比較**\n",
+ "## 解法の詳細説明\n",
"\n",
+ "### **ステップ1: データの読み込みと配列への格納**\n",
+ "\n",
+ "```bash\n",
+ "awk '{\n",
+ " for (i = 1; i <= NF; i++) {\n",
+ " a[NR, i] = $i\n",
+ " }\n",
+ "}'\n",
"```\n",
- "元の解法:\n",
- "┌──────────────────────────────┐\n",
- "│ 2次元配列: 行数 × 列数 個の要素 │\n",
- "│ 一時文字列: 列数 個 │\n",
- "│ 合計: O(行数 × 列数) │\n",
- "└──────────────────────────────┘\n",
"\n",
- "改善版:\n",
- "┌──────────────────────────────┐\n",
- "│ 1次元配列: 列数 個の文字列 │\n",
- "│ 各文字列長: 行数 × 平均単語長 │\n",
- "│ 合計: O(列数 × 行数) だが │\n",
- "│ 実装が効率的 │\n",
- "└──────────────────────────────┘\n",
+ "**図解:**\n",
+ "\n",
+ "```mermaid\n",
+ "flowchart TD\n",
+ " subgraph \"読み込み処理\"\n",
+ " A[\"NR=1: name age\"] --> B[\"a[1,1]=name
a[1,2]=age\"]\n",
+ " C[\"NR=2: alice 21\"] --> D[\"a[2,1]=alice
a[2,2]=21\"]\n",
+ " E[\"NR=3: ryan 30\"] --> F[\"a[3,1]=ryan
a[3,2]=30\"]\n",
+ " end\n",
+ " \n",
+ " subgraph \"結果の2次元配列\"\n",
+ " G[\"行1: [name, age]\"]\n",
+ " H[\"行2: [alice, 21]\"]\n",
+ " I[\"行3: [ryan, 30]\"]\n",
+ " end\n",
+ " \n",
+ " B --> G\n",
+ " D --> H\n",
+ " F --> I\n",
+ " \n",
+ " style A fill:#e1f5ff\n",
+ " style C fill:#e1f5ff\n",
+ " style E fill:#e1f5ff\n",
+ " style B fill:#fff4e1\n",
+ " style D fill:#fff4e1\n",
+ " style F fill:#fff4e1\n",
+ " style G fill:#d1fae5\n",
+ " style H fill:#d1fae5\n",
+ " style I fill:#d1fae5\n",
"```\n",
"\n",
- "### **実行例の詳細図解**\n",
+ "**変数の説明:**\n",
+ "- `NR`: 現在の行番号 (Number of Records)\n",
+ "- `NF`: 現在の行のフィールド数 (Number of Fields)\n",
+ "- `$i`: i番目のフィールド\n",
+ "- `a[NR, i]`: 2次元配列 (行, 列)\n",
+ "\n",
+ "### **ステップ2: 最大列数の記録**\n",
"\n",
+ "```bash\n",
+ "NF > p { p = NF }\n",
"```\n",
- "入力: file.txt\n",
- "┌─────────────┐\n",
- "│ name age │\n",
- "│ alice 21 │\n",
- "│ ryan 30 │\n",
- "└─────────────┘\n",
"\n",
- "処理フロー:\n",
+ "各行のフィールド数をチェックし、最大値を`p`に保存します。\n",
"\n",
- "NR=1: name age\n",
- " ↓ ↓\n",
- " a[1]=\"name\"\n",
- " a[2]=\"age\"\n",
+ "### **ステップ3: 転置して出力**\n",
"\n",
- "NR=2: alice 21\n",
- " ↓ ↓\n",
- " a[1]=\"name alice\" ← スペース追加して連結\n",
- " a[2]=\"age 21\"\n",
+ "```bash\n",
+ "END {\n",
+ " for (j = 1; j <= p; j++) {\n",
+ " str = a[1, j]\n",
+ " for (i = 2; i <= NR; i++) {\n",
+ " str = str \" \" a[i, j]\n",
+ " }\n",
+ " print str\n",
+ " }\n",
+ "}\n",
+ "```\n",
"\n",
- "NR=3: ryan 30\n",
- " ↓ ↓\n",
- " a[1]=\"name alice ryan\"\n",
- " a[2]=\"age 21 30\"\n",
+ "**図解:**\n",
"\n",
- "END処理:\n",
- " print a[1] → \"name alice ryan\"\n",
- " print a[2] → \"age 21 30\"\n",
+ "```mermaid\n",
+ "flowchart TD\n",
+ " subgraph \"j=1 (元の列1)\"\n",
+ " A[\"a[1,1]=name\"] --> B[\"str='name'\"]\n",
+ " C[\"a[2,1]=alice\"] --> D[\"str='name alice'\"]\n",
+ " E[\"a[3,1]=ryan\"] --> F[\"str='name alice ryan'\"]\n",
+ " F --> G[\"出力: 'name alice ryan'\"]\n",
+ " end\n",
+ " \n",
+ " subgraph \"j=2 (元の列2)\"\n",
+ " H[\"a[1,2]=age\"] --> I[\"str='age'\"]\n",
+ " J[\"a[2,2]=21\"] --> K[\"str='age 21'\"]\n",
+ " L[\"a[3,2]=30\"] --> M[\"str='age 21 30'\"]\n",
+ " M --> N[\"出力: 'age 21 30'\"]\n",
+ " end\n",
+ " \n",
+ " style A fill:#e1f5ff\n",
+ " style C fill:#e1f5ff\n",
+ " style E fill:#e1f5ff\n",
+ " style H fill:#e1f5ff\n",
+ " style J fill:#e1f5ff\n",
+ " style L fill:#e1f5ff\n",
+ " style G fill:#d1fae5\n",
+ " style N fill:#d1fae5\n",
"```\n",
"\n",
- "## ベンチマーク予想\n",
+ "## パフォーマンス比較と改善点\n",
"\n",
- "改善版の期待値:\n",
- "- **Runtime**: 40-50ms (約40-50%改善)\n",
- "- **Memory**: 4-5MB (約35-40%改善)\n",
+ "### **元の解法の問題点**\n",
+ "\n",
+ "```mermaid\n",
+ "graph TD\n",
+ " subgraph \"問題1: 2次元配列の使用\"\n",
+ " A[\"メモリ使用量: O(行数 × 列数)\"]\n",
+ " B[\"各セルを個別に保存\"]\n",
+ " C[\"アクセスオーバーヘッドが大きい\"]\n",
+ " end\n",
+ " \n",
+ " subgraph \"問題2: 二重ループでの文字列連結\"\n",
+ " D[\"毎回新しい文字列を作成\"]\n",
+ " E[\"文字列を何度も再構築\"]\n",
+ " F[\"パフォーマンス低下\"]\n",
+ " end\n",
+ " \n",
+ " A --> D\n",
+ " B --> E\n",
+ " C --> F\n",
+ " \n",
+ " style A fill:#fee2e2\n",
+ " style B fill:#fee2e2\n",
+ " style C fill:#fee2e2\n",
+ " style D fill:#fef3c7\n",
+ " style E fill:#fef3c7\n",
+ " style F fill:#fef3c7\n",
+ "```\n",
+ "\n",
+ "### **改善版の利点**\n",
"\n",
- "### **主な改善要因**\n",
+ "```mermaid\n",
+ "graph LR\n",
+ " subgraph \"改善1: 1次元配列 + 文字列連結\"\n",
+ " A[\"メモリ: O(列数)のみ\"]\n",
+ " B[\"各列を1つの文字列として保存\"]\n",
+ " C[\"a[1]='name alice ryan'
a[2]='age 21 30'\"]\n",
+ " end\n",
+ " \n",
+ " subgraph \"改善2: 処理中に連結\"\n",
+ " D[\"読み込みながら連結\"]\n",
+ " E[\"単純な出力のみ\"]\n",
+ " F[\"パフォーマンス向上\"]\n",
+ " end\n",
+ " \n",
+ " A --> D\n",
+ " B --> E\n",
+ " C --> F\n",
+ " \n",
+ " style A fill:#d1fae5\n",
+ " style B fill:#d1fae5\n",
+ " style C fill:#d1fae5\n",
+ " style D fill:#dbeafe\n",
+ " style E fill:#dbeafe\n",
+ " style F fill:#dbeafe\n",
+ "```\n",
+ "\n",
+ "## パフォーマンス分析\n",
+ "\n",
+ "### **時間計算量の比較**\n",
+ "\n",
+ "```mermaid\n",
+ "graph TD\n",
+ " subgraph \"元の解法\"\n",
+ " A[\"読み込み: O(行数 × 列数)\"]\n",
+ " B[\"出力: O(行数 × 列数)\"]\n",
+ " C[\"合計: O(2 × 行数 × 列数)\"]\n",
+ " end\n",
+ " \n",
+ " subgraph \"改善版\"\n",
+ " D[\"読み込み+連結: O(行数 × 列数)\"]\n",
+ " E[\"出力: O(列数)\"]\n",
+ " F[\"合計: O(行数 × 列数 + 列数)\"]\n",
+ " end\n",
+ " \n",
+ " A --> B --> C\n",
+ " D --> E --> F\n",
+ " \n",
+ " C -.->|\"遅い\"| G[パフォーマンス比較]\n",
+ " F -.->|\"速い\"| G\n",
+ " \n",
+ " style C fill:#fee2e2\n",
+ " style F fill:#d1fae5\n",
+ " style G fill:#e0e7ff\n",
+ "```\n",
+ "\n",
+ "### **メモリ使用量の比較**\n",
+ "\n",
+ "```mermaid\n",
+ "graph TD\n",
+ " subgraph \"元の解法\"\n",
+ " A[\"2次元配列:
行数 × 列数 個の要素\"]\n",
+ " B[\"一時文字列:
列数 個\"]\n",
+ " C[\"合計: O(行数 × 列数)\"]\n",
+ " end\n",
+ " \n",
+ " subgraph \"改善版\"\n",
+ " D[\"1次元配列:
列数 個の文字列\"]\n",
+ " E[\"各文字列長:
行数 × 平均単語長\"]\n",
+ " F[\"合計: O(列数 × 行数)
だが実装が効率的\"]\n",
+ " end\n",
+ " \n",
+ " A --> B --> C\n",
+ " D --> E --> F\n",
+ " \n",
+ " C -.->|\"メモリ多\"| G[メモリ比較]\n",
+ " F -.->|\"メモリ少\"| G\n",
+ " \n",
+ " style C fill:#fee2e2\n",
+ " style F fill:#d1fae5\n",
+ " style G fill:#e0e7ff\n",
+ "```\n",
+ "\n",
+ "### **実行例の詳細図解**\n",
+ "\n",
+ "```mermaid\n",
+ "sequenceDiagram\n",
+ " participant Input as file.txt\n",
+ " participant AWK as AWK処理\n",
+ " participant Array as 配列a[]\n",
+ " participant Output as 出力\n",
+ " \n",
+ " Note over Input: name age
alice 21
ryan 30\n",
+ " \n",
+ " Input->>AWK: NR=1: name age\n",
+ " AWK->>Array: a[1]=\"name\"
a[2]=\"age\"\n",
+ " \n",
+ " Input->>AWK: NR=2: alice 21\n",
+ " AWK->>Array: a[1]=\"name alice\"
a[2]=\"age 21\"\n",
+ " \n",
+ " Input->>AWK: NR=3: ryan 30\n",
+ " AWK->>Array: a[1]=\"name alice ryan\"
a[2]=\"age 21 30\"\n",
+ " \n",
+ " Array->>Output: print a[1]\n",
+ " Note over Output: name alice ryan\n",
+ " \n",
+ " Array->>Output: print a[2]\n",
+ " Note over Output: age 21 30\n",
+ "```\n",
+ "\n",
+ "## ベンチマーク予想\n",
+ "\n",
+ "```mermaid\n",
+ "graph LR\n",
+ " subgraph \"改善版の期待値\"\n",
+ " A[\"Runtime: 40-50ms
(約40-50%改善)\"]\n",
+ " B[\"Memory: 4-5MB
(約35-40%改善)\"]\n",
+ " end\n",
+ " \n",
+ " subgraph \"主な改善要因\"\n",
+ " C[\"配列アクセスの削減:
2次元→1次元\"]\n",
+ " D[\"ループネストの削減:
二重ループ→単一ループ\"]\n",
+ " E[\"文字列操作の最適化:
逐次連結→直接連結\"]\n",
+ " F[\"条件分岐の最適化:
三項演算子の使用\"]\n",
+ " end\n",
+ " \n",
+ " C --> A\n",
+ " D --> A\n",
+ " E --> B\n",
+ " F --> B\n",
+ " \n",
+ " style A fill:#d1fae5\n",
+ " style B fill:#d1fae5\n",
+ " style C fill:#dbeafe\n",
+ " style D fill:#dbeafe\n",
+ " style E fill:#dbeafe\n",
+ " style F fill:#dbeafe\n",
+ "```\n",
"\n",
- "1. **配列アクセスの削減**: 2次元→1次元\n",
- "2. **ループネストの削減**: 二重ループ→単一ループ\n",
- "3. **文字列操作の最適化**: 逐次連結→直接連結\n",
- "4. **条件分岐の最適化**: 三項演算子の使用\n",
+ "この最適化により、上位50-70%のパフォーマンスが期待できます!\n",
"\n",
- "この最適化により、上位50-70%のパフォーマンスが期待できます!"
+ "主な変更点:\n",
+ "1. ASCII図をmermaid形式のグラフに変換\n",
+ "2. フローチャート、シーケンス図、グラフを適切に使用\n",
+ "3. 色分けでわかりやすく視覚化\n",
+ "4. 矢印や関係性を明確に表現"
]
}
],
diff --git a/Shell/Bash/Leetcode/195. Tenth Line/TenthLine.ipynb b/Shell/Bash/Leetcode/195. Tenth Line/TenthLine.ipynb
new file mode 100644
index 00000000..55a01a24
--- /dev/null
+++ b/Shell/Bash/Leetcode/195. Tenth Line/TenthLine.ipynb
@@ -0,0 +1,380 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "a2d8d7c3",
+ "metadata": {},
+ "source": [
+ "# Bash Shellを用いた10行目の抽出問題\n",
+ "\n",
+ "この問題では、テキストファイルの10行目だけを出力する方法を解説します。3つの異なるアプローチと、それぞれの動作原理を図解付きで説明します。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "896f0cc3",
+ "metadata": {
+ "vscode": {
+ "languageId": "shellscript"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "#!/bin/bash\n",
+ "\n",
+ "# ========================================\n",
+ "# 解法1: sed を使用する方法\n",
+ "# ========================================\n",
+ "# Analyze Complexity\n",
+ "# Runtime 23 ms\n",
+ "# Beats 69.41%\n",
+ "# Memory 3.85 MB\n",
+ "# Beats 91.20%\n",
+ "\n",
+ "echo \"=== 解法1: sed ===\"\n",
+ "sed -n '10p' file.txt\n",
+ "\n",
+ "# 解説:\n",
+ "# -n : デフォルトの出力を抑制\n",
+ "# '10p' : 10行目のみを出力(print)\n",
+ "\n",
+ "\n",
+ "# ========================================\n",
+ "# 解法2: head と tail を組み合わせる方法\n",
+ "# ========================================\n",
+ "# Analyze Complexity\n",
+ "# Runtime 27 ms\n",
+ "# Beats 24.40%\n",
+ "# Memory 3.88 MB\n",
+ "# Beats 91.20%\n",
+ "\n",
+ "echo -e \"\\n=== 解法2: head + tail ===\"\n",
+ "tail -n +10 file.txt | head -n 1\n",
+ "\n",
+ "# 解説:\n",
+ "# head -n 10 : 最初の10行を取得\n",
+ "# tail -n 1 : その中から最後の1行(=10行目)を取得\n",
+ "\n",
+ "\n",
+ "# ========================================\n",
+ "# 解法3: awk を使用する方法\n",
+ "# ========================================\n",
+ "# Analyze Complexity\n",
+ "# Runtime 30 ms\n",
+ "# Beats 7.19%\n",
+ "# Memory 3.92 MB\n",
+ "# Beats 52.52%\n",
+ "\n",
+ "echo -e \"\\n=== 解法3: awk ===\"\n",
+ "awk 'NR==10' file.txt\n",
+ "\n",
+ "# 解説:\n",
+ "# NR : 現在の行番号(Number of Records)\n",
+ "# NR==10 : 行番号が10の時にその行を出力\n",
+ "\n",
+ "\n",
+ "# ========================================\n",
+ "# 補足: 10行未満の場合の処理\n",
+ "# ========================================\n",
+ "# Analyze Complexity\n",
+ "# Runtime 26 ms\n",
+ "# Beats 34.48%\n",
+ "# Memory 3.94 MB\n",
+ "# Beats 52.52%\n",
+ "\n",
+ "echo -e \"\\n=== 10行未満のファイルへの対応 ===\"\n",
+ "\n",
+ "# エラーチェック付きバージョン\n",
+ "if [ $(wc -l < file.txt) -ge 10 ]; then\n",
+ " sed -n '10p' file.txt\n",
+ "else\n",
+ " echo \"\"\n",
+ "fi"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b7bf7ad3",
+ "metadata": {},
+ "source": [
+ "## 詳細な図解と解説\n",
+ "\n",
+ "### **解法1: `sed` を使用する方法**\n",
+ "\n",
+ "```bash\n",
+ "sed -n '10p' file.txt\n",
+ "```\n",
+ "\n",
+ "**動作原理の図解:**\n",
+ "\n",
+ "```mermaid\n",
+ "graph LR\n",
+ " A[file.txt
Line 1-10] --> B[sed -n '10p'
-n: 自動出力OFF
10p: 10行目のみ出力]\n",
+ " B --> C[出力
Line 10]\n",
+ " \n",
+ " style A fill:#e3f2fd\n",
+ " style B fill:#fff3e0\n",
+ " style C fill:#e8f5e9\n",
+ "```\n",
+ "\n",
+ "**特徴:**\n",
+ "- `-n`: デフォルトの出力を抑制\n",
+ "- `10p`: 10行目に到達したら出力(print)\n",
+ "- **最もシンプルで効率的**\n",
+ "\n",
+ "---\n",
+ "\n",
+ "### **解法2: `head` と `tail` の組み合わせ(非推奨)**\n",
+ "\n",
+ "```bash\n",
+ "head -n 10 file.txt | tail -n 1\n",
+ "```\n",
+ "\n",
+ "**動作原理の図解:**\n",
+ "\n",
+ "```mermaid\n",
+ "graph LR\n",
+ " A[file.txt
Line 1-12] --> B[head -n 10
最初の10行を取得]\n",
+ " B --> C[Line 1-10]\n",
+ " C --> D[tail -n 1
最後の1行を取得]\n",
+ " D --> E[出力
Line 10]\n",
+ " \n",
+ " style A fill:#e3f2fd\n",
+ " style B fill:#fff3e0\n",
+ " style C fill:#f3e5f5\n",
+ " style D fill:#fff3e0\n",
+ " style E fill:#e8f5e9\n",
+ "```\n",
+ "\n",
+ "**処理の流れ:**\n",
+ "1. `head -n 10`: 最初の10行を抽出\n",
+ "2. `tail -n 1`: その中から最後の1行(つまり元の10行目)を取得\n",
+ "\n",
+ "**特徴:**\n",
+ "- 直感的で理解しやすい\n",
+ "- 2つのコマンドを組み合わせるため、やや冗長\n",
+ "- ⚠️ **10行未満のファイルでは誤動作する**\n",
+ "\n",
+ "---\n",
+ "\n",
+ "### **解法3: `awk` を使用する方法**\n",
+ "\n",
+ "```bash\n",
+ "awk 'NR==10' file.txt\n",
+ "```\n",
+ "\n",
+ "**動作原理の図解:**\n",
+ "\n",
+ "```mermaid\n",
+ "graph TD\n",
+ " A[file.txt] --> B{awk 'NR==10'}\n",
+ " B -->|NR=1| C[Line 1: No]\n",
+ " B -->|NR=2| D[Line 2: No]\n",
+ " B -->|NR=3| E[Line 3: No]\n",
+ " B -->|...| F[...]\n",
+ " B -->|NR=9| G[Line 9: No]\n",
+ " B -->|NR=10| H[Line 10: Yes ✓]\n",
+ " H --> I[出力
Line 10]\n",
+ " \n",
+ " style A fill:#e3f2fd\n",
+ " style B fill:#fff3e0\n",
+ " style H fill:#c8e6c9\n",
+ " style I fill:#e8f5e9\n",
+ "```\n",
+ "\n",
+ "**特徴:**\n",
+ "- `NR` (Number of Records): 現在の行番号を保持する変数\n",
+ "- 条件が真の時のみ行を出力(デフォルト動作)\n",
+ "- **テキスト処理に強力で柔軟性が高い**\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## **10行未満のファイルへの対応**\n",
+ "\n",
+ "### **5行のファイルの場合の動作比較:**\n",
+ "\n",
+ "```mermaid\n",
+ "graph TD\n",
+ " A[file.txt
5行のみ] --> B[sed -n '10p']\n",
+ " A --> C[\"head -n 10 | tail -n 1\"]\n",
+ " A --> D[awk 'NR==10']\n",
+ " \n",
+ " B --> E[何も出力しない ✓]\n",
+ " C --> F[Line 5 を出力 ✗]\n",
+ " D --> G[何も出力しない ✓]\n",
+ " \n",
+ " style A fill:#ffebee\n",
+ " style E fill:#e8f5e9\n",
+ " style F fill:#ffcdd2\n",
+ " style G fill:#e8f5e9\n",
+ "```\n",
+ "\n",
+ "**エラーチェック付きバージョン:**\n",
+ "\n",
+ "```bash\n",
+ "# 行数を確認してから処理\n",
+ "if [ $(wc -l < file.txt) -ge 10 ]; then\n",
+ " sed -n '10p' file.txt\n",
+ "else\n",
+ " echo \"エラー: ファイルが10行未満です\" >&2\n",
+ "fi\n",
+ "```\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## **各解法の比較表**\n",
+ "\n",
+ "| 解法 | コマンド | 長所 | 短所 | 10行未満の動作 |\n",
+ "|------|----------|------|------|----------------|\n",
+ "| **sed** | `sed -n '10p'` | シンプル、高速 | sed文法の知識が必要 | 何も出力しない ✓ |\n",
+ "| **head+tail** | `head -n 10 \\| tail -n 1` | 直感的 | 2つのプロセスが必要 | 最終行を出力 ✗ |\n",
+ "| **awk** | `awk 'NR==10'` | 柔軟性が高い | やや複雑 | 何も出力しない ✓ |\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## **推奨される解法**\n",
+ "\n",
+ "**最もシンプルで効率的:** `sed -n '10p' file.txt`\n",
+ "\n",
+ "これが最も一般的で、多くの場合に推奨される方法です!\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## **問題点の分析: なぜ `head -n 10 | tail -n 1` は間違いなのか**\n",
+ "\n",
+ "### **9行のファイルでの動作:**\n",
+ "\n",
+ "```mermaid\n",
+ "graph LR\n",
+ " A[file.txt
9行のみ] --> B[head -n 10
9行すべてを出力]\n",
+ " B --> C[Line 1-9]\n",
+ " C --> D[tail -n 1
最後の1行]\n",
+ " D --> E[出力: Line 9 ✗
期待: 何も出力しない]\n",
+ " \n",
+ " style A fill:#ffebee\n",
+ " style B fill:#fff3e0\n",
+ " style C fill:#f3e5f5\n",
+ " style D fill:#fff3e0\n",
+ " style E fill:#ffcdd2\n",
+ "```\n",
+ "\n",
+ "### **10行のファイルでの動作:**\n",
+ "\n",
+ "```mermaid\n",
+ "graph LR\n",
+ " A[file.txt
10行] --> B[head -n 10
10行を出力]\n",
+ " B --> C[Line 1-10]\n",
+ " C --> D[tail -n 1
最後の1行]\n",
+ " D --> E[出力: Line 10 ✓]\n",
+ " \n",
+ " style A fill:#e3f2fd\n",
+ " style B fill:#fff3e0\n",
+ " style C fill:#f3e5f5\n",
+ " style D fill:#fff3e0\n",
+ " style E fill:#e8f5e9\n",
+ "```\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## **正しい解法: `tail -n +10 | head -n 1`**\n",
+ "\n",
+ "```bash\n",
+ "tail -n +10 file.txt | head -n 1\n",
+ "```\n",
+ "\n",
+ "### **9行のファイルでの動作:**\n",
+ "\n",
+ "```mermaid\n",
+ "graph LR\n",
+ " A[file.txt
9行のみ] --> B[tail -n +10
10行目から取得]\n",
+ " B --> C[空
10行目が存在しない]\n",
+ " C --> D[head -n 1]\n",
+ " D --> E[出力: 空 ✓]\n",
+ " \n",
+ " style A fill:#ffebee\n",
+ " style B fill:#fff3e0\n",
+ " style C fill:#f5f5f5\n",
+ " style D fill:#fff3e0\n",
+ " style E fill:#e8f5e9\n",
+ "```\n",
+ "\n",
+ "### **10行のファイルでの動作:**\n",
+ "\n",
+ "```mermaid\n",
+ "graph LR\n",
+ " A[file.txt
10行] --> B[tail -n +10
10行目から取得]\n",
+ " B --> C[Line 10]\n",
+ " C --> D[head -n 1
最初の1行]\n",
+ " D --> E[出力: Line 10 ✓]\n",
+ " \n",
+ " style A fill:#e3f2fd\n",
+ " style B fill:#fff3e0\n",
+ " style C fill:#f3e5f5\n",
+ " style D fill:#fff3e0\n",
+ " style E fill:#e8f5e9\n",
+ "```\n",
+ "\n",
+ "**✅ 正しい動作:**\n",
+ "- `tail -n +10`: 10行目から最後まで取得(+10は「10行目から」の意味)\n",
+ "- `head -n 1`: その最初の1行を取得\n",
+ "\n",
+ "---\n",
+ "\n",
+ "## **正解のまとめ**\n",
+ "\n",
+ "LeetCode/オンラインジャッジで正解する解法:\n",
+ "\n",
+ "```bash\n",
+ "# 解法1(最もシンプル)- 推奨 ⭐\n",
+ "sed -n '10p' file.txt\n",
+ "\n",
+ "# 解法2(汎用性が高い)- 推奨 ⭐\n",
+ "awk 'NR==10' file.txt\n",
+ "\n",
+ "# 解法3(tailの+記法を使用)- 推奨 ⭐\n",
+ "tail -n +10 file.txt | head -n 1\n",
+ "```\n",
+ "\n",
+ "### **3つの解法の比較フローチャート:**\n",
+ "\n",
+ "```mermaid\n",
+ "graph TD\n",
+ " A[ファイルの行数] --> B{10行以上?}\n",
+ " B -->|Yes| C[sed -n '10p']\n",
+ " B -->|Yes| D[awk 'NR==10']\n",
+ " B -->|Yes| E[\"tail -n +10 | head -n 1\"]\n",
+ " B -->|No| F[何も出力しない]\n",
+ " \n",
+ " C --> G[Line 10 出力 ✓]\n",
+ " D --> G\n",
+ " E --> G\n",
+ " \n",
+ " style A fill:#e3f2fd\n",
+ " style B fill:#fff3e0\n",
+ " style C fill:#c8e6c9\n",
+ " style D fill:#c8e6c9\n",
+ " style E fill:#c8e6c9\n",
+ " style F fill:#ffcdd2\n",
+ " style G fill:#e8f5e9\n",
+ "```\n",
+ "\n",
+ "これらはすべて、ファイルが10行未満の場合は**何も出力しない**ため、テストケースをすべてパスします!\n",
+ "\n",
+ "主な変更点:\n",
+ "1. すべてのASCII図をMermaid形式に変換\n",
+ "2. グラフの種類を適切に選択(`graph LR`、`graph TD`)\n",
+ "3. スタイリングを追加して視覚的に分かりやすく\n",
+ "4. 正しい解法と誤った解法を色分けで明示\n",
+ "5. フローチャートで処理の流れを明確化"
+ ]
+ }
+ ],
+ "metadata": {
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}