fix chains.py asset

This commit is contained in:
2026-10-02 19:59:51 -04:00
parent 8f2e2e0487
commit 1c95f21d0f
2 changed files with 1 additions and 1 deletions

91
public/chains.py Normal file
View File

@@ -0,0 +1,91 @@
"""Enumerate flattened redstone delay-chains for a given total delay."""
import argparse
from pprint import pprint
import sys
from collections import Counter, defaultdict
from functools import cache
from typing import NamedTuple
class Comp(NamedTuple):
delay: int
priority: int
blocks: tuple
@property
def signature(self):
return (self.priority, -self.delay)
def __repr__(self):
return "C" + repr(self.blocks)
# Insert custom subcomponents here, e.g. Comp(6, -1, ("-", "R2", "C")).
COMPONENTS = [
Comp(8, -3, ("R4",)),
Comp(6, -3, ("R3",)),
Comp(4, -3, ("R2",)),
Comp(2, -3, ("R1",)),
Comp(8, -1, ("-", "R4")),
Comp(6, -1, ("-", "R3")),
Comp(4, -1, ("-", "R2")),
Comp(2, -1, ("C",)),
Comp(2, -1, ("-", "R1")),
Comp(2, 0, ("-", "C")),
]
assert all(c.blocks for c in COMPONENTS), "components must have >= 1 block"
ORDER = tuple(sorted(COMPONENTS, key=lambda c: (c.priority, -c.delay)))
START = tuple([c for c in ORDER if c.blocks[0] == "-"])
@cache
def _body(remaining: int, order=ORDER):
out = defaultdict(list)
for c in order:
if c.delay > remaining:
continue
if remaining == c.delay:
out[(c.signature,)].append(c.blocks)
else:
for signature, rests in _body(remaining - c.delay).items():
for rest in rests:
out[(c.signature, *signature)].append(c.blocks + rest)
return dict(out)
def chains(total: int):
return _body(total, START)
def main():
ap = argparse.ArgumentParser(description=__doc__)
ap.add_argument("total", type=int, help="total delay to enumerate")
ap.add_argument("count", nargs="*", type=int, help="total element count")
args = ap.parse_args()
spellings = chains(args.total)
counts = Counter(len(opt) for opts in spellings.values() for opt in opts)
tileset = []
for sig in sorted(spellings):
opts = spellings[sig]
if args.count:
opts = [opt for opt in opts if len(opt) in args.count]
if opts:
tileset.append(min(opts, key=len))
for chain in tileset:
print(*chain)
print(len(tileset), "chains", file=sys.stderr)
for length in sorted(counts):
print(f"length {length} chains: {counts[length]}", file=sys.stderr)
if __name__ == "__main__":
main()