diff --git a/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/README.md b/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/README.md new file mode 100644 index 00000000..a7e14fc9 --- /dev/null +++ b/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/README.md @@ -0,0 +1,392 @@ +# Sqrt(x) - 整数平方根を二分探索で求める + + + +## 目次 + +- [Overview (概要)](#overview) +- [Algorithm (アルゴリズム)](#algorithm) +- [Complexity (計算量)](#complexity) +- [Implementation (実装)](#implementation) +- [Optimization (最適化)](#optimization) + +--- + +

Overview (概要)

+ +### 問題要約 + +非負整数 `x` を受け取り、**floor(√x)**(小数点以下切り捨ての整数平方根)を返す。 + +- `math.sqrt`・`**`・`pow(x, 0.5)` などの **組み込み指数関数・演算子は使用禁止** +- 純粋な整数演算のみで平方根を求める + +### 関数シグネチャ(LeetCode 準拠) + +```python +class Solution: + def mySqrt(self, x: int) -> int: +``` + +### 入出力仕様 + +| 項目 | 内容 | +| ---- | --------------------------------- | +| 入力 | `x: int`(`0 ≤ x ≤ 2^31 - 1`) | +| 出力 | `int`:floor(√x) | +| 制約 | 非負整数。`math.sqrt` / `**` 禁止 | + +### 代表例 + +| x | 出力 | 説明 | +| ------------ | ------- | ----------------------- | +| `4` | `2` | √4 = 2.0 → 2 | +| `8` | `2` | √8 ≈ 2.828 → 切り捨て 2 | +| `0` | `0` | エッジケース | +| `1` | `1` | エッジケース | +| `2147483647` | `46340` | i32::MAX 付近 | + +--- + +

アルゴリズム要点(TL;DR)

+ +- **戦略**: 探索範囲 `[1, x // 2]` に対して**二分探索**を適用 +- **データ構造**: 固定スカラー変数 `low`, `high`, `mid` のみ(追加アロケーションなし) +- **中点計算**: `(low + high) >> 1` — ビットシフトで整数除算(CPython 最速) +- **判定**: `mid * mid` と `x` を比較(Python `int` は任意精度 → オーバーフロー完全ゼロ) +- **終了条件**: `low > high` → `high` = floor(√x) +- **時間計算量**: O(log n) — 最大 31 回のイテレーション(2^31 制約下) +- **空間計算量**: O(1) — スタック変数のみ、ヒープアロケーションなし + +--- + +### 図解 + +### フローチャート + +```mermaid +flowchart TD + Start[Start mySqrt x] --> TypeCheck{x is valid int} + TypeCheck -- No --> RaiseType[Raise TypeError] + TypeCheck -- Yes --> RangeCheck{x < 0 or x ≥ 2^31} + RangeCheck -- Yes --> RaiseVal[Raise ValueError] + RangeCheck -- No --> EdgeCase{x < 2} + EdgeCase -- Yes --> RetX[Return x] + EdgeCase -- No --> Init[low=1 high=x shr 1] + Init --> LoopCond{low <= high} + LoopCond -- No --> RetHigh[Return high] + LoopCond -- Yes --> CalcMid[mid = low+high shr 1] + CalcMid --> CalcSq[sq = mid times mid] + CalcSq --> Cmp{sq vs x} + Cmp -- Equal --> RetMid[Return mid] + Cmp -- Less --> UpLow[low = mid+1] + Cmp -- Greater --> DownHigh[high = mid-1] + UpLow --> LoopCond + DownHigh --> LoopCond +``` + +_入力バリデーション → エッジケース早期リターン → 二分探索ループ の3ステージ構成。`low > high` になった瞬間に `high = floor(√x)` が確定する。_ + +--- + +### データフロー図 + +```mermaid +graph LR + subgraph Validation + A[Input x] --> B[isinstance check] + B --> C[range check] + end + subgraph EarlyReturn + C --> D{x < 2} + D -- Yes --> E[return x] + end + subgraph BinarySearch + D -- No --> F[low=1 high=x shr 1] + F --> G[mid = low+high shr 1] + G --> H[sq = mid times mid] + H --> I{compare sq to x} + I -- Equal --> J[return mid] + I -- Less --> K[low = mid+1] + I -- Greater --> L[high = mid-1] + K --> G + L --> G + end + subgraph Done + I -- loop exit --> M[return high] + end +``` + +_左から右へ: バリデーション → 早期リターン判定 → 二分探索本体 → 結果返却。ループはフィードバックアーク `K→G`, `L→G` で表現。_ + +--- + +### 手動トレース(x = 8) + +``` +探索範囲初期値: low=1, high=4 (= 8 >> 1) + +┌─────┬──────┬───────┬────────────────────────────────┐ +│ Iter│ mid │ sq │ アクション │ +├─────┼──────┼───────┼────────────────────────────────┤ +│ 1 │ 2 │ 4 │ 4 < 8 → low = 3 │ +│ 2 │ 3 │ 9 │ 9 > 8 → high = 2 │ +│ 3 │ (終) │ - │ low(3) > high(2) → return 2 ✓ │ +└─────┴──────┴───────┴────────────────────────────────┘ +``` + +--- + +### 正しさのスケッチ + +### ループ不変条件(Loop Invariant) + +ループの各反復前に以下が成立する: + +> `(low - 1)^2 ≤ x` かつ `(high + 1)^2 > x` + +この不変条件により、**真の答え `floor(√x)` は常に `[low - 1, high]` の範囲に含まれる**ことが保証される。ループ終了時 (`low > high`) には `high = floor(√x)` が確定する。 + +| フェーズ | 不変条件の確認 | +| -------------- | -------------------------------------------------------------------------- | +| **初期化前** | `low=1`, `high=x//2`。x≥2 のとき `0^2=0≤x` かつ `(x//2+1)^2>x` が成立 | +| **sq < x 時** | `mid^2 < x` → `mid` は答えより小さい → `low = mid+1` で下限を安全に上げる | +| **sq > x 時** | `mid^2 > x` → `mid` は答えより大きい → `high = mid-1` で上限を安全に下げる | +| **sq == x 時** | 完全平方数 → `mid` が答えそのもの → 即リターン | +| **終了時** | `low > high` → `high = floor(√x)` が確定 | + +### 終了性 + +- 各イテレーションで `high - low` が必ず 1 以上減少する(`low` が増加 **または** `high` が減少) +- 探索範囲は有限(`[1, x//2]`)→ 必ず有限回で終了 + +--- + +

Complexity (計算量)

+ +| 観点 | 計算量 | 補足 | +| -------------- | -------- | --------------------------------------------- | +| **時間計算量** | O(log n) | 探索範囲が毎回半減。x ≤ 2^31 で最大 31 回 | +| **空間計算量** | O(1) | `low`, `high`, `mid`, `sq` の固定スカラーのみ | + +### アプローチ比較表 + +| アプローチ | 時間 | 空間 | 誤差 | 保守性 | 選択 | +| ------------ | ------------ | -------- | ------------ | ------- | ------ | +| 線形探索 | O(√n) | O(1) | なし | ★★★ | ✗ | +| **二分探索** | **O(log n)** | **O(1)** | **なし** | **★★★** | **✅** | +| ニュートン法 | O(log log n) | O(1) | 浮動小数誤差 | ★★☆ | ✗ | +| `math.isqrt` | O(log n) | O(1) | なし | ★★★ | 禁止 | + +> **選択理由**: ニュートン法は収束が速いが `float` の打ち切り誤差管理が複雑。二分探索は**整数演算のみ・誤差ゼロ・Loop Invariant が明確**で保守性が最高。 + +--- + +

Implementation (実装)

+ +### Python 実装 + +```python +from __future__ import annotations + +from typing import Any + + +class Solution: + """ + LeetCode 69 - Sqrt(x) + math.sqrt / ** 演算子禁止。二分探索で floor(√x) を求める。 + + Time: O(log n) — 最大 31 回のイテレーション + Space: O(1) — スタック変数のみ + """ + + # ------------------------------------------------------------------ # + # 業務開発版(型安全・エラーハンドリング・pylance 対応) + # ------------------------------------------------------------------ # + def mySqrt(self, x: int) -> int: + """ + 非負整数 x の平方根を小数点以下切り捨てで返す。 + + Args: + x: 非負整数 (0 <= x <= 2^31 - 1) + + Returns: + floor(√x) の整数値 + + Raises: + TypeError: x が int でない場合(bool も除外) + ValueError: x が負数または制約超過の場合 + """ + # ── 実行時型ガード(pylance narrowing 対応) ────────────────── + # bool は int のサブクラスのため明示的に除外する + if not isinstance(x, int) or isinstance(x, bool): + raise TypeError(f"x must be int, got {type(x).__name__!r}") + + if x < 0: + raise ValueError(f"x must be non-negative, got {x}") + + if x > 2**31 - 1: + raise ValueError(f"x={x} exceeds constraint 2^31 - 1") + + return self._binary_search_sqrt(x) + + def _binary_search_sqrt(self, x: int) -> int: + """ + 二分探索による整数平方根の内部実装。 + + Loop Invariant: + - (low - 1)^2 <= x + - (high + 1)^2 > x + → ループ終了時: high = floor(√x) + + Args: + x: 検証済み非負整数 + + Returns: + floor(√x) + """ + # ── エッジケース早期リターン ────────────────────────────────── + # x=0 → 0、x=1 → 1(ループ不要) + if x < 2: + return x + + # ── 二分探索 ───────────────────────────────────────────────── + # 探索上限を x//2 に絞る(x>=2 のとき floor(√x) <= x//2 が保証される) + low: int = 1 + high: int = x >> 1 # ビットシフトで x // 2 + + while low <= high: + # 中点計算: ビットシフトで整数除算(CPython 最速) + mid: int = (low + high) >> 1 + sq: int = mid * mid # Python int は任意精度 → オーバーフローなし + + if sq == x: + # 完全平方数: mid が答えそのもの + return mid + elif sq < x: + # mid が小さすぎる → 下限を引き上げ + low = mid + 1 + else: + # mid が大きすぎる → 上限を引き下げ + high = mid - 1 + + # ループ終了後: high = floor(√x) + return high + + # ------------------------------------------------------------------ # + # 競技プログラミング版(型チェック省略・速度最優先) + # ------------------------------------------------------------------ # + def mySqrt_competitive(self, x: int) -> int: + """ + Competitive: O(log n) / O(1) + エラーハンドリング省略・CPython 最速パターン。 + """ + if x < 2: + return x + low, high = 1, x >> 1 + while low <= high: + mid = (low + high) >> 1 + sq = mid * mid + if sq == x: + return mid + elif sq < x: + low = mid + 1 + else: + high = mid - 1 + return high +``` + +--- + +

CPython 最適化ポイント

+ +### 採用した最適化テクニック + +| テクニック | 詳細 | +| ------------------------ | -------------------------------------------------------------------------------------------- | +| **ビットシフト除算** | `x >> 1` は `x // 2` より CPython バイトコード (`BINARY_OP`) が 1 命令少ない | +| **ローカル変数への束縛** | `low`, `high`, `mid`, `sq` をすべてローカルスコープで保持 → `LOAD_FAST` でグローバルより高速 | +| **Python 任意精度 int** | `mid * mid` が 2^62 を超えても**キャスト不要**(Rust/TS の `u64` 昇格が不要) | +| **早期リターン** | `x < 2` を先頭でチェック → ループ初期化コストをゼロに | +| **属性アクセス削減** | `self._binary_search_sqrt` の内部はすべてスカラー演算 → `LOAD_ATTR` なし | + +### 採用しなかった最適化と理由 + +| 候補 | 不採用理由 | +| --------------- | -------------------------------------------- | +| `math.isqrt(x)` | 問題の禁止制約(組み込み指数関数相当)に抵触 | +| `math.sqrt(x)` | 浮動小数誤差の可能性 + 禁止制約 | +| `lru_cache` | 単一呼び出しのためキャッシュ効果なし | +| ニュートン法 | `float` 収束判定の複雑性 + 誤差リスク | + +--- + +

エッジケースと検証観点

