This commit is contained in:
khodowany
2026-10-04 15:51:18 -05:00
parent 405066eb43
commit f234dd6d51
54 changed files with 2104 additions and 330 deletions
+12 -3
View File
@@ -3,6 +3,7 @@ from __future__ import annotations
import dataclasses
import pathlib
import types
import functools
import generator.solo.policy
@@ -13,6 +14,7 @@ import generator.musicxml
class Sequence:
id: str
steps: tuple[int, ...]
@functools.lru_cache(maxsize=32768)
def offsets(self) -> tuple[int, ...]:
result = [0]
for step in self.steps:
@@ -26,12 +28,14 @@ class Sequence:
class Path:
steps: tuple[int, ...]
sources: tuple[str, ...]
@functools.lru_cache(maxsize=32768)
def offsets(self):
result = [0]
for step in self.steps:
result.append(result[-1] + step)
return tuple(result)
@functools.lru_cache(maxsize=32768)
def family(steps):
if not steps or all(s == 0 for s in steps):
return 'repeated'
@@ -47,14 +51,19 @@ def family(steps):
def diverse(items, rank, category, limit):
"""Round-robin eligible musical families before a destructive cutoff."""
groups = {}
for item in sorted(items, key=rank):
groups.setdefault(category(item), []).append(item)
# Rank once: hashing full event provenance and classifying interval paths
# used to be repeated for every retained layer. Preserve stable tie order.
decorated = sorted(((rank(item), i, item) for i,item in enumerate(items)),key=lambda v:v[:2])
for value in decorated:
groups.setdefault(category(value[2]), []).append(value)
result, index = [], 0
while len(result) < limit:
layer = [values[index] for values in groups.values() if len(values) > index]
if not layer:
break
result.extend(sorted(layer, key=rank)[:limit - len(result)])
# Equal ranks retain category insertion order, just as the original stable
# layer sort did; the input index is only for the initial sort.
result.extend(v[2] for v in sorted(layer,key=lambda v:v[0])[:limit-len(result)])
index += 1
return tuple(result)