# 记录（填好的样子）· 0033 综合实战：拨钟问题

> 这一份是**流水线跑出来的记录**（`record_example.md`），照着它填自己的 `record.md`。
> 它是参考解在 `tools.CANON_TEXT` / `tools.canon_cases()` 上跑出来的样子：
> 五组数据、过了 4 组、第 4 组是故意对不上的那一组。
>
> 注意它**没有**「通过」两个字就完事：数据本身、每组的通过情况、第一个反例都在。

## 这一次跑了什么

| 那一格 | 这一次填什么 |
| --- | --- |
| 题目 | 「拨钟问题」：9 个钟排成 3×3，每个按钮按一次拨动一组钟，求全拨到 12 点的最少按键次数 |
| 选定的算法族 | 图的搜索（候选里还有「枚举」：它也能出正确答案，但代价更大，所以第二段挑了搜索） |
| 结论 | **未过**（五组里第 4 组没对上） |
| 跑法 | 对拍：拿固定的五组数据跑第 3 段的解法，跟期望输出逐组比 |
| 数据在哪儿 | **就是下面这两张表**（不是「见 seed」） |
| seed | 20260301 |
| 怎么重跑 | `py pipeline.py`：五段会用同一份数据重跑一遍，记录应当与这里逐字相同 |

## 用到的测试数据本身

| 组号 | 输入（题目原文那三行） | 期望输出 |
| --- | --- | --- |
| 0 | `0 0 0 / 0 0 0 / 0 0 0` | `0` |
| 1 | `0 0 1 / 0 0 1 / 0 0 1` | `1` |
| 2 | `0 1 2 / 3 0 1 / 2 3 0` | `8` |
| 3 | `1 2 3 / 0 1 2 / 3 0 1` | `13` |
| 4 | `2 1 0 / 3 2 1 / 0 3 2` | `4` ← **这一组的期望值是故意写错的** |

期望值那一列是 `tools.canon_exec` **现算**出来的（它枚举每个按钮按 0..3 次的全部
4^9 种组合，取总次数最小的那一个），不是照着解法的输出填的——
照着自己的输出填期望值，那一栏就永远等于「通过」，也就永远验不出东西。

## 每一组跑出来什么

| 组号 | 算出来 | 期望 | 过没过 |
| --- | --- | --- | --- |
| 0 | `0` | `0` | 过 |
| 1 | `1` | `1` | 过 |
| 2 | `8` | `8` | 过 |
| 3 | `13` | `13` | 过 |
| 4 | `18` | `4` | **没过** |

五组里过了 4 组。第 4 组那一行是**故意留在数据里的**：让「不合格时的第一个反例」
这一格有东西可写，而不是让整份记录变成一句「通过」。

## 不合格时的第一个反例

```
第 4 组: 2 1 0 3 2 1 0 3 2 算出来 18 / 期望 4
```

四样都留下来了：**组号（4）、数据（那三行原文）、算出来的（18）、期望的（4）**。
少了任何一样，这条反例就没法复现——「第 4 组没过」不是证据。

## 结论

- 这份记录里的 passed 是 **False**：五组里第 4 组没对上。
- 报告里那一行是 **「验证 未过」**，与验证那一段的结论是**同一个**（不是重新猜一遍）。
- 这一条结论可以直接重放：数据在上面的表里，命令是 `py pipeline.py`。
- 还没弄明白的：把「拨到 12 点」写成按钮次数之后，为什么每组的答案都落在 0..27 之间
  ——见 `answer.md` 里「我不放心的地方」那一条。