+ +| ケース | 入力 | 期待出力 | 処理パス | +| ---------------- | ---------------- | ------------ | -------------------------------------------- | +| 最小値ゼロ | `x = 0` | `0` | 早期リターン `x < 2` | +| 最小の完全平方数 | `x = 1` | `1` | 早期リターン `x < 2` | +| 完全平方数(小) | `x = 4` | `2` | `sq == x` → 即リターン | +| 非完全平方数 | `x = 8` | `2` | ループ終了 `return high` | +| 完全平方数(大) | `x = 2147395600` | `46340` | `sq == x` → 即リターン | +| i32 最大値付近 | `x = 2147483647` | `46340` | ループ終了 `return high` | +| 境界直前 | `x = 2` | `1` | `sq=1<2`→low=2, `sq=4>2`→high=1 → `return 1` | +| 境界直前 | `x = 3` | `1` | 同上 | +| `bool` 混入 | `x = True` | `TypeError` | 型ガード | +| 負数 | `x = -1` | `ValueError` | 範囲ガード | +| `float` 混入 | `x = 4.0` | `TypeError` | 型ガード | +| 制約超過 | `x = 2**31` | `ValueError` | 範囲ガード | + +### 手動トレース(x = 2 / x = 3) + +``` +x=2: low=1, high=1 + Iter1: mid=1, sq=1 < 2 → low=2 + low(2) > high(1) → return high=1 ✓ + +x=3: low=1, high=1 + Iter1: mid=1, sq=1 < 3 → low=2 + low(2) > high(1) → return high=1 ✓ +``` + +--- + +

FAQ

+ +**Q1. なぜ探索上限を `x // 2` にできるのか?** + +x ≥ 2 のとき、`floor(√x) ≤ x // 2` が常に成立する。 +たとえば x=4 → `√4=2 ≤ 2`、x=100 → `√100=10 ≤ 50`。 +x=0, 1 は早期リターンで処理済みなので、探索範囲を半分に削減できる。 + +--- + +**Q2. ニュートン法でも解けるのでは?** + +解けるが、`float` 演算を伴うため **収束判定** が難しい。 +例えば x=2147395600 のような大きな完全平方数で `int(result)` が 46339 になる可能性がある。 +二分探索は**純粋な整数演算**のみで誤差ゼロが保証されるため本問題では最適。 + +--- + +**Q3. Python では `mid * mid` がオーバーフローしないのか?** + +Python の `int` は**任意精度**(bignum)のため、どんなに大きな値でもオーバーフローしない。 +これは Rust(`u64` へのキャストが必要)や TypeScript(`number` の 53bit 精度制限)と異なる Python 最大の利点の一つ。 + +--- + +**Q4. `(low + high) >> 1` と `(low + high) // 2` はどちらが速いか?** + +CPython では `>>` の方がわずかに速い。`BINARY_OP` の実装上、右辺が整数リテラルの場合に最適化される。 +アルゴリズム的な意味は同一(非負整数の整数除算)。 + +--- + +**Q5. なぜ `bool` を型ガードで除外するのか?** + +Python では `bool` は `int` のサブクラスであるため、`isinstance(True, int)` は `True` を返す。 +`True` は `1`、`False` は `0` として動作してしまうため、**意図しない入力**として明示的に弾いている。 +競技プログラミング版ではこのチェックを省略しても LeetCode 制約上は問題ない。 diff --git a/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/README_react.html b/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/README_react.html new file mode 100644 index 00000000..4ebb2e52 --- /dev/null +++ b/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/README_react.html @@ -0,0 +1,1279 @@ + + + + + + LeetCode 69 - Sqrt(x) | 二分探索 + + + + + + + + + + + + + + + + + + + +
+ + + + +
+

+ アルゴリズム概要 +

+
+
+
+ O(log n) +
+
時間計算量
+
+
+
O(1)
+
空間計算量
+
+
+
+ ≤ 31回 +
+
最大反復数
+
+
+
+ 整数演算 +
+
浮動小数誤差ゼロ
+
+
+ +
+
+

問題文

+

+ 非負整数 + x を受け取り、 + floor(√x)(小数点以下切り捨て)を返す。
+ math.sqrt**・ + pow(x, 0.5) + などの組み込み指数演算は使用禁止。 +

+
+
+

制約

+
    +
  • + ✅ + 0 ≤ x ≤ 2³¹ - 1(非負整数) +
  • +
  • + 🚫 + math.sqrt + 禁止 +
  • +
  • + 🚫 + ** + 演算子 禁止 +
  • +
  • + 🚫 + pow(x, 0.5) + 禁止 +
  • +
+
+
+ +
+

入出力例

+
+
+
EXAMPLE 1
+
+ Input: x = 4 +
+
+ Output: 2 +
+
+ √4 = 2.0 → 2(完全平方数) +
+
+
+
EXAMPLE 2
+
+ Input: x = 8 +
+
+ Output: 2 +
+
√8 ≈ 2.828 → 切り捨て 2
+
+
+
+
+ + +
+

+ ステップバイステップ解説 +

+
+
+ + +
+

+ コード実装 +

+ + +
+ + + +
+ +
+
class Solution:
+    def mySqrt(self, x: int) -> int:
+        # エッジケース: x=0, x=1 は即リターン
+        if x < 2:
+            return x
+
+        # 探索範囲: [1, x // 2]
+        # 根拠: x >= 2 のとき floor(√x) <= x // 2 が常に成立
+        low: int = 1
+        high: int = x >> 1  # ビットシフトで x // 2(CPython 最速)
+
+        # Loop Invariant:
+        #   (low - 1)^2 <= x  かつ  (high + 1)^2 > x
+        # → ループ終了時: high = floor(√x)
+        while low <= high:
+            mid: int = (low + high) >> 1  # 中点計算
+            sq:  int = mid * mid          # Python int は任意精度 → オーバーフローなし
+
+            if sq == x:
+                return mid       # 完全平方数: 即リターン
+            elif sq < x:
+                low = mid + 1    # mid が小さすぎる → 下限を引き上げ
+            else:
+                high = mid - 1   # mid が大きすぎる → 上限を引き下げ
+
+        # ループ終了後: high = floor(√x)
+        return high
+
+ + + + +
+ + +
+

+ 処理フローチャート +

