16-color palette with least-used assignment

The Python diss put pink on five different families: 18 families, 12
colors, and the assignment kept grabbing low indices so one hue piled
up. Now 16 colors (added cyan, amber, lavender, emerald) and each
family takes the globally least-used non-adjacent color, so hues
spread evenly — no color repeats more than twice on a dense page.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-07 20:31:52 -04:00
parent 411681d0a0
commit e6b86a8a88
2 changed files with 9 additions and 4 deletions
+8 -4
View File
@@ -53,7 +53,7 @@ def g2p_phones(word: str) -> str | None:
WORD_RE = re.compile(r"[A-Za-z][A-Za-z']*")
DIGITS = re.compile(r"\d")
COLORS = 12 # matches --r0..--r11 in the stylesheet
COLORS = 16 # matches --r0..--r15 in the stylesheet
#: function words too common to flag as internal rhymes
#: (they still count when they end a line)
@@ -1193,12 +1193,16 @@ def analyze(draft: Draft):
grown = [s | {l - 1 for l in s} | {l + 1 for l in s} for s in line_sets]
groups_out = []
chosen: list[int] = []
usage = [0] * COLORS
for gid, g in enumerate(raw_groups):
for t in g["toks"]:
t["gid"] = gid
used = {chosen[j] for j in range(gid) if grown[j] & line_sets[gid]}
color = next((c for c in range(COLORS) if c not in used),
gid % COLORS)
blocked = {chosen[j] for j in range(gid) if grown[j] & line_sets[gid]}
# among non-adjacent colors, take the globally least-used one, so
# hues spread evenly instead of piling on the low indices
avail = [c for c in range(COLORS) if c not in blocked] or list(range(COLORS))
color = min(avail, key=lambda c: (usage[c], c))
usage[color] += 1
chosen.append(color)
groups_out.append({"id": gid, "color": color, "slant": g["slant"]})
+1
View File
@@ -28,6 +28,7 @@
--r0:#e8814a; --r1:#4ea3e8; --r2:#6fd08c; --r3:#d46fb8;
--r4:#e8c54a; --r5:#9b7ce8; --r6:#e85a5a; --r7:#46cabf;
--r8:#c0d44e; --r9:#ee5d8f; --r10:#6f8bf2; --r11:#8fe85a;
--r12:#5ad8d8; --r13:#e0985a; --r14:#b88ce8; --r15:#56c878;
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }