mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-10 20:07:18 +01:00
Toolbox property meanings no longer name an entry or operator
The incomplete-list note shows meanings before code, so "a ^ x ^ x = a" or "x & -x" handed over the answer. Rewrite the six leaking meanings plus two that said "sorted", and pin it with test_no_property_meaning_names_an_entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PjvF5DZG9JduSBYKxqyysi
This commit is contained in:
parent
6343499ed1
commit
2d2d8a41f8
@ -47,6 +47,20 @@ def test_names_and_aliases_are_unique() -> None:
|
||||
assert len(names) == len(set(names))
|
||||
|
||||
|
||||
def test_no_property_meaning_names_an_entry() -> None:
|
||||
# The incomplete-list note shows meanings to kuhy before code; one that
|
||||
# says "a ^ x ^ x = a" hands over the answer it is asking him to find.
|
||||
box = toolbox.load()
|
||||
names = {n.casefold() for e in box["entries"] for n in [e["name"], *e["aliases"]]}
|
||||
leaks = {
|
||||
prop: hit
|
||||
for prop, meaning in box["properties"].items()
|
||||
for hit in names | {"^", "&", "sort"}
|
||||
if hit in meaning.casefold()
|
||||
}
|
||||
assert leaks == {}
|
||||
|
||||
|
||||
def test_no_name_is_a_cluster_problem_title() -> None:
|
||||
# The leak bounce fires on any entry name or alias before the first code
|
||||
# event, so one that is a problem's own title bounces its restatement.
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
{
|
||||
"properties": {
|
||||
"self-inverse": "applying the same value twice undoes it: a ^ x ^ x = a",
|
||||
"self-inverse": "applying the same value twice undoes it: combine a with x, then with x again, and you are back at a",
|
||||
"invertible": "every step has a known undo: a + x - x = a",
|
||||
"commutative": "operand order does not matter: a + b = b + a",
|
||||
"associative": "grouping does not matter, so a running fold works: (a + b) + c = a + (b + c)",
|
||||
"identity element": "a neutral value e with a op e = a: 0 for + ^ gcd, -Infinity for max, +Infinity for min",
|
||||
"identity element": "a neutral value e that leaves anything unchanged when combined with it (a op e = a)",
|
||||
"idempotent": "combining a value with itself changes nothing: max(a, a) = a",
|
||||
"selective": "the result is always one of the operands: max(a, b) is a or b",
|
||||
"divides its inputs": "the result divides every operand, so folding more values can only shrink it",
|
||||
"works per bit": "each bit position is computed independently of the others",
|
||||
"carries between bits": "bit positions interact: a carry moves into the next position",
|
||||
"cancels any k-fold repeat": "a value that occurs exactly k times leaves no trace, for any chosen k",
|
||||
"isolates one bit": "keeps a single set bit and clears the rest: x & -x keeps the lowest one",
|
||||
"isolates one bit": "keeps a single set bit of a number and clears all the others",
|
||||
"O(1) extra space": "a fixed number of variables besides the input, however large the input",
|
||||
"single pass": "reads the input once, front to back",
|
||||
"O(1) lookup": "asks 'seen x?' or 'what is stored for x?' in (expected) constant time",
|
||||
@ -23,23 +23,23 @@
|
||||
"from both ends": "the two indexes start at opposite ends and move toward each other",
|
||||
"window moves right": "both indexes move left to right; the range between them is the current window",
|
||||
"monotone condition": "only correct when validity changes once as a range grows (no negatives in a sum)",
|
||||
"needs sorted input": "only correct once the input is sorted",
|
||||
"needs sorted input": "only correct once the input is in ascending (or descending) order",
|
||||
"O(n log n) time": "costs about n log n comparisons, more than one linear pass",
|
||||
"makes equal values adjacent": "afterwards equal (and close) values sit next to each other",
|
||||
"O(log n) per query": "each question halves the remaining range, so it costs about log n steps",
|
||||
"range query in O(1)": "after O(n) setup, any contiguous range's total is one subtraction",
|
||||
"needs an inverse": "only works over an operation that can be undone (+ with -, ^ with ^); max has none",
|
||||
"needs an inverse": "only works over an operation whose effect can be undone afterwards; one that loses information has none",
|
||||
"keeps every prefix": "stores all n prefix values, so any (l, r) range can be asked later",
|
||||
"handles negatives": "stays correct when values can be negative (a sliding window does not)",
|
||||
"handles negatives": "stays correct when values can be negative, where a grow/shrink-by-running-total approach breaks",
|
||||
"needs a majority": "only correct when one value occurs more than n/2 times",
|
||||
"last-in-first-out": "the most recently added element is the first one taken out",
|
||||
"next-greater lookup": "for every element, finds the nearest later element that is larger (flip for smaller)",
|
||||
"amortized O(n)": "each element is added and removed at most once, so the total work is linear",
|
||||
"overlaps become adjacent": "after sorting by start, every interval that overlaps the current group comes right after it",
|
||||
"overlaps become adjacent": "once items are put in order of their start, everything overlapping the current group comes right after it",
|
||||
"earliest end first": "choosing the interval that ends first leaves the most room for the rest",
|
||||
"greedy": "commits to the locally best choice and never revisits it",
|
||||
"O(log n) push and pop-min": "insert and remove-the-smallest each cost about log n; flip the comparison for largest",
|
||||
"partial order": "only the top element is guaranteed to be in place; the rest is not sorted"
|
||||
"partial order": "only the top element is guaranteed to be in place; the rest is in no particular order"
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user