+
+
+graph TD
+    Start["開始: mySqrt(x)"]
+    CheckEdge{"x < 2?"}
+    ReturnX["return x"]
+    Init["初期化: low=1, high=x/2"]
+    LoopCheck{"low <= high?"}
+    ReturnHigh["return high"]
+    CalcMid["中点計算
mid=(low+high)/2"] + Compare{"sq vs x"} + ReturnMid["return mid"] + UpdateLow["low=mid+1"] + UpdateHigh["high=mid-1"] + End["終了"] + + Start --> CheckEdge + CheckEdge -->|Yes| ReturnX + CheckEdge -->|No| Init + Init --> LoopCheck + LoopCheck -->|No| ReturnHigh + LoopCheck -->|Yes| CalcMid + CalcMid --> Compare + Compare -->|Equal| ReturnMid + Compare -->|Less| UpdateLow + Compare -->|Greater| UpdateHigh + UpdateLow --> LoopCheck + UpdateHigh --> LoopCheck + ReturnX --> End + ReturnMid --> End + ReturnHigh --> End + + style Start fill:#d1fae5,stroke:#10b981,stroke-width:3px + style End fill:#d1fae5,stroke:#10b981,stroke-width:3px + style CheckEdge fill:#fef3c7,stroke:#f59e0b,stroke-width:2px + style LoopCheck fill:#fef3c7,stroke:#f59e0b,stroke-width:2px + style Compare fill:#fef3c7,stroke:#f59e0b,stroke-width:2px + style ReturnX fill:#d1fae5,stroke:#059669,stroke-width:2px + style ReturnMid fill:#d1fae5,stroke:#059669,stroke-width:2px + style ReturnHigh fill:#d1fae5,stroke:#059669,stroke-width:2px + style Init fill:#e0f2fe,stroke:#0284c7,stroke-width:2px + style CalcMid fill:#e0f2fe,stroke:#0284c7,stroke-width:2px + style UpdateLow fill:#e0f2fe,stroke:#0284c7,stroke-width:2px + style UpdateHigh fill:#fee2e2,stroke:#dc2626,stroke-width:2px +
+
+

+ フローの説明:
+ 1. エッジケース判定: x < 2 の場合は x をそのまま返す(0→0, + 1→1)
+ 2. 探索範囲初期化: low=1, + high=x>>1(x/2)で探索上限を半分に削減
+ 3. 二分探索ループ: low>high になるまで + mid=(low+high)>>1 を計算
+ 4. 三方比較: sq==x(即リターン)/ sq<x(low引き上げ)/ + sq>x(high引き下げ)
+ 5. ループ終了: high = floor(√x) が確定 → return high
+ ── 紫の破線: + ループバック(探索範囲を狭めて次のイテレーションへ) +

+
+ + +
+

+ 計算量分析 +

+ +
+
+
O(log n)
+
時間計算量
+
+ x ≤ 2³¹ で最大 + 31 回のイテレーション
探索範囲が毎ステップ半減する +
+
+
+
O(1)
+
空間計算量
+
+ low / high / mid / sq の
スカラー変数のみ。ヒープ確保ゼロ +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ アプローチ + + 時間 + + 空間 + + 誤差 + + 保守性 + + 選択 +
線形探索 + O(√n) + + O(1) + + なし + ★★★ + ✗ 遅い +
+ 二分探索 ✅ + + O(log n) + + O(1) + + なし + + ★★★ + + ✅ 最適 +
ニュートン法 + O(log log n) + + O(1) + + float誤差 + ★★☆ + △ 誤差リスク +
math.isqrt() + O(log n) + + O(1) + + なし + ★★★ + 🚫 禁止 +
+
+ +
+

+ Loop Invariant(ループ不変条件) +

+
+
// ループの各反復前に成立:
+
+ (low - 1)² ≤ x + ← low より小さい値の二乗は x 以下 +
+
+ (high + 1)² > x + ← high より大きい値の二乗は x より大きい +
+
+ // → ループ終了時: high = floor(√x) が数学的に保証される +
+
+
+
+
+ + + + + + + + + + + + diff --git a/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/Sqrt(x)_python.md b/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/Sqrt(x)_python.md new file mode 100644 index 00000000..44e772c1 --- /dev/null +++ b/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/Sqrt(x)_python.md @@ -0,0 +1,199 @@ +## 1. 問題分析結果 + +## 競技プログラミング視点 + +- 制約 `0 ≤ x ≤ 2³¹ - 1` → 探索空間は最大 `~46340` → **二分探索で最大31回**のイテレーションで確定 +- Python の `int` は任意精度 → オーバーフロー完全ゼロ・キャスト不要(Rust/TSと異なる大きな利点) +- `x >> 1` でビットシフト整数除算 → CPython の `BINARY_OP` 最適化が効く +- `math.sqrt` / `**` / `pow` は使用禁止 → 純粋な整数演算のみで完結 + +## 業務開発視点 + +- 入力は `int` だが、`float`・`str`・負数が混入する可能性 → **実行時型ガード**が必要 +- `pylance` 対応: 戻り値型 `int` を明示し、`isinstance` ガードで型を narrowing +- `ValueError` / `TypeError` を使い分けて呼び出し元が例外種別で判断できるように設計 + +## Python特有分析 + +- **データ構造**: 変数3つ(`low`, `high`, `mid`)のみ → `list`/`deque` 不要 +- **標準ライブラリ活用**: `math` モジュールは使用禁止のため不使用。ビットシフト演算子のみ +- **CPython最適化**: `while` ループ + ビットシフト → 組み込み演算子レベルで最速 + +--- + +## 2. アルゴリズムアプローチ比較 + +| アプローチ | 時間計算量 | 空間計算量 | Python実装コスト | 可読性 | 標準ライブラリ活用 | CPython最適化 | 備考 | +| ----------------- | ------------ | ---------- | ---------------- | ------ | ------------------ | ------------- | ----------------------- | +| **線形探索** | O(√n) | O(1) | 低 | ★★★ | なし | 適 | x=2³¹で~46340回、非効率 | +| **二分探索** | O(log n) | O(1) | 低 | ★★★ | なし | ✅ 適 | 整数演算のみ・誤差ゼロ | +| **ニュートン法** | O(log log n) | O(1) | 中 | ★★☆ | なし | 不適 | float収束判定が曖昧 | +| **`isqrt()`使用** | O(log n) | O(1) | 最低 | ★★★ | `math.isqrt` | 適 | 問題の禁止制約に抵触 | + +--- + +## 3. 採用アルゴリズムと根拠 + +- **選択**: 二分探索(Binary Search) +- **理由**: O(log n)・整数演算のみ・Python の任意精度 `int` でオーバーフロー皆無・Loop Invariant が明確で保守性最高 +- **Python最適化戦略**: `x >> 1`(ビットシフト)+ `(low + high) >> 1`(中点計算)で CPython のバイトコード最適化を最大活用 +- **トレードオフ**: ニュートン法は収束が速いが `float` の誤差管理が複雑 → 保守性 vs わずかな速度差で二分探索を選択 + +--- + +## 4. 実装コード + +```python +# Runtime 3 ms +# Beats 66.79% +# Memory 19.32 MB +# Beats 57.57% + +class Solution: + """ + Sqrt(x) — 整数平方根(切り捨て) + math.sqrt / ** 演算子禁止・二分探索で実装 + """ + + # ------------------------------------------------------------------ # + # 業務開発版(型安全・エラーハンドリング・pylance 対応) + # ------------------------------------------------------------------ # + def mySqrt(self, x: int) -> int: + """ + 非負整数 x の平方根を小数点以下切り捨てで返す。 + + Args: + x: 非負整数 (0 ≤ x ≤ 2^31 - 1) + + Returns: + floor(√x) の整数値 + + Raises: + TypeError: x が int でない場合 + ValueError: x が負数または制約超過の場合 + + Complexity: + Time: O(log n) — 最大 31 回のイテレーション + Space: O(1) — 固定変数のみ、追加アロケーションなし + """ + # ── 実行時型ガード(pylance narrowing 対応) ────────────────── + if not isinstance(x, int) or isinstance(x, bool): + raise TypeError(f"x must be int, got {type(x).__name__!r}") + + if x < 0: + raise ValueError(f"x must be non-negative, got {x}") + + if x > 2**31 - 1: + raise ValueError(f"x={x} exceeds constraint 2^31 - 1") + + return self._binary_search_sqrt(x) + + def _binary_search_sqrt(self, x: int) -> int: + """ + 二分探索による整数平方根の計算(内部実装)。 + + Loop Invariant: + low - 1 の二乗は x 以下 + high + 1 の二乗は x より大きい + → ループ終了時: high = floor(√x) + + Args: + x: 検証済み非負整数 + + Returns: + floor(√x) + """ + # ── エッジケース早期リターン ────────────────────────────────── + # x=0 → 0、x=1 → 1(ループを回さず即リターン) + if x < 2: + return x + + # ── 二分探索 ───────────────────────────────────────────────── + # 探索範囲: [1, x // 2] + # 根拠: x >= 2 のとき floor(√x) <= x // 2 が常に成立 + low: int = 1 + high: int = x >> 1 # == x // 2(ビットシフトで整数除算) + + while low <= high: + # オーバーフロー不要(Python の int は任意精度)だが + # ビットシフトで中点計算 → CPython バイトコード最適化 + mid: int = (low + high) >> 1 + square: int = mid * mid + + if square == x: + # 完全平方数: mid が答えそのもの + return mid + elif square < x: + # mid が小さすぎる → 下限を引き上げ + low = mid + 1 + else: + # mid が大きすぎる → 上限を引き下げ + high = mid - 1 + + # ループ終了後: high = floor(√x) + # 例: x=8 → mid=2(4<8)→low=3, mid=3(9>8)→high=2 + # low(3) > high(2) → return 2 ✓ + return high + + # ------------------------------------------------------------------ # + # 競技プログラミング版(型チェック・docstring 省略・速度最優先) + # ------------------------------------------------------------------ # + def mySqrt_competitive(self, x: int) -> int: + """ + Competitive: O(log n) / O(1) + エラーハンドリング省略・CPython 最速パターン + """ + if x < 2: + return x + + low, high = 1, x >> 1 + + while low <= high: + mid = (low + high) >> 1 + sq = mid * mid + if sq == x: + return mid + elif sq < x: + low = mid + 1 + else: + high = mid - 1 + + return high +``` + +--- + +## 5. アルゴリズム動作トレース + +``` +─── x = 4 ───────────────────────────────────────────────────── + 初期値: low=1, high=2 + + Iter 1: mid=1, sq=1 < 4 → low=2 + Iter 2: mid=2, sq=4 == 4 → return 2 ✓ + +─── x = 8 ───────────────────────────────────────────────────── + 初期値: low=1, high=4 + + Iter 1: mid=2, sq=4 < 8 → low=3 + Iter 2: mid=3, sq=9 > 8 → high=2 + low(3) > high(2) → return high=2 ✓ + +─── エッジケース ──────────────────────────────────────────────── + x=0 → early return 0 + x=1 → early return 1 + x=2 → low=1,high=1 → mid=1(1<2)→low=2 → 終了: return 1 ✓ + x=2147483647 → return 46340 +``` + +--- + +## 6. Python固有の設計ポイント整理 + +| 観点 | 実装での対応 | +| -------------------------- | --------------------------------------------------------------------------- | +| **オーバーフロー完全ゼロ** | Python `int` は任意精度 → `u64` キャスト(Rust)が不要 | +| **型narrowing (pylance)** | `isinstance(x, int) and not isinstance(x, bool)` で `bool` 混入も排除 | +| **ビットシフト最適化** | `x >> 1` / `(low+high) >> 1` → CPython `BINARY_OP` 命令で最速 | +| **`bool` ガード** | Python では `bool` は `int` のサブクラス → `isinstance(x, bool)` で明示排除 | +| **2パターン分離** | 業務版(型安全)と競技版(速度最優先)を明確に分離し保守性向上 | diff --git a/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/Sqrt(x)_rust.md b/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/Sqrt(x)_rust.md new file mode 100644 index 00000000..e6c7a8bf --- /dev/null +++ b/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/Sqrt(x)_rust.md @@ -0,0 +1,167 @@ +## 1. 問題の分析 + +## 競技プログラミング視点での分析 + +- 探索空間 `[0, x]` は単調増加 → **二分探索**が最適(最大31回のイテレーション) +- `u32::MAX = 2³¹ - 1 = 2147483647` → `mid` の最大値は `x >> 1` で約 `2³⁰`、よって `mid * mid` は最大 `(2³⁰)² ≈ 1.15×10¹⁸` に達するため、**`u64` へのキャスト**でオーバーフローを防止 +- スタックのみ使用・ヒープアロケーション完全ゼロ → キャッシュに最適 +- 全変数が `Copy` 型(`u32`, `u64`) → 借用・所有権の複雑性なし + +## 業務開発視点での分析 + +- LeetCode 制約 `0 ≤ x ≤ 2³¹ - 1` → `i32` ではなく**`u32` が意味論的に正確**(非負整数) +- `Result` で不正入力を型レベルで表現 +- `Option` ではなく `Result` を選択 → エラー種別を呼び出し元に伝達可能 + +## Rust特有の考慮点 + +- `i32` パラメータ(LeetCode signature)を `u32` に変換する際の**符号安全変換** `u32::try_from()` を活用 +- `mid.checked_mul(mid)` で算術オーバーフローを**型安全に**回避する選択肢もあるが、`u64` キャストの方がパフォーマンス上有利 +- イテレータ vs 命令型ループ: 二分探索は**収束条件が動的**なため `while` ループが最適(`Iterator` では表現しにくい) + +--- + +## 2. アルゴリズムアプローチ比較 + +| アプローチ | 時間計算量 | 空間計算量 | Rust実装コスト | 安全性 | 可読性 | 備考 | +| ------------------- | ------------ | ---------- | -------------- | ------ | ------ | ------------------------------ | +| **線形探索** | O(√n) | O(1) | 低 | 高 | 高 | x=2³¹では~46340回、非効率 | +| **二分探索** | O(log n) | O(1) | 低 | 高 | 高 | ✅ 整数演算のみ・誤差なし | +| **ニュートン法** | O(log log n) | O(1) | 中 | 中 | 中 | 浮動小数点誤差・収束判定が複雑 | +| **ビット操作(MSB)** | O(log n) | O(1) | 高 | 中 | 低 | 最上位ビットから確定、可読性低 | + +--- + +## 3. 選択したアルゴリズムと理由 + +- **選択したアプローチ**: 二分探索(Binary Search) +- **理由**: + - O(log n) = **最大31回**のループで解が確定(`log₂(2³¹) ≈ 31`) + - 浮動小数点を**一切使わない整数演算**のみ → Rust の `u32`/`u64` 型安全性を最大活用 + - Loop Invariant(`high * high <= x`)がコード上で自明 → 保守性・レビュー効率が高い +- **Rust特有の最適化ポイント**: + - `u32` / `u64` は `Copy` トレイト実装済み → 借用なしで値渡し、ゼロコスト + - 全変数がスタック配置 → ヒープアロケーション完全ゼロ + - モノモーフィゼーション不要(ジェネリクスなし) → コンパイル結果がシンプルで高速 + +--- + +## 4. 実装コード + +```rust +impl Solution { +// Runtime 0 ms +// Beats 100.00% +// Memory 2.07 MB +// Beats 90.93% + + /// 非負整数 x の平方根を小数点以下切り捨てで返す(二分探索) + /// + /// # Arguments + /// * `x` - 非負整数 (0 ≤ x ≤ 2^31 - 1) + /// + /// # Returns + /// `floor(√x)` を `i32` で返す + /// + /// # Panics + /// `x` が負の場合(LeetCode 制約上は発生しない) + /// + /// # Complexity + /// - Time: O(log n) — 最大 31 回のイテレーション + /// - Space: O(1) — スタック変数のみ、ヒープアロケーションなし + pub fn my_sqrt(x: i32) -> i32 { + // ── 符号安全変換 ───────────────────────────────────────────── + // LeetCode は i32 で渡すが、問題制約は非負整数 → u32 に変換 + // x < 0 は制約上あり得ないが、安全のため assert で明示 + debug_assert!(x >= 0, "x must be non-negative, got {x}"); + let x = x as u32; + + // ── エッジケース早期リターン ────────────────────────────────── + // x = 0 → 0、x = 1 → 1(二分探索を回さず即リターン) + if x < 2 { + return x as i32; + } + + // ── 二分探索 ───────────────────────────────────────────────── + // 探索範囲: [1, x / 2] + // 根拠: x >= 2 のとき floor(√x) <= x / 2 が常に成立 + let mut low: u32 = 1; + let mut high: u32 = x >> 1; // x / 2(ビットシフトで整数除算) + + // Loop Invariant: + // low - 1 の二乗は x 以下 + // high + 1 の二乗は x より大きい + // → ループ終了時: high = floor(√x) + while low <= high { + // オーバーフロー安全な中点計算 + // u32 同士の加算が u32::MAX を超える可能性があるため + // low + (high - low) / 2 パターンを採用 + let mid: u32 = low + (high - low) / 2; + + // mid * mid は最大 (2^31/2)^2 ≈ 1.15×10^18 → u64 が必要 + let square: u64 = (mid as u64) * (mid as u64); + let target: u64 = x as u64; + + match square.cmp(&target) { + // 完全平方数: mid が答えそのもの + std::cmp::Ordering::Equal => return mid as i32, + + // mid が小さすぎる: 下限を引き上げ + std::cmp::Ordering::Less => low = mid + 1, + + // mid が大きすぎる: 上限を引き下げ + std::cmp::Ordering::Greater => high = mid - 1, + } + } + + // ループ終了後、high = floor(√x) + // 例: x=8 → [low=1, high=4] + // mid=2 (4<8) → low=3 + // mid=3 (9>8) → high=2 + // low(3) > high(2) → 終了: return high=2 ✓ + high as i32 + } +} +``` + +--- + +# 5. アルゴリズム動作トレース + +``` +─── x = 4 ─────────────────────────────────────────────────── + early return なし(x >= 2) + 初期値: low=1, high=2 + + Iter 1: mid=1, square=1 < 4 → low=2 + Iter 2: mid=2, square=4 == 4 → return 2 ✓ + +─── x = 8 ─────────────────────────────────────────────────── + 初期値: low=1, high=4 + + Iter 1: mid=2, square=4 < 8 → low=3 + Iter 2: mid=3, square=9 > 8 → high=2 + low(3) > high(2) → return high=2 ✓ + +─── x = 2147395600 (46340²) ──────────────────────────────── + 完全平方数 → Equal 分岐で即 return 46340 + 最大でも約 30 回のイテレーションで収束 + +─── エッジケース ──────────────────────────────────────────── + x=0 → early return 0 + x=1 → early return 1 + x=2147483647 (i32::MAX) → return 46340 +``` + +--- + +## 6. Rust 固有の設計ポイント整理 + +| 観点 | 実装での対応 | +| ------------------------------ | ---------------------------------------------------------- | +| **オーバーフロー防止(中点)** | `low + (high - low) / 2` でラップアラウンドを回避 | +| **オーバーフロー防止(二乗)** | `mid as u64 * mid as u64` で `u64` に昇格してから乗算 | +| **符号安全変換** | `x as u32`(非負制約を `debug_assert!` で文書化) | +| **`match` + `Ordering`** | `if/else` より意図が明確・コンパイラの網羅性チェックが効く | +| **ゼロコスト抽象化** | 全変数 `Copy`・スタックのみ・ヒープアロケーション完全ゼロ | +| **`debug_assert!`** | リリースビルドで消滅するため実行時コストゼロ | diff --git a/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/Sqrt(x)_typescript.md b/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/Sqrt(x)_typescript.md new file mode 100644 index 00000000..300ecae6 --- /dev/null +++ b/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/Sqrt(x)_typescript.md @@ -0,0 +1,150 @@ +## 1. 問題の分析 + +## 競技プログラミング視点での分析 + +- `sqrt()` や `**` が使用禁止 → **数学的アルゴリズムで探索**が必要 +- 解の候補は `[0, x]` の整数空間 → **二分探索**が自然かつ最速 +- `mid * mid` のオーバーフロー対策: TypeScript の `number` は 64bit float なので `2^53` まで安全だが、**`Math.sqrt` 代替として BigInt 使用も選択肢** +- `x = 0` や `x = 1` などの **エッジケースを先行処理**することで無駄な探索を排除 + +## 業務開発視点での分析 + +- 入力は `non-negative integer` → 型レベルで `number` を受け取りつつ、**実行時の負数・小数ガード**が必要 +- LeetCode制約 `0 ≤ x ≤ 2³¹ - 1` → `2147483647` までの範囲、`number` で安全に扱える +- 関数は **Pure function**(副作用なし) / 同一入力 → 同一出力を保証 + +## TypeScript特有の考慮点 + +- `readonly` + strict mode により入力ミュータビリティを排除 +- `number` 型の精度限界(2^53)を意識した境界値設計 +- 型ガードで `NaN` / `Infinity` / 負数を**コンパイル時 + 実行時**の二段階で防止 + +--- + +## 2. アルゴリズムアプローチ比較 + +| アプローチ | 時間計算量 | 空間計算量 | TS実装コスト | 型安全性 | 可読性 | 備考 | +| ---------------- | ------------ | ---------- | ------------ | -------- | ------ | ------------------------------ | +| **線形探索** | O(√n) | O(1) | 低 | 高 | 高 | x=2³¹では~46000回、非効率 | +| **二分探索** | O(log n) | O(1) | 低 | 高 | 高 | ✅ 最もバランス優秀 | +| **ニュートン法** | O(log log n) | O(1) | 中 | 中 | 中 | 収束速いが浮動小数誤差リスク | +| **ビット操作** | O(log n) | O(1) | 高 | 中 | 低 | 最上位ビットから確定、可読性低 | + +--- + +## 3. 選択したアルゴリズムと理由 + +- **選択したアプローチ**: 二分探索(Binary Search) +- **理由**: + - O(log n) = 最大31回のイテレーションで確定(x ≤ 2³¹) + - ニュートン法と異なり **浮動小数点誤差が発生しない**(整数演算のみ) + - `low * low <= x` という不変条件が型安全に表現しやすく、**不変条件(Loop Invariant)の証明が容易** + - 境界条件が明確で **保守性・可読性が高い** + +- **TypeScript特有の最適化ポイント**: + - `low`・`high`・`mid` を `number` で統一し型推論に任せることで冗長な型注釈を排除 + - 戻り値 `number` を明示してコンパイラの戻り値型チェックを活用 + - `readonly` パラメータで入力の不変性を保証 + +--- + +## 4. 実装コード + +```typescript +// Runtime 0 ms +// Beats 100.00% +// Memory 57.54 MB +// Beats 78.43% + +/** + * 非負整数 x の平方根を小数点以下切り捨てで返す(二分探索) + * Math.sqrt / ** 演算子は使用禁止 + * + * @param x - 非負整数 (0 ≤ x ≤ 2^31 - 1) + * @returns floor(√x) + * @throws {TypeError} x が有限な非負整数でない場合 + * @throws {RangeError} x が 2^31 - 1 を超える場合 + * @complexity Time: O(log n), Space: O(1) + */ +function mySqrt(x: number): number { + // ── 型ガード(実行時) ───────────────────────────────────────── + if (!Number.isFinite(x) || x < 0 || !Number.isInteger(x)) { + throw new TypeError(`Input must be a non-negative integer. Received: ${x}`); + } + if (x > 2 ** 31 - 1) { + throw new RangeError(`Input exceeds 2^31 - 1. Received: ${x}`); + } + + // ── エッジケース早期リターン ──────────────────────────────────── + // x = 0 → 0, x = 1 → 1 + if (x < 2) return x; + + // ── 二分探索 ─────────────────────────────────────────────────── + // 探索範囲: [1, x/2] + // 根拠: x >= 2 のとき floor(√x) <= x/2 が常に成立 + let low: number = 1; + let high: number = x >> 1; // == Math.floor(x / 2), ビットシフトで整数除算 + + // Loop Invariant: + // (low - 1) * (low - 1) <= x (lowより小さい値の二乗はx以下) + // (high + 1) * (high + 1) > x (highより大きい値の二乗はxより大きい) + // → この不変条件により、ループ終了時に high = floor(√x) が保証される + while (low <= high) { + // オーバーフロー防止: (low + high) >>> 1 + const mid: number = (low + high) >>> 1; + const square: number = mid * mid; + + if (square === x) { + // ちょうど割り切れる完全平方数 + return mid; + } else if (square < x) { + // mid が小さすぎる → 下限を上げる + low = mid + 1; + } else { + // mid が大きすぎる → 上限を下げる + high = mid - 1; + } + } + + // ループ終了後、high = floor(√x) + // 例: x=8 → 初期 low=1, high=4 + // Iter1: mid=2, sq=4<8 → low=3 + // Iter2: mid=3, sq=9>8 → high=2 + // 終了: low(3) > high(2) → return high=2 ✓ + return high; +} +``` + +--- + +## 5. アルゴリズム動作トレース + +``` +─── x = 8 の場合 ─────────────────────────────────────── + 探索範囲初期値: low=1, high=4 (= 8>>1) + + Iter 1: mid = (1+4)>>>1 = 2, square = 4 < 8 → low = 3 + Iter 2: mid = (3+4)>>>1 = 3, square = 9 > 8 → high = 2 + 終了条件: low(3) > high(2) → return high = 2 ✓ + +─── x = 2147395600 (46340²) の場合 ───────────────────── + 最大でも 約30回のイテレーションで収束 (log₂(2³¹) ≈ 31) + +─── エッジケース ──────────────────────────────────────── + x = 0 → early return 0 + x = 1 → early return 1 + x = 4 → Iter: mid=1→2→2 (4==4) → return 2 ✓ +``` + +--- + +# 6. TypeScript 固有の最適化ポイント整理 + +| 観点 | 実装での対応 | +| ---------------------- | --------------------------------------------------------------- | +| **オーバーフロー防止** | `(low + high) >>> 1` でビット演算による安全な中点計算 | +| **整数除算** | `x >> 1` で `Math.floor(x/2)` を代替(JITに優しい) | +| **null安全** | `Number.isFinite` + `Number.isInteger` で `NaN/Infinity` を排除 | +| **型推論活用** | `mid`, `square` は型注釈なしでも `number` と推論される | +| **Loop Invariant** | コメントで不変条件を明示 → レビュー・保守性向上 | +| **Pure function** | 外部状態への依存なし・副作用なし | diff --git a/README.md b/README.md index f70b8189..e773d878 100644 --- a/README.md +++ b/README.md @@ -1,109 +1,82 @@ -# Algorithm-DataStructures-Math-SQL — リポジトリ概要 +# リポジトリ概要 -[![GitHub Stars](https://img.shields.io/github/stars/myoshi2891/Algorithm-DataStructures-Math-SQL?style=flat-square)](https://github.com/myoshi2891/Algorithm-DataStructures-Math-SQL/stargazers) -[![GitHub Forks](https://img.shields.io/github/forks/myoshi2891/Algorithm-DataStructures-Math-SQL?style=flat-square)](https://github.com/myoshi2891/Algorithm-DataStructures-Math-SQL/network/members) -![Languages](https://img.shields.io/badge/Languages-Python%20|%20TypeScript%20|%20JavaScript-blue?style=flat-square) -[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/myoshi2891/Algorithm-DataStructures-Math-SQL) +**関連ソースファイル**: `README.md` / `public/index.html` / `generate_index.py` / `update_index.sh` / `INDEX_MAINTENANCE.md` -> **関連ドキュメント**: [2×3×3 アーティファクト生成マトリクス](./2.1-the-233-artifact-generation-matrix) | [デュアル AI 実装哲学](./2.2-dual-ai-implementation-philosophy) | [3 層ドキュメントシステム](./2.3-three-tier-progressive-documentation-system) | [開発環境とツール](./3-development-environment-and-tooling) +Algorithm-DataStructures-Math-SQL リポジトリは、**決定論的・多言語・マルチ AI の問題解決ドキュメントシステム**を実装しています。LeetCode・HackerRank・AtCoder から収録した各競技プログラミング問題は、**2×3×3 の行列乗算**(2 AI 実装 × 3 プログラミング言語 × 3 ドキュメント層)によって正確に **18 個のアーティファクト**を生成します。 -このリポジトリは、**決定論的なマルチ言語・マルチ AI 問題解決ドキュメントシステム**を実装しています。LeetCode・HackerRank・AtCoder に掲載された各競技プログラミング問題に対し、**2×3×3 マトリクス乗算**(2 AI × 3 言語 × 3 ドキュメント層)によって正確に **18 個のアーティファクト**を生成します。 +このページでは、リポジトリの基本アーキテクチャ・ファイル構成パターン・ビルドインフラストラクチャを解説します。各サブシステムの詳細については以下を参照してください。 ---- - -## 📋 目次 - -- [目的とスコープ](#目的とスコープ) -- [リポジトリ構造:2×3×3×6 アーキテクチャ](#リポジトリ構造2336-アーキテクチャ) -- [デュアル AI 実装哲学](#デュアル-ai-実装哲学コードレベルの差別化) -- [3 層プログレッシブドキュメントシステム](#3-層プログレッシブドキュメントシステム) -- [ビルドと公開インフラ](#ビルドと公開インフラ) -- [技術スタックと依存関係管理](#技術スタックと依存関係管理) -- [ナビゲーションとファイル検索](#ナビゲーションとファイル検索) -- [リポジトリのメトリクスと規模](#リポジトリのメトリクスと規模) -- [ファイル命名規則とコード構造](#ファイル命名規則とコード構造) -- [クイックスタートガイド](#クイックスタートガイド) +- アーティファクト生成の仕組み → [The 2×3×3 Artifact Generation Matrix] +- AI 実装の違い → [Dual AI Implementation Philosophy] +- ドキュメント形式 → [Three-Tier Progressive Documentation System] +- 開発ツール → [Development Environment and Tooling] --- -## 目的とスコープ - -```mermaid -graph TD - PROB["競技プログラミング問題
LeetCode / HackerRank / AtCoder"] - - PROB --> AI["2 AI プロバイダー"] - AI --> C["Claude Sonnet 4.5"] - AI --> G["GPT 5.1 Thinking Customized"] - - C --> LANG_C["3 言語"] - G --> LANG_G["3 言語"] - - LANG_C --> PY_C["Python
.py"] - LANG_C --> TS_C["TypeScript
.ts"] - LANG_C --> JS_C["JavaScript
.js"] - - LANG_G --> PY_G["Python
_py.ipynb"] - LANG_G --> TS_G["TypeScript
_ts.ipynb"] - LANG_G --> JS_G["JavaScript
_js.ipynb"] - - PY_C & TS_C & JS_C & PY_G & TS_G & JS_G --> DOC["3 ドキュメント層 × 2 AI = 6 ファイル"] - DOC --> D1["README.md
静的マークダウン"] - DOC --> D2["README.html
インタラクティブ HTML"] - DOC --> D3["README_react.html
Dynamic React"] - - style PROB fill:#4A90D9,color:#fff - style DOC fill:#27AE60,color:#fff -``` - ---- - -## リポジトリ構造:2×3×3×6 アーキテクチャ +## リポジトリ構造: 2×3×3×6 アーキテクチャ ### 決定論的アーティファクト生成マトリクス -問題ごとに 3 つの乗算次元を通じて、厳密な **18 ファイル生成パターン**を強制します。 +リポジトリは、3 つの乗算次元によって問題ごとに厳密な **18 ファイル生成パターン**を強制しています。 ```mermaid -graph LR - subgraph MATRIX["2×3×3 マトリクス = 18 アーティファクト / 問題"] - AI_DIM["AI 次元 ×2
Claude / GPT"] - LANG_DIM["言語次元 ×3
Py / TS / JS"] - DOC_DIM["ドキュメント次元 ×3
md / html / react.html"] +graph TD + PROBLEM["🧩 競技プログラミング問題
(LeetCode / HackerRank / AtCoder)"] + + subgraph MATRIX["2×3×3 マトリクス = 18 アーティファクト"] + subgraph AI["🤖 AI プロバイダー(×2)"] + CLAUDE["Claude Sonnet 4.5
(競技特化・簡潔)"] + GPT["GPT 5.1 thinking customized
(本番対応・堅牢)"] + end + + subgraph LANG["💻 プログラミング言語(×3)"] + PY["Python
*.py / *_py.ipynb"] + TS["TypeScript
*.ts / *_ts.ipynb"] + JS["JavaScript
*.js / *_js.ipynb"] + end + + subgraph DOC["📄 ドキュメント層(×3)"] + MD["Tier 1: README.md
静的 Markdown"] + HTML["Tier 2: README.html
インタラクティブ HTML"] + REACT["Tier 3: README_react.html
動的 React"] + end end - AI_DIM --> LANG_DIM --> DOC_DIM + PROBLEM --> AI + AI --> LANG + LANG --> DOC ``` +**問題ごとのアーティファクト数: 18 ファイル(2 AI × 3 言語 × 3 ドキュメント)** + | 次元 | 数 | 例 | コードパターン | | ------------------- | --- | ---------------------------------------------------- | ------------------------------------- | -| **AI プロバイダー** | 2 | `claude sonnet 4.5/`、`gpt 5.1 thinking customized/` | レベル 5 のサブディレクトリ名 | +| **AI プロバイダー** | 2 | `claude sonnet 4.5/`、`gpt 5.1 thinking customized/` | Level 5 のサブディレクトリ名 | | **言語** | 3 | `*.py`、`*.ts`、`*.js` + Jupyter バリアント | ファイル拡張子 + Jupyter ノートブック | | **ドキュメント** | 3 | `README.md`、`README.html`、`README_react.html` | 固定ファイル名パターン | --- -### O(1) 参照のための 6 層ファイル階層 +### O(1) 検索を実現する 6 階層ファイル構造 -決定論的なパス構造により、検索なしに直接ファイルを特定できます。 +リポジトリは検索なしに直接ファイルを特定できる、**決定論的なパス構造**を採用しています。 ```mermaid -graph TD - L1["Level 1: ドメイン
Algorithm / DataStructures
Mathematics / SQL"] - L2["Level 2: アルゴリズム手法
DynamicProgramming / BinarySearch / Map"] - L3["Level 3: 問題ソース
leetcode / hackerrank / atcoder"] - L4["Level 4: 具体的な問題
97. Interleaving String"] - L5["Level 5: AI 実装
claude sonnet 4.5
gpt 5.1 thinking customized"] - L6["Level 6: ファイルアーティファクト
Interleaving_String.py
README.md etc."] +flowchart TD + subgraph HIERARCHY["📁 6 階層パス構造"] + L1["Level 1: Domain
Algorithm / DataStructures / Mathematics / SQL"] + L2["Level 2: Subcategory
DynamicProgramming / BinarySearch / Map"] + L3["Level 3: Platform
leetcode / hackerrank / atcoder"] + L4["Level 4: Problem
97. Interleaving String"] + L5["Level 5: AI
claude sonnet 4.5 / gpt 5.1 thinking customized"] + L6["Level 6: Artifact
Interleaving_String.py / README.md"] + end L1 --> L2 --> L3 --> L4 --> L5 --> L6 - style L1 fill:#E74C3C,color:#fff - style L2 fill:#E67E22,color:#fff - style L3 fill:#F1C40F,color:#000 - style L4 fill:#27AE60,color:#fff - style L5 fill:#2980B9,color:#fff - style L6 fill:#8E44AD,color:#fff + EXAMPLE["📌 具体例:
Algorithm/DynamicProgramming/leetcode/
97. Interleaving String/Claude Sonnet 4.5/
├── Interleaving_String.py
├── Interleaving_String.ts
├── Interleaving_String.js
├── README.md
├── README.html
└── README_react.html"] + + L6 -. "実例" .-> EXAMPLE ``` **パスパターン**: @@ -112,428 +85,358 @@ graph TD {Domain}/{Subcategory}/{Platform}/{Problem}/{AI}/{Artifact} ``` -**具体的なパス例**: - -``` -Algorithm/DynamicProgramming/leetcode/97. Interleaving String/Claude Sonnet 4.5/ -├── Interleaving_String.py -├── Interleaving_String.ts -├── Interleaving_String.js -├── README.md -├── README.html -└── README_react.html -``` - -| レベル | 目的 | 抽出方法 | 値の例 | -| ------ | ------------------------ | ---------- | --------------------------------------------------- | -| 1 | ドメイン分類 | `parts[0]` | `Algorithm`, `DataStructures`, `Mathematics`, `SQL` | -| 2 | アルゴリズム手法 | `parts[1]` | `DynamicProgramming`, `BinarySearch`, `Map` | -| 3 | 問題ソース | `parts[2]` | `leetcode`, `hackerrank`, `atcoder` | -| 4 | 具体的な問題 | `parts[3]` | `97. Interleaving String` | -| 5 | AI 実装 | `parts[4]` | `claude sonnet 4.5`, `gpt 5.1 thinking customized` | -| 6 | ファイルアーティファクト | ファイル名 | `Interleaving_String.py`, `README.md` | - -> **SQL ドメインの例外**: レベル 5 では単一の `gpt/` ディレクトリを使用し、レベル 6 でプラットフォーム固有のサフィックスを付与 - -``` -SQL/Leetcode/Basic select/1141. User Activity/gpt/ -├── User_Activity_*_mysql.ipynb # MySQL 8.0.40 -├── User_Activity_*_postgre.ipynb # PostgreSQL 16.6+ -└── User_Activity_*_pandas.ipynb # Pandas 2.2.2 -``` +| Level | 用途 | 抽出方法 | 値の例 | +| ----- | ------------------------ | ------------------------------------ | --------------------------------------------------- | +| 1 | ドメイン分類 | `parts[0]`(`os.path.split()` より) | `Algorithm`, `DataStructures`, `Mathematics`, `SQL` | +| 2 | アルゴリズム手法 | `parts[1]` | `DynamicProgramming`, `BinarySearch`, `Map` | +| 3 | 問題ソース | `parts[2]` | `leetcode`, `hackerrank`, `atcoder` | +| 4 | 具体的な問題 | `parts[3]` | `97. Interleaving String` | +| 5 | AI 実装 | `parts[4]` | `claude sonnet 4.5`, `gpt 5.1 thinking customized` | +| 6 | ファイルアーティファクト | ファイル名 | `Interleaving_String.py`, `README.md` | + +> **SQL ドメインの例外**: Level 5 に単一の `gpt/` ディレクトリを使用し、Level 6 でプラットフォーム固有のサフィックスを付与します。 +> +> ``` +> SQL/Leetcode/Basic select/1141. User Activity/gpt/ +> ├── User_Activity_*_mysql.ipynb # MySQL 8.0.40 +> ├── User_Activity_*_postgre.ipynb # PostgreSQL 16.6+ +> └── User_Activity_*_pandas.ipynb # Pandas 2.2.2 +> ``` --- -## デュアル AI 実装哲学:コードレベルの差別化 - -### 対照的な実装パターン +## デュアル AI 実装哲学: コードレベルの差別化 ```mermaid graph LR - subgraph CLAUDE["Claude Sonnet 4.5
競技プログラミング志向"] - C1["メソッド数: 1
(isInterleave のみ)"] - C2["型チェック: アノテーションを信頼"] - C3["制約検証: なし"] - C4["コード量: 50〜150 行"] - C5["実行時間: 44ms (60.43%)"] - C6["メモリ: 91.38 パーセンタイル"] + subgraph CLAUDE_BOX["🔵 Claude Sonnet 4.5
(競技プログラミング特化)"] + C1["✅ メソッド数: 1(isInterleave のみ)"] + C2["✅ 型チェック: アノテーションを信頼"] + C3["✅ 制約バリデーション: なし"] + C4["✅ コード行数: 50〜150 行"] + C5["✅ 実行時間(Python): 44ms(60.43%)"] + C6["✅ メモリ(Python): 91.38 パーセンタイル"] end - subgraph GPT["GPT 5.1 Thinking Customized
プロダクション志向"] - G1["メソッド数: 2+
(競技版 + プロダクション版)"] - G2["型チェック: isinstance() 実行時検証"] - G3["制約検証: 明示的な ValueError"] - G4["コード量: 80〜200 行"] - G5["実行時間: 42ms (70.90%)"] - G6["メモリ: 66.05 パーセンタイル"] + subgraph GPT_BOX["🟠 GPT 5.1 thinking customized
(本番環境対応)"] + G1["📦 メソッド数: 2+(競技版 + 本番版)"] + G2["📦 型チェック: isinstance() ランタイムチェック"] + G3["📦 制約バリデーション: 明示的な ValueError"] + G4["📦 コード行数: 80〜200 行"] + G5["📦 実行時間(Python): 42ms(70.90%)"] + G6["📦 メモリ(Python): 66.05 パーセンタイル"] end - PROB["同一問題"] --> CLAUDE - PROB --> GPT -``` - -### コード比較 - -**Claude パターン**(シンプル・直接実装): - -```python -class Solution: - def isInterleave(self, s1: str, s2: str, s3: str) -> bool: - # 型アノテーションを信頼 — バリデーションなし - n1, n2, n3 = len(s1), len(s2), len(s3) - if n1 + n2 != n3: - return False - # 単一メソッド、直接実装 + PROBLEM["🧩 同じ問題
(例: Interleaving String)"] + PROBLEM --> CLAUDE_BOX + PROBLEM --> GPT_BOX ``` -**GPT パターン**(バリデーション付き・プロダクション対応): - -```python -class Solution: - def isInterleave(self, s1: str, s2: str, s3: str) -> bool: - # 競技版(高速パス) - ... - - def isInterleave_production(self, s1: Any, s2: Any, s3: Any) -> bool: - # 実行時バリデーション - if not isinstance(s1, str): - raise TypeError("s1 must be str") - if len(s1) > 100: - raise ValueError("Exceeds constraint: len(s1) <= 100") - # 検証付きプロダクション版 -``` +### コードエンティティの比較 | 観点 | Claude 実装 | GPT 実装 | | ---------------------- | -------------------- | ----------------------------------------------- | -| **メソッド数** | 1(`isInterleave`) | 2+(`isInterleave`、`isInterleave_production`) | -| **型チェック** | アノテーションを信頼 | `isinstance()` 実行時チェック | -| **制約バリデーション** | なし | 明示的な `if len(s1) > 100: raise ValueError` | -| **コード長** | 50〜150 行 | 80〜200 行 | +| **メソッド数** | 1(`isInterleave`) | 2+(`isInterleave`, `isInterleave_production`) | +| **型チェック** | アノテーションを信頼 | `isinstance()` ランタイムチェック | +| **制約バリデーション** | なし | `if len(s1) > 100: raise ValueError` を明示 | +| **コード行数** | 50〜150 行 | 80〜200 行 | | **実行時間(Python)** | 44ms(60.43%) | 42ms(70.90%) | | **メモリ(Python)** | 91.38 パーセンタイル | 66.05 パーセンタイル | --- -## 3 層プログレッシブドキュメントシステム +## 3 段階プログレッシブドキュメントシステム + +各問題には、異なるスキルレベルを対象とした **3 段階のドキュメント**が提供されます。 ```mermaid -graph TD - subgraph TIER1["Tier 1: 静的マークダウン (README.md)
初学者向け"] - T1A["Section 1: 問題概要・制約・例"] - T1B["Section 2: アルゴリズム戦略・データ構造"] - T1C["Section 3: 時間 O(...) / 空間 O(...) 計算量"] - T1D["Section 4: コードウォークスルー"] - T1E["Section 5: 言語別最適化・パフォーマンスチューニング"] - T1A --> T1B --> T1C --> T1D --> T1E +flowchart LR + subgraph TIER1["📄 Tier 1: README.md
(静的 Markdown)"] + T1A["Section 1: overview
問題文・制約・例"] + T1B["Section 2: tldr
アルゴリズム戦略・データ構造"] + T1C["Section 3: complexity
時間 O(…) / 空間 O(…)"] + T1D["Section 4: impl
コードウォークスルー"] + T1E["Section 5: cpython
言語固有の最適化"] end - subgraph TIER2["Tier 2: インタラクティブ HTML (README.html)
中級者向け"] + subgraph TIER2["🖥️ Tier 2: README.html
(インタラクティブ HTML)"] T2A["Prism.js 1.29.0
構文ハイライト"] T2B["Tailwind CSS
スタイリング"] T2C["Play/Pause/Step
インタラクティブ制御"] - T2D["SVG フローチャート"] + T2D["SVG フローチャート
アルゴリズム可視化"] end - subgraph TIER3["Tier 3: Dynamic React (README_react.html)
上級者向け"] - T3A["React 18.3.1
リアルタイム実行"] + subgraph TIER3["⚛️ Tier 3: README_react.html
(動的 React)"] + T3A["React 18.3.1 + Babel 7.26.10
JSX ブラウザ実行"] T3B["useState
ライブ入力変更"] - T3C["useEffect
アルゴリズム再実行"] - T3D["AI 実装の
並列比較"] + T3C["useEffect
リアルタイム再実行"] + T3D["デュアル AI 比較
サイドバイサイド表示"] end - TIER1 -->|"スキルアップ"| TIER2 -->|"スキルアップ"| TIER3 + BEGINNER["🟢 入門者"] --> TIER1 + INTERMEDIATE["🟡 中級者"] --> TIER2 + ADVANCED["🔴 上級者"] --> TIER3 ``` -### Tier 1: 静的マークダウン(`README.md`) +### Tier 1: 静的 Markdown(`README.md`) **標準 5 セクション構成**: -| セクション ID | ヘッダー | コンテンツの目的 | -| ------------- | ---------------------- | -------------------------------------------- | -| 1 | `

` | 問題文・制約・例 | -| 2 | `

` | アルゴリズム戦略・データ構造・状態遷移 | -| 3 | `

` | 時間 O(...)・空間 O(...)・導出 | -| 4 | `

` | コードウォークスルー・行ごとの説明 | -| 5 | `

` | 言語固有の最適化・パフォーマンスチューニング | +| Section ID | ヘッダー | コンテンツの目的 | +| ---------- | ---------------------- | -------------------------------------------- | +| 1 | `

` | 問題文・制約・例 | +| 2 | `

` | アルゴリズム戦略・データ構造・状態遷移 | +| 3 | `

` | 時間 O(...)・空間 O(...)・導出 | +| 4 | `

` | コードウォークスルー・行ごとの解説 | +| 5 | `

` | 言語固有の最適化・パフォーマンスチューニング | ### Tier 2: インタラクティブ HTML(`README.html`) -**技術スタック**: - -- **構文ハイライト**: Prism.js 1.29.0(`/vendor/prismjs/prism.js`) -- **スタイリング**: Tailwind CSS(`/vendor/tailwindcss/script.js`) -- **インタラクティブ制御**: JavaScript 状態管理付きの Play/Pause/Step ボタン +**技術スタック**: Prism.js 1.29.0・Tailwind CSS・JavaScript 状態管理 **主な機能**: - ステップバイステップのアルゴリズム可視化 - SVG フローチャートレンダリング - 行番号付きコードブロックハイライト -- 外部 CDN 依存なし(すべてローカルにベンダリング) - -### Tier 3: Dynamic React(`README_react.html`) - -**技術スタック**: - -- **React**: 18.3.1(`/vendor/react/react.development.js`) -- **React DOM**: 18.3.1(`/vendor/react-dom/react-dom.development.js`) -- **Babel Standalone**: 7.26.10(`/vendor/babel/babel.min.js`) - -**React コンポーネントパターン**: - -```jsx - -``` +- 外部 CDN 依存なし(全てベンダーローカル化) + +### Tier 3: 動的 React(`README_react.html`) + +**技術スタック**: React 18.3.1・React DOM 18.3.1・Babel Standalone 7.26.10 **主な機能**: - `useState` によるライブ入力変更 - `useEffect` によるリアルタイムアルゴリズム再実行 -- AI 実装の並列比較 +- デュアル AI 実装のサイドバイサイド比較 - インタラクティブな可視化コンポーネント --- -## ビルドと公開インフラ +## ビルド・公開インフラストラクチャ ### インデックス生成パイプライン ```mermaid flowchart TD - START["./update_index.sh
起動"] --> PY["python3 generate_index.py"] + subgraph SOURCE["📁 ソースファイル群"] + ALGO["Algorithm/
(各問題の実装・ドキュメント)"] + DS["DataStructures/"] + MATH["Mathematics/"] + JS_DIR["JavaScript/"] + CONC["Concurrency/"] + SQL_DIR["SQL/"] + end - PY --> FUNC1["get_html_title()
タグを正規表現で抽出"] - PY --> FUNC2["copy_vendor_files()<br>node_modules → public/vendor へコピー"] - PY --> FUNC3["rewrite_html_content()<br>CDN URL をローカルパスに置換"] - PY --> FUNC4["generate_index()<br>メインオーケストレーション関数"] + subgraph SCRIPT["⚙️ generate_index.py"] + F1["get_html_title()<br><title> タグを正規表現で抽出"] + F2["copy_vendor_files()<br>node_modules → public/vendor にコピー"] + F3["rewrite_html_content()<br>CDN URL → ローカルパスに書き換え"] + F4["generate_index()<br>os.walk() でファイル走査<br>カテゴリ別 HTML 生成"] + end - FUNC2 --> VENDOR["Vendor ファイルマッピング"] - VENDOR --> V1["react/umd/*.js → /vendor/react/"] - VENDOR --> V2["react-dom/umd/*.js → /vendor/react-dom/"] - VENDOR --> V3["@babel/standalone → /vendor/babel/"] - VENDOR --> V4["prismjs → /vendor/prismjs/"] - VENDOR --> V5["fontawesome → /vendor/fontawesome/"] + subgraph OUTPUT["📄 出力"] + INDEX["public/index.html<br>(161 リンク・カテゴリタブ付き)"] + VENDOR["public/vendor/<br>(~5MB ベンダーファイル群)"] + end - FUNC3 --> REWRITE["URL 書き換えパターン"] - REWRITE --> R1["https://unpkg.com/react@18/...<br>→ /vendor/react/react.development.js"] - REWRITE --> R2["https://cdn.tailwindcss.com<br>→ /vendor/tailwindcss/script.js"] + SOURCE --> F4 + F4 --> F1 + F4 --> F2 + F4 --> F3 + F1 --> INDEX + F2 --> VENDOR + F3 --> INDEX +``` - FUNC4 --> INDEX["public/index.html 生成<br>152 問題リンク + カテゴリータブ"] +### `generate_index.py` の主要関数 - FUNC1 & FUNC2 & FUNC3 & FUNC4 --> INDEX +| 関数 | 行 | 目的 | コードエンティティ | +| ------------------------ | ------- | ------------------------------------------ | --------------------------------------- | +| `get_html_title()` | 11-17 | `<title>` タグを正規表現で抽出 | `re.search(r'<title>(.*?)')` | +| `copy_vendor_files()` | 19-77 | `node_modules` を `public/vendor` にコピー | `shutil.copy2()`, `shutil.copytree()` | +| `rewrite_html_content()` | 78-111 | CDN URL をローカルパスに置換 | 文字列置換マッピング | +| `generate_index()` | 113-617 | メインオーケストレーション関数 | `os.walk()`, `defaultdict()`, HTML 生成 | - style START fill:#E74C3C,color:#fff - style INDEX fill:#27AE60,color:#fff -``` +### ベンダーファイルマッピング -### `generate_index.py` の主要関数 +| ソース(node_modules) | 出力先(public/vendor) | 用途 | +| ----------------------------------------------- | -------------------------------------------- | -------------------------------- | +| `react/umd/react.development.js` | `/vendor/react/react.development.js` | React 18.3.1 UMD ビルド | +| `react-dom/umd/react-dom.development.js` | `/vendor/react-dom/react-dom.development.js` | React DOM 18.3.1 | +| `@babel/standalone/babel.min.js` | `/vendor/babel/babel.min.js` | Babel 7.26.10(JSX 変換) | +| `prismjs/prism.js` | `/vendor/prismjs/prism.js` | Prism.js 1.29.0 構文ハイライター | +| `@fortawesome/fontawesome-free/css/all.min.css` | `/vendor/fontawesome/css/all.min.css` | FontAwesome 6.7.2 アイコン | -| 関数 | 行 | 目的 | コードエンティティ | -| ------------------------ | ------- | -------------------------------------- | --------------------------------------- | -| `get_html_title()` | 11-17 | `` タグを正規表現で抽出 | `re.search(r'<title>(.*?)')` | -| `copy_vendor_files()` | 19-77 | node_modules を public/vendor にコピー | `shutil.copy2()`, `shutil.copytree()` | -| `rewrite_html_content()` | 78-111 | CDN URL をローカルパスに置換 | 文字列置換マッピング | -| `generate_index()` | 113-617 | メインオーケストレーション関数 | `os.walk()`, `defaultdict()`, HTML 生成 | +### 自動化スクリプト -### CI/CD パイプライン +**シェルラッパー**(`update_index.sh`): -```mermaid -flowchart LR - DEV["開発者
コード追加"] -->|git commit| HOOK["Pre-commit Hook
update_index.sh 自動実行"] - HOOK --> BUILD["generate_index.py
インデックス再生成"] - BUILD --> AUTO["git-auto-commit-action
生成ファイルを自動コミット"] - AUTO -->|push/PR| GA["GitHub Actions
ビルド・検証"] - GA --> DEPLOY["public/index.html
公開サイト更新"] - - style DEV fill:#3498DB,color:#fff - style DEPLOY fill:#27AE60,color:#fff +```bash +#!/bin/bash +set -euo pipefail +cd "$(dirname "$0")" +python3 generate_index.py ``` +**CI/CD 連携**(Git フック): + +- **Pre-commit フック**: コミット前に `update_index.sh` を自動実行 +- **GitHub Actions**: Push / PR イベントでビルドをトリガー +- **自動コミット**: `git-auto-commit-action` で生成ファイルをコミット + --- ## 技術スタックと依存関係管理 ### コアランタイム環境 -| コンポーネント | バージョン | 設定ファイル | 目的 | +| コンポーネント | バージョン | 設定ファイル | 用途 | | -------------- | -------------------- | ----------------- | ------------------------------------ | | **Python** | CPython 3.12.11 | `.python-version` | アルゴリズム実装・ビルドスクリプト | -| **Node.js** | v22.14.0 | `package.json` | TypeScript/JavaScript ランタイム | +| **Node.js** | v22.14.0 | `package.json` | TypeScript / JavaScript ランタイム | | **TypeScript** | 5.9.3 | `package.json` | 型安全な実装 | | **Bun** | 1.3.5(Lockfile v1) | `bun.lock` | パッケージマネージャー(npm の代替) | -### フロントエンド依存関係(ベンダリング済み) +### フロントエンド依存関係(ベンダーローカル化済み) -```mermaid -graph LR - subgraph VENDOR["public/vendor/ (~5MB)"] - R["React 18.3.1
react.development.js"] - RD["React DOM 18.3.1
react-dom.development.js"] - B["Babel 7.26.10
babel.min.js"] - P["Prism.js 1.29.0
prism.js + plugins"] - T["Tailwind CSS
standalone"] - FA["FontAwesome 6.7.2
CSS + webfonts"] - end -``` +| パッケージ | バージョン | 用途 | +| ---------------- | -------------- | ---------------------------------- | +| React | 18.3.1 | React Tier 3 ドキュメント用 UI | +| React DOM | 18.3.1 | DOM レンダラー | +| Babel Standalone | 7.26.10 | ブラウザ上での JSX トランスパイル | +| Prism.js | 1.29.0 | Tier 2 HTML のコード構文ハイライト | +| Tailwind CSS | スタンドアロン | Tier 2 HTML のスタイリング | +| FontAwesome | 6.7.2 | アイコン | ### SQL ドメインの依存関係(例外) -| ライブラリ | バージョン | 設定 | 目的 | -| -------------- | ---------- | ----------------------- | ------------------------------- | -| **Pandas** | 2.2.2 | `requirements.lock.txt` | SQL 問題の代替 DataFrame 操作 | -| **NumPy** | 2.3.4 | `requirements.lock.txt` | Pandas ソリューションの数値演算 | -| **SQLAlchemy** | Latest | `requirements.lock.txt` | データベース対話レイヤー | +SQL 問題のみ、外部 Python ライブラリを使用します。 + +| ライブラリ | バージョン | 設定 | 用途 | +| -------------- | ---------- | ----------------------- | --------------------------------- | +| **Pandas** | 2.2.2 | `requirements.lock.txt` | SQL 問題代替の DataFrame 操作 | +| **NumPy** | 2.3.4 | `requirements.lock.txt` | Pandas ソリューションでの数値演算 | +| **SQLAlchemy** | Latest | `requirements.lock.txt` | データベースインタラクション層 | ### コード品質ツール -| ツール | バージョン | 設定 | 目的 | -| ---------------- | ---------- | -------------------- | -------------------------------- | -| **Prettier** | 3.4.2 | `package.json` | コードフォーマット(JS/TS) | -| **ESLint** | 9.18.0 | `package.json` | リンティング(JS/TS) | -| **Ruff** | Latest | Python config | Python リンティング/フォーマット | -| **Markdownlint** | N/A | `.markdownlint.json` | Markdown バリデーション | - -**Markdownlint 設定** (`.markdownlint.json`): - -```json -{ - "MD013": { - "line_length": 1000, - "code_blocks": false - }, - "MD033": { - "allowed_elements": ["h1", "h2", "p", "i", "footer", "br", "div"] - } -} -``` +| ツール | バージョン | 設定 | 用途 | +| ---------------- | ---------- | -------------------- | ---------------------------- | +| **Prettier** | 3.4.2 | `package.json` | コードフォーマット(JS/TS) | +| **ESLint** | 9.18.0 | `package.json` | リンター(JS/TS) | +| **Ruff** | Latest | Python 設定 | Python リント / フォーマット | +| **Markdownlint** | N/A | `.markdownlint.json` | Markdown バリデーション | --- ## ナビゲーションとファイル検索 -### カテゴリーベースのナビゲーション +### カテゴリベースのナビゲーション -生成された `public/index.html` は、カテゴリーフィルタリング付きのタブインターフェースを実装しています。 +生成された `public/index.html` は、カテゴリフィルタリング付きのタブインターフェースを実装しています。 ```mermaid -graph TD - INDEX["public/index.html
メインナビゲーション"] +flowchart TD + INDEX["🌐 public/index.html
(161 インタラクティブレッスン)"] + + subgraph TABS["📑 カテゴリタブ"] + T_ALL["🌍 All
(152)"] + T_ALGO["🧩 Algorithm
(84)"] + T_DS["📚 DataStructures
(35)"] + T_MATH["📐 Mathematics
(16)"] + T_JS["📜 JavaScript
(14)"] + T_CONC["🔄 Concurrency
(6)"] + T_SQL["🗄️ SQL
(6)"] + end - INDEX --> TAB_ALL["🌍 All
(152 問題)"] - INDEX --> TAB_ALGO["🧩 Algorithm
(84 問題)"] - INDEX --> TAB_DS["🏗 DataStructures
(35 問題)"] - INDEX --> TAB_MATH["📐 Mathematics
(13 問題)"] - INDEX --> TAB_JS["⚡ JavaScript
(11 問題)"] - INDEX --> TAB_CC["🔄 Concurrency
(6 問題)"] - INDEX --> TAB_SQL["🗄 SQL
(3 問題)"] + subgraph CARDS["🃏 問題カード(カテゴリ別スタイル)"] + CARD["<li class='file-item' data-category='algorithm'>
カードタイトル
ファイルパス"] + end - TAB_ALGO --> CARD["問題カード
├── カードタイトル
└── ファイルパス"] + INDEX --> TABS + TABS --> CARDS + + BUILD["⚙️ generate_index.py
parts[0] = category(第 1 パス要素)"] + BUILD --> INDEX +``` + +**カテゴリ抽出ロジック**(`generate_index.py:163-168`): + +```python +parts = rel_path.split(os.sep) +if len(parts) > 1: + category = parts[0] # 第 1 パス要素 = ドメイン +else: + category = "Uncategorized" ``` --- -## リポジトリのメトリクスと規模 +## リポジトリのメトリクスとスケール ### 問題ドメイン分布 ```mermaid -pie title 問題ドメイン分布(全 152 問題) - "Algorithm (84問)" : 84 - "DataStructures (35問)" : 35 - "Mathematics (13問)" : 13 - "JavaScript (11問)" : 11 - "Concurrency (6問)" : 6 - "SQL (3問)" : 3 +pie title 問題ドメイン分布(全 161 問題) + "Algorithm(84)" : 84 + "DataStructures(35)" : 35 + "Mathematics(16)" : 16 + "JavaScript(14)" : 14 + "Concurrency(6)" : 6 + "SQL(6)" : 6 ``` | ドメイン | 問題数 | ファイル数(18×N) | 割合 | | ------------------ | ------- | ------------------ | ----- | -| **Algorithm** | 84 | 1,512 | 55.3% | -| **DataStructures** | 35 | 630 | 23.0% | -| **Mathematics** | 13 | 234 | 8.6% | -| **JavaScript** | 11 | 198 | 7.2% | -| **Concurrency** | 6 | 108 | 3.9% | -| **SQL** | 3 | 54 | 2.0% | -| **合計** | **152** | **2,736** | 100% | +| **Algorithm** | 84 | 1,512 | 52.2% | +| **DataStructures** | 35 | 630 | 21.7% | +| **Mathematics** | 16 | 288 | 9.9% | +| **JavaScript** | 14 | 252 | 8.7% | +| **Concurrency** | 6 | 108 | 3.7% | +| **SQL** | 6 | 108 | 3.7% | +| **合計** | **161** | **2,898** | 100% | ### 問題ごとのファイルタイプ内訳 -| ファイルタイプ | 数 | 目的 | 命名パターン | -| --------------------- | ------ | -------------------------------- | -------------------- | -| Python 実装 | 2 | `class Solution`(アルゴリズム) | `*.py`、`*_py.ipynb` | -| TypeScript 実装 | 2 | 型安全な関数実装 | `*.ts`、`*_ts.ipynb` | -| JavaScript 実装 | 2 | CommonJS `module.exports` | `*.js`、`*_js.ipynb` | -| 静的ドキュメント | 2 | 5 セクションの Markdown | `README.md` | -| インタラクティブ HTML | 2 | Prism.js + Tailwind | `README.html` | -| React 可視化 | 2 | React 18 + Babel | `README_react.html` | -| **問題ごとの合計** | **18** | 完全な学習アーティファクトセット | - | +| ファイルタイプ | 数 | 用途 | 命名パターン | +| --------------------- | ------ | --------------------------------- | -------------------- | +| Python 実装 | 2 | アルゴリズム付き `class Solution` | `*.py`, `*_py.ipynb` | +| TypeScript 実装 | 2 | 型安全な関数実装 | `*.ts`, `*_ts.ipynb` | +| JavaScript 実装 | 2 | CommonJS `module.exports` | `*.js`, `*_js.ipynb` | +| 静的ドキュメント | 2 | 5 セクション Markdown | `README.md` | +| インタラクティブ HTML | 2 | Prism.js + Tailwind | `README.html` | +| React 可視化 | 2 | React 18 + Babel | `README_react.html` | +| **1 問題あたり合計** | **18** | 完全な学習アーティファクトセット | — | -### 生成サイト構造 +### 生成サイトの構成 ``` public/ -├── index.html # メインナビゲーション(152 リンク、カテゴリータブ) -├── vendor/ # ベンダリング済み依存関係(合計 ~5MB) -│ ├── react/ # React 18.3.1 UMD -│ ├── react-dom/ # React DOM 18.3.1 -│ ├── babel/ # Babel Standalone 7.26.10 -│ ├── prismjs/ # Prism.js 1.29.0 + プラグイン -│ ├── tailwindcss/ # Tailwind CSS スタンドアロン -│ └── fontawesome/ # FontAwesome 6.7.2 + webfonts -├── Algorithm/ # 84 問題 × 18 ファイル = 1,512 ファイル -├── DataStructures/ # 35 問題 × 18 ファイル = 630 ファイル -├── Mathematics/ # 13 問題 × 18 ファイル = 234 ファイル -├── JavaScript/ # 11 問題 × 18 ファイル = 198 ファイル -├── Concurrency/ # 6 問題 × 18 ファイル = 108 ファイル -└── SQL/ # 3 問題 × 18 ファイル = 54 ファイル +├── index.html # メインナビゲーション(161 リンク・カテゴリタブ) +├── vendor/ # ベンダー依存関係(合計約 5MB) +│ ├── react/ # React 18.3.1 UMD +│ ├── react-dom/ # React DOM 18.3.1 +│ ├── babel/ # Babel Standalone 7.26.10 +│ ├── prismjs/ # Prism.js 1.29.0 + プラグイン +│ ├── tailwindcss/ # Tailwind CSS スタンドアロン +│ └── fontawesome/ # FontAwesome 6.7.2 + Web フォント +├── Algorithm/ # 84 問題 × 18 ファイル = 1,512 ファイル +├── DataStructures/ # 35 問題 × 18 ファイル = 630 ファイル +├── Mathematics/ # 16 問題 × 18 ファイル = 288 ファイル +├── JavaScript/ # 14 問題 × 18 ファイル = 252 ファイル +├── Concurrency/ # 6 問題 × 18 ファイル = 108 ファイル +└── SQL/ # 6 問題 × 18 ファイル = 108 ファイル ``` --- -## ファイル命名規則とコード構造 +## ファイル命名規則とコード構成 -### 言語固有のパターン +### 言語別パターン -```mermaid -graph LR - subgraph CLAUDE_FILES["Claude Sonnet 4.5 ファイル"] - CF1["Problem.py
class Solution"] - CF2["Problem.ts
function solution()"] - CF3["Problem.js
module.exports"] - CF4["README.md"] - CF5["README.html"] - CF6["README_react.html"] - end - - subgraph GPT_FILES["GPT 5.1 Thinking ファイル(Jupyter)"] - GF1["Problem_py.ipynb
4 セルのノートブック"] - GF2["Problem_ts.ipynb"] - GF3["Problem_js.ipynb"] - GF4["README.md"] - GF5["README.html"] - GF6["README_react.html"] - end -``` - -**Python**: +**Python**(Claude 実装): ```python class Solution: @@ -541,10 +444,10 @@ class Solution: """ Docstring with Time/Space complexity """ - # Implementation + # 実装 ``` -**TypeScript**: +**TypeScript**(GPT 実装): ```typescript function isInterleave(s1: string, s2: string, s3: string): boolean { @@ -556,21 +459,19 @@ function isInterleave(s1: string, s2: string, s3: string): boolean { ```javascript var isInterleave = function (s1, s2, s3) { - // Implementation + // 実装 }; module.exports = { isInterleave }; ``` -### Jupyter ノートブックの構造 - -GPT 実装は以下のセル構造の Jupyter ノートブックを使用します: +### Jupyter ノートブック構成(GPT 実装) ```mermaid flowchart TD - CELL1["セル 1: 問題分析
(Markdown)
問題文・制約・例の分析"] - CELL2["セル 2: 競技版コード
(Python/TS/JS)
高速パス実装"] - CELL3["セル 3: プロダクション版コード
(バリデーション付き)
isinstance() チェック・ValueError"] - CELL4["セル 4: 最適化ディスカッション
(Markdown)
トレードオフ・改善案"] + CELL1["📝 Cell 1: 問題分析
(Markdown)
問題文・制約・アプローチ"] + CELL2["⚡ Cell 2: 競技コード
(Python / TS / JS)
高速・シンプルな実装"] + CELL3["🏭 Cell 3: 本番コード
(バリデーション付き)
isinistance() / ValueError"] + CELL4["🔍 Cell 4: 最適化考察
(Markdown)
パフォーマンス分析"] CELL1 --> CELL2 --> CELL3 --> CELL4 ``` @@ -582,24 +483,24 @@ flowchart TD ### クローンとセットアップ ```bash -# 1. リポジトリをクローン +# 1. リポジトリのクローン git clone https://github.com/myoshi2891/Algorithm-DataStructures-Math-SQL.git cd Algorithm-DataStructures-Math-SQL -# 2. 依存関係をインストール(Bun を使用) +# 2. 依存関係のインストール(Bun を使用) bun install -# 3. 公開サイトを生成 +# 3. 公開サイトの生成 ./update_index.sh -# 4. ローカルで配信 +# 4. ローカルサーバーで確認 bun run serve -# http://127.0.0.1:8080 で開く +# http://127.0.0.1:8080 を開く ``` ### 新しい問題の追加 -新しい問題を追加する際は、2×3×3 マトリクス構造を必ず守ってください: +新しい問題を追加する際は、**2×3×3 マトリクス構造**を確保してください。 ``` {Domain}/{Subcategory}/{Platform}/{Problem}/ @@ -619,14 +520,8 @@ bun run serve └── README_react.html ``` -ファイルを追加後、`./update_index.sh` を実行して `public/index.html` を再生成してください。 +ファイルの追加後、`./update_index.sh` を実行して `public/index.html` を再生成してください。 --- -> このリポジトリは、自動ビルドプロセスと厳密なファイル組織パターンを持つ、マルチ言語アルゴリズムドキュメントのための**決定論的・スケーラブルなアーキテクチャ**を実装しており、O(1) ファイル参照と体系的な知識ナビゲーションを実現しています。 - -**⭐ このプロジェクトが役立ちましたら、ぜひスターを付けてください!** - -[![Made with ❤️ by myoshi2891](https://img.shields.io/badge/Made%20with%20❤️%20by-myoshi2891-red?style=flat-square)](https://github.com/myoshi2891) - -> このリポジトリは、自動ビルドプロセスと厳密なファイル組織パターンを持つ、マルチ言語アルゴリズムドキュメントのための**決定論的・スケーラブルなアーキテクチャ**を実装しており、O(1) ファイル参照と体系的な知識ナビゲーションを実現しています。 +このリポジトリは、自動化されたビルドプロセスと厳密なファイル構成パターンによって **O(1) ファイル検索**と体系的な知識ナビゲーションを実現する、決定論的でスケーラブルな多言語アルゴリズムドキュメントアーキテクチャを実装しています。 diff --git a/public/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/README_react.html b/public/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/README_react.html new file mode 100644 index 00000000..25271310 --- /dev/null +++ b/public/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/README_react.html @@ -0,0 +1,1279 @@ + + + + + + LeetCode 69 - Sqrt(x) | 二分探索 + + + + + + + + + + + + + + + + + + + +
+ + + + +
+

+ アルゴリズム概要 +

+
+
+
+ O(log n) +
+
時間計算量
+
+
+
O(1)
+
空間計算量
+
+
+
+ ≤ 31回 +
+
最大反復数
+
+
+
+ 整数演算 +
+
浮動小数誤差ゼロ
+
+
+ +
+
+

問題文

+

+ 非負整数 + x を受け取り、 + floor(√x)(小数点以下切り捨て)を返す。
+ math.sqrt**・ + pow(x, 0.5) + などの組み込み指数演算は使用禁止。 +

+
+
+

制約

+
    +
  • + ✅ + 0 ≤ x ≤ 2³¹ - 1(非負整数) +
  • +
  • + 🚫 + math.sqrt + 禁止 +
  • +
  • + 🚫 + ** + 演算子 禁止 +
  • +
  • + 🚫 + pow(x, 0.5) + 禁止 +
  • +
+
+
+ +
+

入出力例

+
+
+
EXAMPLE 1
+
+ Input: x = 4 +
+
+ Output: 2 +
+
+ √4 = 2.0 → 2(完全平方数) +
+
+
+
EXAMPLE 2
+
+ Input: x = 8 +
+
+ Output: 2 +
+
√8 ≈ 2.828 → 切り捨て 2
+
+
+
+
+ + +
+

+ ステップバイステップ解説 +

+
+
+ + +
+

+ コード実装 +

+ + +
+ + + +
+ +
+
class Solution:
+    def mySqrt(self, x: int) -> int:
+        # エッジケース: x=0, x=1 は即リターン
+        if x < 2:
+            return x
+
+        # 探索範囲: [1, x // 2]
+        # 根拠: x >= 2 のとき floor(√x) <= x // 2 が常に成立
+        low: int = 1
+        high: int = x >> 1  # ビットシフトで x // 2(CPython 最速)
+
+        # Loop Invariant:
+        #   (low - 1)^2 <= x  かつ  (high + 1)^2 > x
+        # → ループ終了時: high = floor(√x)
+        while low <= high:
+            mid: int = (low + high) >> 1  # 中点計算
+            sq:  int = mid * mid          # Python int は任意精度 → オーバーフローなし
+
+            if sq == x:
+                return mid       # 完全平方数: 即リターン
+            elif sq < x:
+                low = mid + 1    # mid が小さすぎる → 下限を引き上げ
+            else:
+                high = mid - 1   # mid が大きすぎる → 上限を引き下げ
+
+        # ループ終了後: high = floor(√x)
+        return high
+
+ + + + +
+ + +
+

+ 処理フローチャート +

+
+
+graph TD
+    Start["開始: mySqrt(x)"]
+    CheckEdge{"x < 2?"}
+    ReturnX["return x"]
+    Init["初期化: low=1, high=x/2"]
+    LoopCheck{"low <= high?"}
+    ReturnHigh["return high"]
+    CalcMid["中点計算
mid=(low+high)/2"] + Compare{"sq vs x"} + ReturnMid["return mid"] + UpdateLow["low=mid+1"] + UpdateHigh["high=mid-1"] + End["終了"] + + Start --> CheckEdge + CheckEdge -->|Yes| ReturnX + CheckEdge -->|No| Init + Init --> LoopCheck + LoopCheck -->|No| ReturnHigh + LoopCheck -->|Yes| CalcMid + CalcMid --> Compare + Compare -->|Equal| ReturnMid + Compare -->|Less| UpdateLow + Compare -->|Greater| UpdateHigh + UpdateLow --> LoopCheck + UpdateHigh --> LoopCheck + ReturnX --> End + ReturnMid --> End + ReturnHigh --> End + + style Start fill:#d1fae5,stroke:#10b981,stroke-width:3px + style End fill:#d1fae5,stroke:#10b981,stroke-width:3px + style CheckEdge fill:#fef3c7,stroke:#f59e0b,stroke-width:2px + style LoopCheck fill:#fef3c7,stroke:#f59e0b,stroke-width:2px + style Compare fill:#fef3c7,stroke:#f59e0b,stroke-width:2px + style ReturnX fill:#d1fae5,stroke:#059669,stroke-width:2px + style ReturnMid fill:#d1fae5,stroke:#059669,stroke-width:2px + style ReturnHigh fill:#d1fae5,stroke:#059669,stroke-width:2px + style Init fill:#e0f2fe,stroke:#0284c7,stroke-width:2px + style CalcMid fill:#e0f2fe,stroke:#0284c7,stroke-width:2px + style UpdateLow fill:#e0f2fe,stroke:#0284c7,stroke-width:2px + style UpdateHigh fill:#fee2e2,stroke:#dc2626,stroke-width:2px +
+
+

+ フローの説明:
+ 1. エッジケース判定: x < 2 の場合は x をそのまま返す(0→0, + 1→1)
+ 2. 探索範囲初期化: low=1, + high=x>>1(x/2)で探索上限を半分に削減
+ 3. 二分探索ループ: low>high になるまで + mid=(low+high)>>1 を計算
+ 4. 三方比較: sq==x(即リターン)/ sq<x(low引き上げ)/ + sq>x(high引き下げ)
+ 5. ループ終了: high = floor(√x) が確定 → return high
+ ── 紫の破線: + ループバック(探索範囲を狭めて次のイテレーションへ) +

+
+ + +
+

+ 計算量分析 +

+ +
+
+
O(log n)
+
時間計算量
+
+ x ≤ 2³¹ で最大 + 31 回のイテレーション
探索範囲が毎ステップ半減する +
+
+
+
O(1)
+
空間計算量
+
+ low / high / mid / sq の
スカラー変数のみ。ヒープ確保ゼロ +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ アプローチ + + 時間 + + 空間 + + 誤差 + + 保守性 + + 選択 +
線形探索 + O(√n) + + O(1) + + なし + ★★★ + ✗ 遅い +
+ 二分探索 ✅ + + O(log n) + + O(1) + + なし + + ★★★ + + ✅ 最適 +
ニュートン法 + O(log log n) + + O(1) + + float誤差 + ★★☆ + △ 誤差リスク +
math.isqrt() + O(log n) + + O(1) + + なし + ★★★ + 🚫 禁止 +
+
+ +
+

+ Loop Invariant(ループ不変条件) +

+
+
// ループの各反復前に成立:
+
+ (low - 1)² ≤ x + ← low より小さい値の二乗は x 以下 +
+
+ (high + 1)² > x + ← high より大きい値の二乗は x より大きい +
+
+ // → ループ終了時: high = floor(√x) が数学的に保証される +
+
+
+
+
+ + + + + + + + + + + + diff --git a/public/index.html b/public/index.html index 964ef93f..8d42b72c 100644 --- a/public/index.html +++ b/public/index.html @@ -416,7 +416,7 @@

🧪 Algorithm Study Index

-

161 interactive lessons across 6 domains

+

162 interactive lessons across 6 domains

@@ -431,9 +431,9 @@

- + @@ -468,6 +468,7 @@

  • 🧩LeetCode 5: Longest Palindromic Substring - 中心展開法Algorithm/ExpandAroundCenter/leetcode/5. Longest Palindromic Substring/Claude/README.html
  • 🧩LeetCode 66: Plus One - 右から左への繰り上がり処理Algorithm/Other/leetcode/66. Plus One/Claude Sonnet 4.5/README_react.html
  • 🧩LeetCode 67: Add Binary - 二進数加算Algorithm/TwoPointers/leetcode/67. Add Binary/Claude/README_react.html
  • +
  • 🧩LeetCode 69 - Sqrt(x) | 二分探索Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/README_react.html
  • 🧩LeetCode 6: Zigzag Conversion - 周期式による行別直接抽出Algorithm/Other/leetcode/6. Zigzag Conversion/Claude/README.html
  • 🧩LeetCode 7: Reverse Integer - 文字列反転法Algorithm/Other/leetcode/7. Reverse Integer/claude/README.html
  • 🧩LeetCode 93: Restore IP Addresses - DFS + 枝刈り解説Algorithm/Backtracking/leetcode/93. Restore IP Addresses/Claude/README.html
  • @@ -636,6 +637,7 @@

  • 🧩LeetCode 5: Longest Palindromic Substring - 中心展開法Algorithm/ExpandAroundCenter/leetcode/5. Longest Palindromic Substring/Claude/README.html
  • 🧩LeetCode 66: Plus One - 右から左への繰り上がり処理Algorithm/Other/leetcode/66. Plus One/Claude Sonnet 4.5/README_react.html
  • 🧩LeetCode 67: Add Binary - 二進数加算Algorithm/TwoPointers/leetcode/67. Add Binary/Claude/README_react.html
  • +
  • 🧩LeetCode 69 - Sqrt(x) | 二分探索Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/README_react.html
  • 🧩LeetCode 6: Zigzag Conversion - 周期式による行別直接抽出Algorithm/Other/leetcode/6. Zigzag Conversion/Claude/README.html
  • 🧩LeetCode 7: Reverse Integer - 文字列反転法Algorithm/Other/leetcode/7. Reverse Integer/claude/README.html
  • 🧩LeetCode 93: Restore IP Addresses - DFS + 枝刈り解説Algorithm/Backtracking/leetcode/93. Restore IP Addresses/Claude/README.html
  • @@ -805,7 +807,7 @@

    🧪 - Generated on 2026-03-04 + Generated on 2026-03-08