83 lines
2.0 KiB
Python
83 lines
2.0 KiB
Python
"""Enumerate flattened redstone delay-chains for a given total delay."""
|
|
|
|
import argparse
|
|
import sys
|
|
from typing import NamedTuple
|
|
|
|
|
|
class Comp(NamedTuple):
|
|
delay: int
|
|
priority: int
|
|
blocks: tuple
|
|
|
|
|
|
# Append 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"
|
|
_ORDERED = sorted(COMPONENTS, key=lambda c: (c.priority, -c.delay))
|
|
|
|
|
|
def _canon(comps):
|
|
seen = {}
|
|
for c in comps:
|
|
seen.setdefault((c.priority, c.delay), c)
|
|
return list(seen.values())
|
|
|
|
|
|
HEAD = _canon([c for c in _ORDERED if c.blocks[0] == "-"])
|
|
BODY = _canon(_ORDERED)
|
|
|
|
|
|
def chains(total: int):
|
|
for c in HEAD:
|
|
if c.delay > total:
|
|
continue
|
|
if total == c.delay:
|
|
yield c.blocks
|
|
else:
|
|
for rest in _body(total - c.delay):
|
|
yield c.blocks + rest
|
|
|
|
|
|
def _body(remaining: int):
|
|
for c in BODY:
|
|
if c.delay > remaining:
|
|
continue
|
|
if remaining == c.delay:
|
|
yield c.blocks
|
|
else:
|
|
for rest in _body(remaining - c.delay):
|
|
yield c.blocks + rest
|
|
|
|
|
|
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()
|
|
|
|
tileset = chains(args.total)
|
|
if args.count:
|
|
tileset = (chain for chain in tileset if len(chain) in args.count)
|
|
tileset = list(tileset)
|
|
|
|
for chain in tileset:
|
|
print(*chain)
|
|
print(len(tileset), "chains", file=sys.stderr)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|