From 716747cdef9eb525657f760719bb5501cfe9e542 Mon Sep 17 00:00:00 2001 From: yhcedpn <261370596+yhcedpn@users.noreply.github.com> Date: Sun, 14 Jun 2026 02:09:51 -0700 Subject: [PATCH 1/2] =?UTF-8?q?docs:=20=E9=87=8D=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E8=A7=84=E8=8C=83=E6=96=87=E4=BB=B6=E5=B9=B6=E8=A1=A5=E5=85=85?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E8=81=8C=E8=B4=A3=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 9 +- ...00\345\217\221\350\247\204\350\214\203.md" | 89 +++++++++++++++++++ ...00\345\217\221\350\247\204\350\214\203.md" | 70 --------------- ...13\350\257\225\350\247\204\350\214\203.md" | 58 ++++++++++++ ...00\345\217\221\350\247\204\350\214\203.md" | 39 -------- 5 files changed, 155 insertions(+), 110 deletions(-) create mode 100644 "specs/StrangeSort \345\274\200\345\217\221\350\247\204\350\214\203.md" delete mode 100644 "specs/StrangeSort \351\241\271\347\233\256\345\274\200\345\217\221\350\247\204\350\214\203.md" create mode 100644 "specs/StrangeSortTest \346\265\213\350\257\225\350\247\204\350\214\203.md" delete mode 100644 "specs/StrangeSortTest \351\241\271\347\233\256\345\274\200\345\217\221\350\247\204\350\214\203.md" diff --git a/AGENTS.md b/AGENTS.md index f49abea..f8fa215 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,7 +11,9 @@ ## 规范文件 -规范文件位于 specs/ 目录中,其内的每个文件内包含必须遵守的开发规范。如果你发现各个规范文件之间有冲突,必须告诉用户。如果有对行为契约的变更,务必更新规范文件。 +规范文件位于 specs/ 目录中,包含必须遵守的开发规范和功能行为契约。 + +如果你发现各个规范文件之间有冲突,必须告诉用户。如果有对功能行为契约的变更,务必更新规范文件,并提示用户。 ## 计划文件 @@ -24,6 +26,11 @@ 当用户要求你把制定好的开发计划写入到文件时,除非用户明确要求你写入到已有的计划文件,否则你必须写入到新计划文件。 除非用户要求,否则忽略计划文件目录内的计划文件(除了用户提到的文件),将它们视为历史计划。制定新计划时,不必变更旧的计划。 +## README 文件和 wiki 目录 + +1. `README.md` 写项目介绍,快速开始指导和文档索引。 +2. `wiki/` 写快速开始和算法使用教程。 + ## 功能实现注意事项 当用户要求你把某个计划文件落地实现: diff --git "a/specs/StrangeSort \345\274\200\345\217\221\350\247\204\350\214\203.md" "b/specs/StrangeSort \345\274\200\345\217\221\350\247\204\350\214\203.md" new file mode 100644 index 0000000..1bb0847 --- /dev/null +++ "b/specs/StrangeSort \345\274\200\345\217\221\350\247\204\350\214\203.md" @@ -0,0 +1,89 @@ +# StrangeSort 开发规范 + +## 架构设计要求 + +1. 保持高内聚、低耦合。 +2. 一个类型只负责一类明确职责,避免功能堆叠。 +3. 优先组合而不是继承。 +4. 公共 API 变更必须谨慎,未经明确要求不要新增、删除、重命名或重排公开重载。 +5. 默认参数语义、泛型约束、枚举合法值和异常行为未经明确要求不得改变。 +6. 实现可以重构,公开行为不能漂移。 + +## 变更防漂移规定 + +1. 修改算法前,先明确这次改动属于“修复实现偏离现有协议”还是“有意修改协议”。 +2. 如果只是修复实现,必须保持本文件中的公开行为协议不变,并补测试证明协议仍成立。 +3. 如果有意修改协议,必须在同一次改动中同步更新本文件、测试和受影响的 `README.md` 或 `wiki/`。 +4. 禁止只改实现不改规范,也禁止只改测试去迎合实现。 +5. 禁止把这些奇异算法静默改造成正常排序算法。 +6. 禁止在没有公开说明的情况下改变空输入、单元素、重复值、随机源为空、比较器为空、非法枚举值、不可比较类型和溢出等边界行为。 + +## 算法行为协议 + +### StalinSort + +公开 API 族:提供 `T[]` 和 `List` 两组 `RemoveOutOfOrder` 重载,支持默认比较器和显式 `IComparer`。 + +1. 从左到右扫描输入,第一个元素总是保留。 +2. 仅当 `comparer.Compare(lastKept, current) <= 0` 时保留当前元素,否则删除。 +3. 输出始终是输入的子序列,保留元素相对顺序不变;禁止交换、重排或额外排序。 +4. 数组重载不修改输入数组。`values.Length <= 1` 时返回原数组引用;长度大于 `1` 时总返回新数组,即使输入本身已满足顺序。 +5. `List` 重载原地删除违序元素。 +6. `comparer == null` 时使用 `Comparer.Default`;只有真的发生比较时才要求 `T` 可比较。 +7. `values == null` 时抛 `ArgumentNullException`;默认比较器不可用且运行时需要比较时抛 `ArgumentException`;自定义比较器异常原样传播。 +8. 数组重载异常后输入保持不变;`List` 重载异常后可能已部分修改,且不回滚。 + +### ThanosSort + +公开 API 族:提供 `T[]` 和 `List` 两组 `PruneUntilSorted` 重载,支持默认比较器、显式 `IComparer`、`RemovalCountStrategy` 和 `Random`。 + +1. 反复检查当前序列是否有序;如果无序,就随机删除当前序列的一半元素;重复直到结果有序。 +2. 输出始终是输入的有序子序列,且幸存元素保持原有相对顺序。 +3. `RemovalCountStrategy.FloorHalf` 在奇数长度时删除 `count / 2`;`RemovalCountStrategy.CeilingHalf` 在奇数长度时删除 `(count + 1) / 2`。 +4. 数组重载不修改输入数组。`values.Length <= 1` 或输入本身已排序时返回原数组引用;其余情况下返回新数组。 +5. `List` 重载原地随机删除元素,直到列表有序。 +6. `comparer == null` 时使用 `Comparer.Default`;`random == null` 时使用 `Random.Shared`;默认删除策略为 `FloorHalf`。 +7. 使用相同输入、比较器、删除策略和显式随机种子时,数组重载可复现,列表重载可复现,且两者结果内容一致。 +8. `values == null` 或显式传入的 `random == null` 时抛 `ArgumentNullException`;非法 `removalStrategy` 抛 `ArgumentOutOfRangeException`;默认比较器不可用且运行时需要比较时抛 `ArgumentException`;比较器和随机源异常原样传播。 +9. 数组重载异常后输入保持不变;`List` 重载异常后可能已部分修改,且不回滚。 + +### EpsteinSort + +公开 API 族:提供 `T[]` 和 `List` 两组 `RetainOnlyMinorsAndSort` 重载,支持默认比较器和显式 `IComparer`,其中 `T : INumber`。 + +1. 算法分两步:先过滤,再排序。 +2. 过滤规则固定为只保留 `[0, 18)` 内的值。 +3. 对浮点类型,`NaN`、`-Infinity` 和 `+Infinity` 都会被删除。 +4. 过滤阶段不受比较器影响;比较器只参与最终排序。 +5. 数组重载不修改输入数组,并始终返回结果数组,不返回原数组引用。 +6. `List` 重载先原地删除所有不在 `[0, 18)` 内的元素,再对保留元素排序。 +7. `comparer == null` 时使用 `Comparer.Default`。 +8. `values == null` 时抛 `ArgumentNullException`。如果比较器在排序阶段抛出异常,底层排序 API 会抛 `InvalidOperationException`,原始比较器异常通常作为 `InnerException` 暴露。 +9. 数组重载异常后输入保持不变;`List` 重载排序失败时,过滤阶段可能已经完成,且不回滚。 + +### BrezhnevSort + +公开 API 族:提供 `T[]` 和 `List` 两组 `RewriteAsOrdinalSequence` 重载,其中 `T : INumber`。 + +1. 不比较、筛选或重排输入元素。 +2. 输出只由输入长度决定。长度为 `n` 时,结果固定为 `1..n`。 +3. 输入元素原值不会被读取,也不会影响结果。 +4. 数组重载不修改输入数组,并始终返回新的结果数组。 +5. `List` 重载原地把整个列表改写为 `1..n`。 +6. `values == null` 时抛 `ArgumentNullException`。 +7. 当输入长度超出 `T` 的可表示范围时抛 `OverflowException`。 +8. 数组重载异常后输入保持不变;`List` 重载溢出时可能已部分修改,且不回滚。 + +### TrumpSort + +公开 API 族:提供 `T[]` 和 `List` 两组 `ShuffleAndWin` 重载,支持默认随机源和显式 `Random`。 + +1. 对输入执行一次 Fisher-Yates 随机重排。 +2. 不保证结果有序,不删除元素,也不改写元素值。 +3. 输出与输入长度一致,元素多重集一致。 +4. 数组重载不修改输入数组,并始终返回结果数组,不返回原数组引用。 +5. `List` 重载原地随机重排。 +6. `random == null` 时使用 `Random.Shared`。 +7. 使用相同输入和显式随机种子时,数组重载可复现,列表重载可复现,且两者结果内容一致。 +8. `values == null` 或显式传入的 `random == null` 时抛 `ArgumentNullException`;随机源异常原样传播。 +9. 数组重载异常后输入保持不变;`List` 重载异常后可能已部分修改,且不回滚。 diff --git "a/specs/StrangeSort \351\241\271\347\233\256\345\274\200\345\217\221\350\247\204\350\214\203.md" "b/specs/StrangeSort \351\241\271\347\233\256\345\274\200\345\217\221\350\247\204\350\214\203.md" deleted file mode 100644 index 9979564..0000000 --- "a/specs/StrangeSort \351\241\271\347\233\256\345\274\200\345\217\221\350\247\204\350\214\203.md" +++ /dev/null @@ -1,70 +0,0 @@ -# StrangeSort 项目开发规范 - -## 整体架构设计目标 - -1. 实现高内聚,低耦合的功能架构。 -2. 遵守开闭原则,一个类应该对扩展开放,对修改封闭。 -3. 遵守单一职责原则,一个类应该只有一个发生变化的原因,即一个类只负责一项职责。禁止引入功能繁多的超级类。 -4. 遵守里氏替换原则,派生类的对象能够替换其基类的对象被使用,且不破坏程序的正确性。 -5. 遵守接口隔离原则,一个类不应该使用它不需要的接口。使用多个专门的接口比使用一个单一的总接口更好,降低依赖耦合。 -6. 遵守依赖倒置原则,高层模块不应该直接依赖底层模块,二者都应该依赖其抽象。面向接口编程,不面向具体某个类的实现编程。 -7. 遵守迪米特法则,一个对象应当对其他对象有最少的了解。即:一个类尽量降低其成员的访问权限,避免低层耦合。 -8. 遵守合成复用原则,尽量使用对象组合或聚合,而不是继承关系来达到软件模块复用的目的。 - -## 公开行为契约 - -1. 本规范文件是项目公开算法行为的唯一契约来源。算法说明、输入输出、异常、随机性、是否原地修改、是否返回原引用或新实例等对外可观察行为,均以本规范文件为准。 -2. `README.md` 与 GitHub Wiki 只承担项目介绍、导航和补充说明职责,不是公开行为契约来源。 -3. 当 `README.md`、GitHub Wiki 与实现或测试不一致时,必须先明确当前改动属于“修复实现偏离契约”,还是“有意修改契约”。禁止在未说明的情况下静默选择其一。 - -## 算法行为冻结要求 - -1. 除非用户明确要求或批准行为变更,否则修改算法实现时,禁止改变任何既有公开可观察行为。 -2. 公开可观察行为至少包括以下内容: - - 输出内容与输出长度规则。 - - 是否保持输入元素的相对顺序。 - - 是否允许重排元素。 - - 是否会删除元素、改写元素或仅调整顺序。 - - 数组重载是否修改输入数组,是否返回原数组引用,还是返回新数组。 - - `List` 重载是否原地修改,以及异常时是否可能部分修改。 - - `comparer == null` 时是否使用 `Comparer.Default`。 - - `random` 未显式传入时是否使用 `Random.Shared`。 - - 随机算法在固定随机种子下是否可复现,以及数组重载和列表重载在相同种子下是否应表现一致。 - - 异常类型、异常触发条件,以及异常发生后输入是否保持不变。 -3. 任何仅以“更合理”“更像正常排序”“性能更好”“代码更简洁”为理由的改动,都不能成为改变算法语义的正当依据。 - -## 各算法不可漂移红线 - -1. `StalinSort`:输出必须始终是输入的子序列,且保留元素的相对顺序不变。禁止引入交换、重排或额外排序。 -2. `ThanosSort`:输出必须始终是输入的有序子序列。禁止把该算法改成直接排序、非随机裁剪,或改变固定随机种子下的可复现性。 -3. `EpsteinSort`:过滤规则固定为数值区间 `[0, 18)`;过滤阶段不得受比较器影响。禁止在未修改契约的情况下扩大、缩小或替换该过滤规则。 -4. `BrezhnevSort`:输出只能由输入长度决定,不得读取输入元素值来影响结果。禁止把它改成基于原值排序、筛选或重排的算法。 -5. `TrumpSort`:行为固定为执行一次随机重排。禁止把它改成多轮随机处理、带筛选的处理,或任何保证结果有序的实现。 - -## 算法修改流程 - -1. 修改任一算法前,必须先明确这次改动属于以下哪一类: - - 修复实现缺陷,但不改变公开契约。 - - 修改公开契约。 -2. 若属于“修复实现缺陷”,提交内容必须能说明哪些测试证明契约未发生漂移。 -3. 若属于“修改公开契约”,则必须在同一次改动中同步更新以下内容: - - 本规范文件中对应算法说明。 - - 本目录下受影响的规范条款。 - - 对应测试用例。 -4. 禁止只修改实现而不更新契约说明;也禁止只修改文档或测试而保留与之冲突的实现。 - -## 实现约束 - -1. 优先保持现有公开 API 形状稳定。未经明确要求,不要新增、删除、重命名或重排公开重载。 -2. 未经明确要求,不要改变泛型约束、默认参数语义、枚举合法取值范围及其异常行为。 -3. 未经明确要求,不要把当前“返回原引用”的情形改为“总是新分配”,也不要反向修改。 -4. 未经明确要求,不要把当前“异常时可能部分修改输入”的行为改成回滚语义,也不要反向修改。 -5. 如果为了修复缺陷必须触及上述行为,必须先把该改动按“契约变更”处理,而不是伪装成普通重构。 - -## 禁止事项 - -1. 禁止为了让算法“更符合常见排序直觉”而修改奇异算法的核心语义。 -2. 禁止为了通过测试而在实现中硬编码特定输入、特定长度、特定随机种子或特定比较器结果。 -3. 禁止在没有公开说明的情况下,静默改变边界条件行为,例如空输入、单元素输入、重复值、不可比较类型、非法枚举值、溢出和随机源为空等场景。 -4. 禁止在未更新契约和测试前,合并任何会改变公开行为的算法修改。 - diff --git "a/specs/StrangeSortTest \346\265\213\350\257\225\350\247\204\350\214\203.md" "b/specs/StrangeSortTest \346\265\213\350\257\225\350\247\204\350\214\203.md" new file mode 100644 index 0000000..6e4e844 --- /dev/null +++ "b/specs/StrangeSortTest \346\265\213\350\257\225\350\247\204\350\214\203.md" @@ -0,0 +1,58 @@ +# StrangeSortTest 测试规范 + +## 目标 + +1. `StrangeSortTest` 的首要职责是防止公开行为漂移和功能实现错误。 +2. 测试要以 `specs/StrangeSort 开发规范.md` 内算法行为协议为准,不要只按当前实现去写断言。 + +## 通用要求 + +1. 任何算法改动,至少覆盖对应算法的数组重载和 `List` 重载。 +2. 任何协议变更,必须在同一次改动中同步更新规范和测试。 +3. 禁止为了让测试通过而在实现中硬编码输入、长度、随机种子或比较结果。 +4. 随机相关测试必须显式控制随机种子,不要依赖 `Random.Shared` 的即时输出。 +5. 异常测试除了断言异常类型,还要断言输入是否被修改。 + +## 边缘条件测试指南 + +1. 优先覆盖空输入、单元素输入、重复元素、已满足目标条件的输入和最小可复现输入。 +2. 覆盖 `null` 参数、`comparer == null`、`random == null`、非法枚举值、不可比较类型和溢出路径。 +3. 区分数组重载与 `List` 重载的输入修改语义、返回引用语义和异常后状态。 +4. 如果规范声明了相对顺序、元素多重集、子序列性质、固定过滤区间或固定结果长度,这些都应有直接断言。 +5. 文档中的调用示例应尽量有对应测试,避免示例和真实行为脱节。 + +## 各算法重点 + +### StalinSort + +1. 断言输出是输入子序列,且相对顺序保持不变。 +2. 断言数组重载在长度 `0` 或 `1` 时返回原引用,在更长输入时返回新数组。 +3. 覆盖默认比较器不可用时的异常,以及 `List` 异常后可能部分修改。 + +### ThanosSort + +1. 断言结果始终是有序子序列。 +2. 覆盖 `FloorHalf` 和 `CeilingHalf` 两种删除策略。 +3. 使用固定种子验证数组重载可复现、列表重载可复现,以及两者结果一致。 +4. 覆盖非法 `RemovalCountStrategy` 和显式 `random == null`。 + +### EpsteinSort + +1. 断言结果只包含 `[0, 18)` 内的值。 +2. 对浮点类型覆盖 `NaN`、`-Infinity` 和 `+Infinity`。 +3. 断言过滤不受比较器影响,比较器只影响排序结果。 +4. 覆盖排序异常时 `List` 可能已经完成过滤的情况。 + +### BrezhnevSort + +1. 断言结果只由输入长度决定,与输入值无关。 +2. 断言数组重载始终返回新数组。 +3. 覆盖目标类型可表示范围不足时的 `OverflowException`。 +4. 覆盖 `List` 溢出时可能部分改写的情况。 + +### TrumpSort + +1. 断言结果长度不变,元素多重集不变。 +2. 使用固定种子验证数组重载可复现、列表重载可复现,以及两者结果一致。 +3. 断言数组重载始终返回新数组。 +4. 覆盖显式 `random == null` 和随机源异常传播。 diff --git "a/specs/StrangeSortTest \351\241\271\347\233\256\345\274\200\345\217\221\350\247\204\350\214\203.md" "b/specs/StrangeSortTest \351\241\271\347\233\256\345\274\200\345\217\221\350\247\204\350\214\203.md" deleted file mode 100644 index fe48a5c..0000000 --- "a/specs/StrangeSortTest \351\241\271\347\233\256\345\274\200\345\217\221\350\247\204\350\214\203.md" +++ /dev/null @@ -1,39 +0,0 @@ -# StrangeSortTest 项目开发规范 - -1. 在编写测试代码时,严禁为了让测试用例通过而引入违反开发目标和开发计划的补丁,例如硬编码一个值让测试用例通过。 - -## 契约测试原则 - -1. `StrangeSortTest` 的首要职责是防止算法公开行为发生漂移,而不只是验证“代码当前怎么写就怎么测”。 -2. 对外公开行为以 `specs/StrangeSort 项目开发规范.md` 为准。测试应优先覆盖该规范文件中已声明的行为、边界条件、异常和示例。 -3. 当实现修改但公开契约不变时,必须补充或调整测试来证明契约仍然成立。 -4. 当公开契约有意变更时,必须在同一次改动中同步更新 `specs/StrangeSort 项目开发规范.md` 与测试;禁止只改实现不改测试预期,也禁止只改测试去迎合实现。 - -## 算法修改后的最低测试要求 - -1. 任何涉及算法实现的改动,至少应覆盖对应算法的数组重载和 `List` 重载。 -2. 任何涉及算法实现的改动,至少应覆盖以下一类或多类测试,具体以该算法公开契约为准: - - `specs/StrangeSort 项目开发规范.md` 中已出现的调用示例。 - - 空输入、单元素输入、重复元素、已满足目标条件的输入。 - - 是否保持相对顺序、是否保持元素多重集、是否只输出子序列、是否改写元素值等不变量。 - - 数组重载是否保持输入不变,是否返回原引用或新数组。 - - `List` 重载是否原地修改,以及异常时可能出现的部分修改行为。 - - `comparer == null`、`random == null`、非法枚举值、不可比较类型、溢出等异常路径。 - - 固定随机种子下的可复现性,以及数组重载和列表重载在相同随机种子下的一致性。 - -## 各算法建议重点覆盖的不变量 - -1. `StalinSort`:输出是输入子序列,且相对顺序保持不变。 -2. `ThanosSort`:输出是输入的有序子序列;固定种子时结果可复现。 -3. `EpsteinSort`:结果仅包含 `[0, 18)` 内的值;过滤不受比较器影响;结果最终按比较器排序。 -4. `BrezhnevSort`:结果只由输入长度决定;输入原值不会影响输出;长度超出目标类型表示范围时按契约抛异常。 -5. `TrumpSort`:结果与输入长度一致,元素多重集一致;固定种子时结果可复现;数组重载和列表重载在相同种子下内容一致。 - -## 测试编写约束 - -1. 禁止编写依赖实现细节但未体现公开契约价值的脆弱测试,例如断言内部局部变量、私有辅助流程或偶然的循环结构。 -2. 随机相关测试必须显式控制随机种子,禁止依赖 `Random.Shared` 的即时输出作为断言基础。 -3. 涉及异常的测试,除断言异常类型外,还应验证契约中声明的输入是否被修改。 -4. 新增或修复 bug 测试时,应优先用最小输入构造能稳定复现问题的用例,避免把多个行为混在一个测试里。 -5. 如果发现现有测试没有覆盖 `specs/StrangeSort 项目开发规范.md` 中已写明的行为,应优先补齐缺失覆盖,而不是默认实现当前行为就是正确契约。 - From f6c27c11326fb50c7777f7c8780a606a389620ab Mon Sep 17 00:00:00 2001 From: yhcedpn <261370596+yhcedpn@users.noreply.github.com> Date: Sun, 14 Jun 2026 02:10:09 -0700 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20=E9=87=8D=E7=BB=84=20README=20?= =?UTF-8?q?=E4=B8=8E=20Wiki=20=E6=95=99=E7=A8=8B=E5=AF=BC=E8=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 47 +++---------- wiki/Algorithm-Overview.md | 21 ------ wiki/BrezhnevSort-Guide.md | 25 +++++++ wiki/BrezhnevSort-Reference.md | 91 ------------------------- wiki/EpsteinSort-Guide.md | 25 +++++++ wiki/EpsteinSort-Reference.md | 115 ------------------------------- wiki/Getting-Started.md | 32 --------- wiki/Home.md | 38 +++++------ wiki/Quick-Start.md | 42 ++++++++++++ wiki/StalinSort-Guide.md | 25 +++++++ wiki/StalinSort-Reference.md | 86 ----------------------- wiki/ThanosSort-Guide.md | 28 ++++++++ wiki/ThanosSort-Reference.md | 120 --------------------------------- wiki/TrumpSort-Guide.md | 24 +++++++ wiki/TrumpSort-Reference.md | 92 ------------------------- wiki/_Sidebar.md | 13 ++-- 16 files changed, 200 insertions(+), 624 deletions(-) delete mode 100644 wiki/Algorithm-Overview.md create mode 100644 wiki/BrezhnevSort-Guide.md delete mode 100644 wiki/BrezhnevSort-Reference.md create mode 100644 wiki/EpsteinSort-Guide.md delete mode 100644 wiki/EpsteinSort-Reference.md delete mode 100644 wiki/Getting-Started.md create mode 100644 wiki/Quick-Start.md create mode 100644 wiki/StalinSort-Guide.md delete mode 100644 wiki/StalinSort-Reference.md create mode 100644 wiki/ThanosSort-Guide.md delete mode 100644 wiki/ThanosSort-Reference.md create mode 100644 wiki/TrumpSort-Guide.md delete mode 100644 wiki/TrumpSort-Reference.md diff --git a/README.md b/README.md index 4cb505f..c16f360 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,21 @@ # StrangeSort -`StrangeSort` 是一个基于 .NET 10 的 C# 类库,只收录和实现几种冠以**经典人物的名字**的奇异算法。 - -这个仓库当前包含 5 组公开算法: - -- `StalinSort`:从左到右删除违序元素,保留一个有序子序列。大力清洗所有不符合要求的元素! -- `ThanosSort`:随机删除当前序列的一半元素,重复执行直到序列有序。一键清除多余元素,剩下多少你别问,嘿嘿。 -- `EpsteinSort`:先保留数值区间 `[0, 18)` 内的元素,再对保留元素排序。只保留未成年数字,太老的全部斩杀! -- `BrezhnevSort`:无视输入值本身,只根据输入长度把结果改写为从 `1` 到 `n` 的序数序列。内容不重要,排场最重要! -- `TrumpSort`:对输入内容执行一次随机重排。具体发生了什么不重要,先赢再说! +`StrangeSort` 是一个基于 `.NET 10` 的 C# 类库,实现几种冠以**历史经典人物**的名字的奇异算法。只是为了好玩! ## 快速开始 -### 从 GitHub Packages 安装 - -当前包名是 `StrangeSort`,GitHub Packages 源地址示例为 `https://nuget.pkg.github.com/yhcedpn/index.json`。 - -首次使用时,先添加包源: - -```powershell -dotnet nuget add source "https://nuget.pkg.github.com/yhcedpn/index.json" --name github-yhcedpn --username YOUR_GITHUB_USERNAME --password YOUR_GITHUB_PAT --store-password-in-clear-text -``` - -然后安装包: - -```powershell -dotnet add package StrangeSort --version --source github-yhcedpn -``` +NuGet 包名:`StrangeSort` -### 快速使用 +GitHub Packages 源:`https://nuget.pkg.github.com/yhcedpn/index.json` -调用前通常需要引入对应命名空间: +[Wiki 快速开始](./wiki/Quick-Start.md):安装后的最小使用路径。 -```csharp -using StrangeSort.StalinSort; -using StrangeSort.ThanosSort; -using StrangeSort.EpsteinSort; -using StrangeSort.BrezhnevSort; -using StrangeSort.TrumpSort; +## 文档索引 -int[] source = [3, 1, 2, 4]; -int[] result = StalinSorter.RemoveOutOfOrder(source); -``` +1. [StrangeSort 开发规范](./specs/StrangeSort%20%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md):架构设计要求、变更防漂移规定、各算法行为协议。 -## 详细文档 +2. [StrangeSortTest 测试规范](./specs/StrangeSortTest%20%E6%B5%8B%E8%AF%95%E8%A7%84%E8%8C%83.md):边缘条件测试指南与测试约束。 -详见 Wiki: +3. [Wiki 主索引](./wiki/Home.md):文档入口。 -公开行为契约以规范文件为准,`README.md` 与 GitHub Wiki 只承担项目介绍、导航和补充说明职责:[StrangeSort 项目开发规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSort%20%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md) +4. `wiki/*-Guide.md`:各算法使用教程页。 diff --git a/wiki/Algorithm-Overview.md b/wiki/Algorithm-Overview.md deleted file mode 100644 index aed3cce..0000000 --- a/wiki/Algorithm-Overview.md +++ /dev/null @@ -1,21 +0,0 @@ -# Algorithm Overview - -导航: [Home](Home) | [Getting Started](Getting-Started) - -| 算法 | 命名空间 | 核心行为 | 是否重排元素 | 是否依赖随机性 | -| --- | --- | --- | --- | --- | -| [StalinSort Reference](StalinSort-Reference) | `StrangeSort.StalinSort` | 从左到右删除相对最近保留元素违序的元素 | 否,只删除 | 否 | -| [ThanosSort Reference](ThanosSort-Reference) | `StrangeSort.ThanosSort` | 每轮随机删除一半元素,直到结果有序 | 否,只删除 | 是 | -| [EpsteinSort Reference](EpsteinSort-Reference) | `StrangeSort.EpsteinSort` | 先过滤到 `[0, 18)`,再排序 | 是,会排序保留元素 | 否 | -| [BrezhnevSort Reference](BrezhnevSort-Reference) | `StrangeSort.BrezhnevSort` | 无视原值,只按输入长度生成 `1..n` | 否,不重排,但会重写所有值 | 否 | -| [TrumpSort Reference](TrumpSort-Reference) | `StrangeSort.TrumpSort` | 对输入执行一次 Fisher-Yates 随机重排 | 是,重排全部元素 | 是 | - -## 一句话介绍 - -- `StalinSort`:从左到右删除违序元素,保留一个有序子序列。 -- `ThanosSort`:随机删除当前序列的一半元素,重复执行直到序列有序。 -- `EpsteinSort`:先保留数值区间 `[0, 18)` 内的元素,再对保留元素排序。 -- `BrezhnevSort`:无视输入值本身,只根据输入长度把结果改写为从 `1` 到 `n` 的序数序列。 -- `TrumpSort`:对输入内容执行一次随机重排。 - -公开行为契约仍以 [StrangeSort 项目开发规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSort%20%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md) 为准。 diff --git a/wiki/BrezhnevSort-Guide.md b/wiki/BrezhnevSort-Guide.md new file mode 100644 index 0000000..a4bc4c2 --- /dev/null +++ b/wiki/BrezhnevSort-Guide.md @@ -0,0 +1,25 @@ +# BrezhnevSort Guide + +`BrezhnevSort` 不看输入值,只按输入长度生成 `1..n`。 + +## 什么时候用 + +当你要把任意数值序列直接改写成序数序列时可以用它,可以让任意数值序列和勃列日涅夫同志领导的中央的总路线一起摇摆! + +## 示例 + +```csharp +var values = new[] { 999, -3, 42, 0 }; +var result = BrezhnevSorter.RewriteAsOrdinalSequence(values); +// result = [1, 2, 3, 4] +``` + +## 要点 + +1. 输出只由输入长度决定。 +2. 它不是重排,而是重写。 +3. 输入值再特殊,也不会影响结果。 + +## 相关规范 + +[StrangeSort 开发规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSort%20%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md) diff --git a/wiki/BrezhnevSort-Reference.md b/wiki/BrezhnevSort-Reference.md deleted file mode 100644 index d631c72..0000000 --- a/wiki/BrezhnevSort-Reference.md +++ /dev/null @@ -1,91 +0,0 @@ -# BrezhnevSort Reference - -导航: [Home](Home) | [Getting Started](Getting-Started) | [Algorithm Overview](Algorithm-Overview) - -说明:本页是参考文档,不是公开行为契约来源;如有冲突,以 [StrangeSort 项目开发规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSort%20%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md) 为准。 - -## 算法说明 - -`BrezhnevSort` 不是传统排序。它不会比较、筛选或重排输入元素,而是只根据输入长度生成一个固定结果: - -- 输入长度为 `n` -- 输出内容固定为从 `1` 到 `n` 的序数序列 -- 输入元素原有的值不会被读取,也不会影响输出结果 - -因此,两个长度相同但内容完全不同的输入,会得到相同的输出。 - -例如: - -- 输入:`[999, -3, 42]` -- 输出:`[1, 2, 3]` - -## 公共 API - -```csharp -public static T[] RewriteAsOrdinalSequence(T[] values) - where T : INumber - -public static void RewriteAsOrdinalSequence(List values) - where T : INumber -``` - -## 输入与输出 - -数组重载: - -- 输入:`T[] values` -- 类型约束:`T : INumber` -- 输出:`T[]` -- 行为:不修改输入数组,返回一个新的结果数组 -- 特别说明: - - 返回数组长度与输入数组一致 - - 返回内容固定为 `1..n` - - 输入数组中的原始值不会影响结果 - - 即使输入本身已经是 `1..n`,也仍然返回新数组而不是原数组引用 - -`List` 重载: - -- 输入:`List values` -- 类型约束:`T : INumber` -- 输出:无返回值,结果直接写回原列表 -- 行为:原地把整个列表改写为 `1..n` -- 特别说明: - - 空列表保持为空 - - 原列表中的原始值不会影响结果 - -## 异常 - -所有重载都可能出现: - -- `ArgumentNullException` - - `values == null` - -所有重载都还可能出现: - -- `OverflowException` - - 当输入长度超出 `T` 可表示范围时抛出 - - 例如对 `byte` 来说,长度达到 `256` 就无法表示 - -数组重载异常特征: - -- 如果抛出异常,输入数组不会被修改 - -`List` 重载异常特征: - -- 如果在改写途中因数值转换溢出抛出异常,列表可能已经被部分修改 -- 该修改不会回滚 - -## 调用示例 - -```csharp -var values = new[] { 999, -3, 42, 0 }; -var result = BrezhnevSorter.RewriteAsOrdinalSequence(values); -// result = [1, 2, 3, 4] -// values 保持不变 - -var list = new List { 100, -5, 8 }; -BrezhnevSorter.RewriteAsOrdinalSequence(list); -// list = [1, 2, 3] -``` - -导航: [Home](Home) | [Getting Started](Getting-Started) | [Algorithm Overview](Algorithm-Overview) diff --git a/wiki/EpsteinSort-Guide.md b/wiki/EpsteinSort-Guide.md new file mode 100644 index 0000000..743f0ba --- /dev/null +++ b/wiki/EpsteinSort-Guide.md @@ -0,0 +1,25 @@ +# EpsteinSort Guide + +`EpsteinSort` 会先过滤,再排序。只有 `[0, 18)` 内的值能留下来。 + +## 什么时候用 + +当你需要固定区间过滤加排序,而不是通用排序时可以用它。像爱泼斯坦先生一样,保留并排序未成年人! + +## 示例 + +```csharp +var values = new[] { 18, 0, -5, 17, 5, 18, 2, -1 }; +var result = EpsteinSorter.RetainOnlyMinorsAndSort(values); +// result = [0, 2, 5, 17] +``` + +## 要点 + +1. 过滤规则固定是 `[0, 18)`。 +2. 比较器只影响排序,不影响过滤。 +3. 对浮点类型,`NaN` 和正负无穷都会被删除。 + +## 相关规范 + +[StrangeSort 开发规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSort%20%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md) diff --git a/wiki/EpsteinSort-Reference.md b/wiki/EpsteinSort-Reference.md deleted file mode 100644 index f092af1..0000000 --- a/wiki/EpsteinSort-Reference.md +++ /dev/null @@ -1,115 +0,0 @@ -# EpsteinSort Reference - -导航: [Home](Home) | [Getting Started](Getting-Started) | [Algorithm Overview](Algorithm-Overview) - -说明:本页是参考文档,不是公开行为契约来源;如有冲突,以 [StrangeSort 项目开发规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSort%20%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md) 为准。 - -## 算法说明 - -`EpsteinSort` 的行为分为两步: - -1. 过滤:只保留数值位于 `[0, 18)` 的元素。 -2. 排序:对保留元素做最终排序。 - -这不是一个通用任意范围排序器,而是一个“固定过滤规则 + 排序”的算法实现。 - -过滤规则固定为: - -- `value >= 0` -- `value < 18` - -对浮点数还有额外约束: - -- `NaN` 会被删除 -- `-Infinity` 会被删除 -- `+Infinity` 会被删除 - -过滤阶段永远只看这个固定数值区间,不受比较器影响;比较器只参与最后的排序阶段。 - -## 公共 API - -```csharp -public static T[] RetainOnlyMinorsAndSort(T[] values) - where T : INumber - -public static T[] RetainOnlyMinorsAndSort(T[] values, IComparer? comparer) - where T : INumber - -public static void RetainOnlyMinorsAndSort(List values) - where T : INumber - -public static void RetainOnlyMinorsAndSort(List values, IComparer? comparer) - where T : INumber -``` - -## 输入与输出 - -数组重载: - -- 输入:`T[] values` -- 类型约束:`T : INumber` -- 可选输入:`IComparer? comparer` -- 输出:`T[]` -- 行为:不修改输入数组,返回过滤并排序后的结果数组 -- 默认值:`comparer == null` 时使用 `Comparer.Default` -- 特别说明: - - 空输入返回 `Array.Empty()` - - 结果只包含满足 `[0, 18)` 的值 - - 结果一定已经按比较器定义完成排序 - -`List` 重载: - -- 输入:`List values` -- 类型约束:`T : INumber` -- 可选输入:`IComparer? comparer` -- 输出:无返回值,结果直接写回原列表 -- 行为:先原地删除不满足 `[0, 18)` 的元素,再对保留元素排序 -- 默认值:`comparer == null` 时使用 `Comparer.Default` - -## 异常 - -所有重载都可能出现: - -- `ArgumentNullException` - - `values == null` - -比较器相关异常: - -- 如果传入的比较器在排序阶段抛出异常,异常会继续向外传播 -- 对 `EpsteinSort` 来说,排序阶段依赖 `Array.Sort` 或 `List.Sort` -- 实测行为上,比较器抛出的原始异常通常会作为 `InnerException` 被包装在 `InvalidOperationException` 中抛出 - -数组重载异常特征: - -- 即使排序失败,输入数组也不会被修改 - -`List` 重载异常特征: - -- 如果排序阶段失败,过滤阶段可能已经完成 -- 也就是说,列表可能已经删掉了所有不在 `[0, 18)` 内的值 -- 该修改不会回滚 - -## 调用示例 - -```csharp -var values = new[] { 18, 0, -5, 17, 5, 18, 2, -1 }; -var result = EpsteinSorter.RetainOnlyMinorsAndSort(values); -// result = [0, 2, 5, 17] -// values 保持不变 - -var list = new List -{ - double.NaN, - 3.5, - double.PositiveInfinity, - -1.0, - 0.0, - 18.0, - double.NegativeInfinity, - 17.25, -}; -EpsteinSorter.RetainOnlyMinorsAndSort(list); -// list = [0.0, 3.5, 17.25] -``` - -导航: [Home](Home) | [Getting Started](Getting-Started) | [Algorithm Overview](Algorithm-Overview) diff --git a/wiki/Getting-Started.md b/wiki/Getting-Started.md deleted file mode 100644 index f111524..0000000 --- a/wiki/Getting-Started.md +++ /dev/null @@ -1,32 +0,0 @@ -# Getting Started - -导航: [Home](Home) | [Algorithm Overview](Algorithm-Overview) - -`StrangeSort` 是一个基于 .NET 10 的 C# 类库,只收录和实现几种冠以**经典人物的名字**的奇异算法。 - -## 项目概览 - -- 目标运行时:`.NET 10` -- 核心项目:`StrangeSort` -- 测试项目:`StrangeSortTest` -- 核心库开启了 AOT 兼容性检查,测试项目开启了 AOT 发布 - -## 如何引用 - -如果你在同一个解决方案中使用它,直接给你的项目添加对 `StrangeSort/StrangeSort.csproj` 的项目引用即可。 - -调用前通常需要引入对应命名空间: - -```csharp -using StrangeSort.StalinSort; -using StrangeSort.ThanosSort; -using StrangeSort.EpsteinSort; -using StrangeSort.BrezhnevSort; -using StrangeSort.TrumpSort; -``` - -## 下一步阅读 - -- 想先快速了解五个算法差异:查看 [Algorithm Overview](Algorithm-Overview) -- 想直接查某个算法的公共 API、输入输出与异常:进入各算法参考页 -- 想确认公开行为契约:查看 [StrangeSort 项目开发规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSort%20%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md) diff --git a/wiki/Home.md b/wiki/Home.md index 4e9fc2d..3be508e 100644 --- a/wiki/Home.md +++ b/wiki/Home.md @@ -1,30 +1,24 @@ # StrangeSort Wiki -`StrangeSort` 是一个基于 .NET 10 的 C# 类库,只收录和实现几种冠以**经典人物的名字**的奇异算法。 +这里是 StrangeSort 的文档主索引。 -这个仓库当前包含 5 组公开算法: +## 先看哪里 -- `StalinSort`:从左到右删除违序元素,保留一个有序子序列。大力清洗所有不符合要求的元素! -- `ThanosSort`:随机删除当前序列的一半元素,重复执行直到序列有序。一键清除多余元素,剩下多少你别问,嘿嘿。 -- `EpsteinSort`:先保留数值区间 `[0, 18)` 内的元素,再对保留元素排序。只保留未成年数字,太老的全部斩杀! -- `BrezhnevSort`:无视输入值本身,只根据输入长度把结果改写为从 `1` 到 `n` 的序数序列。内容不重要,排场最重要! -- `TrumpSort`:对输入内容执行一次随机重排。具体发生了什么不重要,先赢再说! +1. 想先跑起来:看 [Quick Start](Quick-Start)。 +2. 想了解具体算法怎么用:看下面的算法教程页。 +3. 想确认精确行为和测试要求:看仓库 `specs/` 里的两份规范。 -## 文档导航 +## 页面索引 -- [Getting Started](Getting-Started) -- [Algorithm Overview](Algorithm-Overview) -- [StalinSort Reference](StalinSort-Reference) -- [ThanosSort Reference](ThanosSort-Reference) -- [EpsteinSort Reference](EpsteinSort-Reference) -- [BrezhnevSort Reference](BrezhnevSort-Reference) -- [TrumpSort Reference](TrumpSort-Reference) +1. [Quick Start](Quick-Start) +2. [StalinSort Guide](StalinSort-Guide) +3. [ThanosSort Guide](ThanosSort-Guide) +4. [EpsteinSort Guide](EpsteinSort-Guide) +5. [BrezhnevSort Guide](BrezhnevSort-Guide) +6. [TrumpSort Guide](TrumpSort-Guide) -## 文档职责说明 +## 规范入口 -GitHub Wiki 用于承载详细参考文档;仓库首页 `README.md` 用于项目简介、快速上手和导航。 - -项目公开行为契约只以规范文件为准;如果 Wiki、`README.md`、实现或测试之间出现不一致,应优先检查规范文件: - -- [StrangeSort 项目开发规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSort%20%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md) -- [仓库 README](https://github.com/yhcedpn/StrangeSort#readme) +1. [StrangeSort 开发规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSort%20%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md) +2. [StrangeSortTest 测试规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSortTest%20%E6%B5%8B%E8%AF%95%E8%A7%84%E8%8C%83.md) +3. [README](https://github.com/yhcedpn/StrangeSort#readme) diff --git a/wiki/Quick-Start.md b/wiki/Quick-Start.md new file mode 100644 index 0000000..f349720 --- /dev/null +++ b/wiki/Quick-Start.md @@ -0,0 +1,42 @@ +# Quick Start + +## 1. 安装包 + +示例命令: + +```powershell +dotnet nuget add source "https://nuget.pkg.github.com/yhcedpn/index.json" --name github-yhcedpn --username YOUR_GITHUB_USERNAME --password YOUR_GITHUB_PAT +dotnet add package StrangeSort --version --source github-yhcedpn +``` + +## 2. 引入命名空间 + +```csharp +using StrangeSort.BrezhnevSort; +using StrangeSort.EpsteinSort; +using StrangeSort.StalinSort; +using StrangeSort.ThanosSort; +using StrangeSort.TrumpSort; +``` + +## 3. 选择一个算法调用 + +```csharp +int[] source = [3, 1, 2, 4]; + +int[] stalin = StalinSorter.RemoveOutOfOrder(source); +int[] thanos = ThanosSorter.PruneUntilSorted( + source, + comparer: null, + removalStrategy: RemovalCountStrategy.FloorHalf, + random: new Random(2026)); +int[] epstein = EpsteinSorter.RetainOnlyMinorsAndSort(source); +int[] brezhnev = BrezhnevSorter.RewriteAsOrdinalSequence(source); +int[] trump = TrumpSorter.ShuffleAndWin(source, new Random(2026)); +``` + +## 4. 接下来读什么 + +1. 想看某个算法的使用说明:进入对应 `*-Guide` 页面。 +2. 想确认精确行为:看 `specs/StrangeSort 开发规范.md`。 +3. 想确认测试覆盖重点:看 `specs/StrangeSortTest 测试规范.md`。 diff --git a/wiki/StalinSort-Guide.md b/wiki/StalinSort-Guide.md new file mode 100644 index 0000000..2a63925 --- /dev/null +++ b/wiki/StalinSort-Guide.md @@ -0,0 +1,25 @@ +# StalinSort Guide + +`StalinSort` 会从左到右删除违序元素,最后留下一个保持原顺序的有序子序列。 + +## 什么时候用 + +当你想保留原始相对顺序,只移除“不合队列”的元素时可以用它。它专为沿袭斯大林同志的方针设计,一键清洗不正确的元素! + +## 示例 + +```csharp +var values = new[] { 2, 1, 3, 2, 4 }; +var result = StalinSorter.RemoveOutOfOrder(values); +// result = [2, 3, 4] +``` + +## 要点 + +1. 它只删除,不排序,不重排。 +2. 结果一定是输入的子序列。 +3. 自定义比较器可以改变“有序”的判断方向。 + +## 相关规范 + +[StrangeSort 开发规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSort%20%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md) diff --git a/wiki/StalinSort-Reference.md b/wiki/StalinSort-Reference.md deleted file mode 100644 index 39ba2b3..0000000 --- a/wiki/StalinSort-Reference.md +++ /dev/null @@ -1,86 +0,0 @@ -# StalinSort Reference - -导航: [Home](Home) | [Getting Started](Getting-Started) | [Algorithm Overview](Algorithm-Overview) - -说明:本页是参考文档,不是公开行为契约来源;如有冲突,以 [StrangeSort 项目开发规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSort%20%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md) 为准。 - -## 算法说明 - -`StalinSort` 不是传统排序算法。它不会交换元素位置,而是从左到右扫描: - -- 第一个元素总是保留。 -- 后续元素如果满足 `comparer.Compare(lastKept, current) <= 0`,就保留。 -- 否则直接删除。 - -因此输出结果一定是输入序列的一个子序列,并且保留元素的相对顺序不变。 - -例如: - -- 输入:`[2, 1, 3, 2, 4]` -- 输出:`[2, 3, 4]` - -## 公共 API - -```csharp -public static T[] RemoveOutOfOrder(T[] values) -public static T[] RemoveOutOfOrder(T[] values, IComparer? comparer) -public static void RemoveOutOfOrder(List values) -public static void RemoveOutOfOrder(List values, IComparer? comparer) -``` - -## 输入与输出 - -数组重载: - -- 输入:`T[] values` -- 可选输入:`IComparer? comparer` -- 输出:`T[]` -- 行为:不修改输入数组,返回一个有序子序列 -- 特别说明: - - 当 `values.Length <= 1` 时,直接返回输入数组引用 - - 当输入已经有序时,返回一个内容等价的新数组,不会改动原数组 - - 当 `comparer == null` 时,使用 `Comparer.Default` - -`List` 重载: - -- 输入:`List values` -- 可选输入:`IComparer? comparer` -- 输出:无返回值,结果直接写回原列表 -- 行为:原地删除违序元素 -- 当 `comparer == null` 时,使用 `Comparer.Default` - -## 异常 - -所有重载都可能出现: - -- `ArgumentNullException` - - `values == null` - -默认比较器相关异常: - -- `ArgumentException` - - 当 `comparer == null`,且 `Comparer.Default` 无法比较 `T`,并且运行时确实需要比较时抛出 - - 典型情况:`T` 没有默认可比性,且输入至少需要做一次比较 - - 不会触发该异常的情况:空数组、单元素数组、空列表、单元素列表 - -自定义比较器相关异常: - -- 比较器自己抛出的异常会继续向外传播 -- 对数组重载,输入数组不会被修改 -- 对 `List` 重载,如果比较器在处理中途抛出异常,列表可能已经被部分修改,且不会回滚 - -## 调用示例 - -```csharp -var values = new[] { 2, 1, 3, 2, 4 }; -var result = StalinSorter.RemoveOutOfOrder(values); -// result = [2, 3, 4] -// values 保持不变 - -var list = new List { 5, 4, 3, 6, 2, 1 }; -var descendingComparer = Comparer.Create((left, right) => right.CompareTo(left)); -StalinSorter.RemoveOutOfOrder(list, descendingComparer); -// list 可能变成 [5, 4, 3, 2, 1] -``` - -导航: [Home](Home) | [Getting Started](Getting-Started) | [Algorithm Overview](Algorithm-Overview) diff --git a/wiki/ThanosSort-Guide.md b/wiki/ThanosSort-Guide.md new file mode 100644 index 0000000..b8bb8df --- /dev/null +++ b/wiki/ThanosSort-Guide.md @@ -0,0 +1,28 @@ +# ThanosSort Guide + +`ThanosSort` 会反复随机删除一半元素,直到剩余结果有序。 + +## 什么时候用 + +当你想保留原顺序,但接受用随机裁剪换取“最终有序”时可以用它。灭霸在此! + +## 示例 + +```csharp +var values = new[] { 5, 1, 4, 4, 2, 3 }; +var result = ThanosSorter.PruneUntilSorted( + values, + comparer: null, + removalStrategy: RemovalCountStrategy.CeilingHalf, + random: new Random(2026)); +``` + +## 要点 + +1. 它不是随机排序,而是随机删到有序。 +2. 幸存元素仍保持原有相对顺序。 +3. 固定随机种子时结果可复现。 + +## 相关规范 + +[StrangeSort 开发规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSort%20%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md) diff --git a/wiki/ThanosSort-Reference.md b/wiki/ThanosSort-Reference.md deleted file mode 100644 index 01f5eae..0000000 --- a/wiki/ThanosSort-Reference.md +++ /dev/null @@ -1,120 +0,0 @@ -# ThanosSort Reference - -导航: [Home](Home) | [Getting Started](Getting-Started) | [Algorithm Overview](Algorithm-Overview) - -说明:本页是参考文档,不是公开行为契约来源;如有冲突,以 [StrangeSort 项目开发规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSort%20%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md) 为准。 - -## 算法说明 - -`ThanosSort` 同样不是传统排序。它的行为是: - -- 先判断当前序列是否已经有序 -- 如果无序,就随机删除当前序列的一半元素 -- 重复以上过程,直到结果有序 - -保留下来的元素仍然保持原有相对顺序,因此输出仍然是输入序列的一个有序子序列。 - -当当前长度为奇数时,每轮删除多少个元素由 `RemovalCountStrategy` 控制: - -- `RemovalCountStrategy.FloorHalf = 0`:删除 `count / 2` -- `RemovalCountStrategy.CeilingHalf = 1`:删除 `(count + 1) / 2` - -## 公共 API - -```csharp -public static T[] PruneUntilSorted(T[] values) -public static T[] PruneUntilSorted(T[] values, IComparer? comparer) -public static T[] PruneUntilSorted(T[] values, IComparer? comparer, RemovalCountStrategy removalStrategy) -public static T[] PruneUntilSorted(T[] values, IComparer? comparer, RemovalCountStrategy removalStrategy, Random random) - -public static void PruneUntilSorted(List values) -public static void PruneUntilSorted(List values, IComparer? comparer) -public static void PruneUntilSorted(List values, IComparer? comparer, RemovalCountStrategy removalStrategy) -public static void PruneUntilSorted(List values, IComparer? comparer, RemovalCountStrategy removalStrategy, Random random) -``` - -## 输入与输出 - -数组重载: - -- 输入:`T[] values` -- 可选输入:`IComparer? comparer`、`RemovalCountStrategy removalStrategy`、`Random random` -- 输出:`T[]` -- 行为:不修改输入数组,返回一个有序子序列 -- 默认值: - - `comparer == null` 时使用 `Comparer.Default` - - 默认删除策略是 `RemovalCountStrategy.FloorHalf` - - 默认随机源是 `Random.Shared` -- 特别说明: - - 当输入长度 `<= 1` 时,直接返回输入数组引用 - - 当输入本身已经有序时,直接返回输入数组引用 - - 使用同一种随机源种子时,数组重载和列表重载会得到可复现的一致内容 - -`List` 重载: - -- 输入:`List values` -- 可选输入:`IComparer? comparer`、`RemovalCountStrategy removalStrategy`、`Random random` -- 输出:无返回值,结果直接写回原列表 -- 行为:原地随机删除元素,直到列表有序 -- 默认值: - - `comparer == null` 时使用 `Comparer.Default` - - 默认删除策略是 `RemovalCountStrategy.FloorHalf` - - 默认随机源是 `Random.Shared` - -## 异常 - -所有重载都可能出现: - -- `ArgumentNullException` - - `values == null` - -带 `random` 参数的重载还可能出现: - -- `ArgumentNullException` - - `random == null` - -带 `removalStrategy` 参数的重载还可能出现: - -- `ArgumentOutOfRangeException` - - `removalStrategy` 不是已定义值 - - 当前只接受以下取值: - - `RemovalCountStrategy.FloorHalf`,底层值为 `0` - - `RemovalCountStrategy.CeilingHalf`,底层值为 `1` - - 例如 `(RemovalCountStrategy)(-1)`、`(RemovalCountStrategy)99` 会触发该异常 - -默认比较器相关异常: - -- `ArgumentException` - - 当 `comparer == null`,且 `Comparer.Default` 无法比较 `T`,并且运行时确实需要比较时抛出 - - 不会触发该异常的情况:空输入、单元素输入 - -自定义比较器或随机源相关异常: - -- 比较器抛出的异常会直接向外传播 -- 随机源抛出的异常也会直接向外传播 -- 对数组重载,输入数组不会被修改 -- 对 `List` 重载,如果在处理中途抛出异常,列表可能已经被部分修改,且不会回滚 - -## 调用示例 - -```csharp -var values = new[] { 5, 1, 4, 4, 2, 3 }; -var result = ThanosSorter.PruneUntilSorted( - values, - comparer: null, - removalStrategy: RemovalCountStrategy.CeilingHalf, - random: new Random(12345)); - -// result 是 values 的一个有序子序列 -// values 保持不变 - -var list = new List { 3, 1, 2 }; -ThanosSorter.PruneUntilSorted( - list, - comparer: null, - removalStrategy: RemovalCountStrategy.FloorHalf, - random: new Random(2026)); -// list 被原地裁剪为一个有序子序列 -``` - -导航: [Home](Home) | [Getting Started](Getting-Started) | [Algorithm Overview](Algorithm-Overview) diff --git a/wiki/TrumpSort-Guide.md b/wiki/TrumpSort-Guide.md new file mode 100644 index 0000000..136f052 --- /dev/null +++ b/wiki/TrumpSort-Guide.md @@ -0,0 +1,24 @@ +# TrumpSort Guide + +`TrumpSort` 会对输入执行一次随机重排,不保证结果有序。 + +## 什么时候用 + +当你只想打乱顺序,而不是排序或过滤时可以用它。无论如何,先赢再说!用它的人每一天都会赢! + +## 示例 + +```csharp +var values = new[] { 1, 2, 3, 4, 5 }; +var result = TrumpSorter.ShuffleAndWin(values, new Random(2026)); +``` + +## 要点 + +1. 它只做一次 Fisher-Yates shuffle。 +2. 不删除元素,不改写元素值。 +3. 固定随机种子时结果可复现。 + +## 相关规范 + +[StrangeSort 开发规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSort%20%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md) diff --git a/wiki/TrumpSort-Reference.md b/wiki/TrumpSort-Reference.md deleted file mode 100644 index 385292f..0000000 --- a/wiki/TrumpSort-Reference.md +++ /dev/null @@ -1,92 +0,0 @@ -# TrumpSort Reference - -导航: [Home](Home) | [Getting Started](Getting-Started) | [Algorithm Overview](Algorithm-Overview) - -说明:本页是参考文档,不是公开行为契约来源;如有冲突,以 [StrangeSort 项目开发规范](https://github.com/yhcedpn/StrangeSort/blob/main/specs/StrangeSort%20%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md) 为准。 - -## 算法说明 - -`TrumpSort` 不是传统排序。它不会保证结果有序,而是对输入序列执行一次 Fisher-Yates 随机重排。 - -它的行为是: - -- 遍历序列尾部到头部的位置。 -- 对每个位置随机选择一个不超过当前位置的索引。 -- 交换这两个位置上的元素。 - -因此,输出结果与输入包含完全相同的元素多重集,只是顺序被随机打乱。 - -例如: - -- 输入:`[1, 2, 3, 4]` -- 可能输出:`[3, 1, 4, 2]` - -## 公共 API - -```csharp -public static T[] ShuffleAndWin(T[] values) -public static T[] ShuffleAndWin(T[] values, Random random) -public static void ShuffleAndWin(List values) -public static void ShuffleAndWin(List values, Random random) -``` - -## 输入与输出 - -数组重载: - -- 输入:`T[] values` -- 可选输入:`Random random` -- 输出:`T[]` -- 行为:不修改输入数组,返回一个新的随机排列结果数组 -- 默认值:`random` 未显式传入时使用 `Random.Shared` -- 特别说明: - - 返回数组长度与输入数组一致 - - 返回数组与输入数组包含相同的元素多重集 - - 即使输入为空数组或单元素数组,也会返回新的结果数组而不是原数组引用 - - 使用相同随机种子时,结果可复现 - -`List` 重载: - -- 输入:`List values` -- 可选输入:`Random random` -- 输出:无返回值,结果直接写回原列表 -- 行为:原地执行一次随机重排 -- 默认值:`random` 未显式传入时使用 `Random.Shared` -- 特别说明: - - 列表长度保持不变 - - 列表中的元素多重集保持不变 - - 使用相同随机种子时,结果可复现 - - 对相同输入使用相同随机种子时,数组重载和列表重载会得到一致内容 - -## 异常 - -所有重载都可能出现: - -- `ArgumentNullException` - - `values == null` - -带 `random` 参数的重载还可能出现: - -- `ArgumentNullException` - - `random == null` - -随机源相关异常: - -- 随机源自己抛出的异常会直接向外传播 -- 对数组重载,如果随机源在处理中抛出异常,输入数组不会被修改 -- 对 `List` 重载,如果随机源在处理中抛出异常,列表可能已经被部分修改,且不会回滚 - -## 调用示例 - -```csharp -var values = new[] { 1, 2, 3, 4, 5 }; -var result = TrumpSorter.ShuffleAndWin(values, new Random(2026)); -// result 是 values 的一个随机排列 -// values 保持不变 - -var list = new List { 1, 2, 3, 4, 5 }; -TrumpSorter.ShuffleAndWin(list, new Random(2026)); -// list 被原地随机重排 -``` - -导航: [Home](Home) | [Getting Started](Getting-Started) | [Algorithm Overview](Algorithm-Overview) diff --git a/wiki/_Sidebar.md b/wiki/_Sidebar.md index 0c51f4a..da6d084 100644 --- a/wiki/_Sidebar.md +++ b/wiki/_Sidebar.md @@ -1,8 +1,7 @@ - [Home](Home) -- [Getting Started](Getting-Started) -- [Algorithm Overview](Algorithm-Overview) -- [StalinSort Reference](StalinSort-Reference) -- [ThanosSort Reference](ThanosSort-Reference) -- [EpsteinSort Reference](EpsteinSort-Reference) -- [BrezhnevSort Reference](BrezhnevSort-Reference) -- [TrumpSort Reference](TrumpSort-Reference) +- [Quick Start](Quick-Start) +- [StalinSort Guide](StalinSort-Guide) +- [ThanosSort Guide](ThanosSort-Guide) +- [EpsteinSort Guide](EpsteinSort-Guide) +- [BrezhnevSort Guide](BrezhnevSort-Guide) +- [TrumpSort Guide](TrumpSort-Guide)