include missing spellings under length constraint

This commit is contained in:
David Allemang
2026-10-02 15:42:14 -04:00
parent be84f5b1bf
commit 8f2e2e0487
7 changed files with 89 additions and 52 deletions

View File

@@ -13,7 +13,7 @@ subsequent set of components.
#show raw.where(lang: "mc-diorama"): it => diorama(
autoplay: true,
loop: true,
radius: 5,
radius: 8,
theta: 160,
it.text,
)
@@ -108,15 +108,6 @@ t 20
p 0 0 0
```
#show raw.where(lang: "mc-diorama"): it => diorama(
autoplay: true,
loop: true,
radius: 5,
theta: 180,
phi: 0,
it.text,
)
```
prefix | BED -->
00 | A D G J ...
@@ -127,7 +118,7 @@ prefix | BED -->
#show raw.where(lang: "mc-diorama"): it => diorama(
autoplay: true,
loop: true,
radius: 9,
radius: 15,
phi: 30,
theta: 110,
speed: 0.4,

View File

@@ -1,8 +1,9 @@
"""Enumerate flattened redstone delay-chains for a given total delay."""
import argparse
from pprint import pprint
import sys
from collections import Counter
from collections import Counter, defaultdict
from functools import cache
from typing import NamedTuple
@@ -12,6 +13,13 @@ class Comp(NamedTuple):
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 = [
@@ -28,41 +36,29 @@ COMPONENTS = [
]
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:
yield from (c.blocks + rest for rest in _body(total - c.delay))
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):
out = []
for c in BODY:
def _body(remaining: int, order=ORDER):
out = defaultdict(list)
for c in order:
if c.delay > remaining:
continue
if remaining == c.delay:
out.append(c.blocks)
out[(c.signature,)].append(c.blocks)
else:
out.extend(c.blocks + rest for rest in _body(remaining - c.delay))
return tuple(out)
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():
@@ -71,15 +67,21 @@ def main():
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)
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)
counts = Counter(map(len, tileset))
print(len(tileset), "chains", file=sys.stderr)
for length in sorted(counts):
print(f"length {length} chains: {counts[length]}", file=sys.stderr)

View File

@@ -1,6 +1,6 @@
#import "/lib.typ": callout, diorama, warn
#show raw.where(block: true, lang: "mc-diorama"): it => diorama(orbit: false, it.text)
#show raw.where(block: true, lang: "mc-diorama"): it => diorama(orbit: false, radius: 7, it.text)
#title()

View File

@@ -1,10 +1,22 @@
- R3 - R1 - R1
- R3 - R1 - C
- R3 - C - R1
- R3 - C - C
- R2 R1 R1 - R1
- R2 R1 R1 - C
- R2 R1 - R1 R1
- R2 R1 C - R1
- R2 R1 C - C
- R2 R1 - C R1
- R2 R1 - C C
- R2 - R2 - R1
- R2 - R2 - C
- R2 - R1 R1 R1
- R2 C R1 - R1
- R2 C R1 - C
- R2 - R1 - R2
- R2 C - R1 R1
- R2 C C - R1
- R2 C C - C
- R2 C - C R1
- R2 C - C C
@@ -13,10 +25,14 @@
- R2 - C - R2
- R2 - C C R1
- R2 - C C C
- R1 R2 R1 - R1
- R1 R2 R1 - C
- R1 R2 - R1 R1
- R1 R2 C - R1
- R1 R2 C - C
- R1 R2 - C R1
- R1 R2 - C C
- R1 R1 R2 - R1
- R1 R1 R2 - C
- R1 R1 R1 R1 R1
- R1 R1 R1 R1 C
@@ -25,26 +41,33 @@
- R1 R1 R1 C C
- R1 R1 - R2 R1
- R1 R1 - R2 C
- R1 R1 - R1 R2
- R1 R1 C R1 R1
- R1 R1 C R1 C
- R1 R1 C - R2
- R1 R1 C C R1
- R1 R1 C C C
- R1 R1 - C R2
- R1 - R3 - R1
- R1 - R3 - C
- R1 - R2 R1 R1
- R1 - R2 R1 C
- R1 - R2 - R2
- R1 - R2 C R1
- R1 - R2 C C
- R1 - R1 R2 R1
- R1 C R2 - R1
- R1 C R2 - C
- R1 - R1 R1 R2
- R1 C R1 R1 R1
- R1 C R1 R1 C
- R1 C R1 - R2
- R1 C R1 C R1
- R1 C R1 C C
- R1 - R1 - R3
- R1 C - R2 R1
- R1 C - R2 C
- R1 C - R1 R2
- R1 C C R1 R1
- R1 C C R1 C
- R1 C C - R2
@@ -56,10 +79,14 @@
- R1 - C R1 R2
- R1 - C - R3
- R1 - C C R2
- C R2 R1 - R1
- C R2 R1 - C
- C R2 - R1 R1
- C R2 C - R1
- C R2 C - C
- C R2 - C R1
- C R2 - C C
- C R1 R2 - R1
- C R1 R2 - C
- C R1 R1 R1 R1
- C R1 R1 R1 C
@@ -68,26 +95,33 @@
- C R1 R1 C C
- C R1 - R2 R1
- C R1 - R2 C
- C R1 - R1 R2
- C R1 C R1 R1
- C R1 C R1 C
- C R1 C - R2
- C R1 C C R1
- C R1 C C C
- C R1 - C R2
- C - R3 - R1
- C - R3 - C
- C - R2 R1 R1
- C - R2 R1 C
- C - R2 - R2
- C - R2 C R1
- C - R2 C C
- C - R1 R2 R1
- C C R2 - R1
- C C R2 - C
- C - R1 R1 R2
- C C R1 R1 R1
- C C R1 R1 C
- C C R1 - R2
- C C R1 C R1
- C C R1 C C
- C - R1 - R3
- C C - R2 R1
- C C - R2 C
- C C - R1 R2
- C C C R1 R1
- C C C R1 C
- C C C - R2

View File

@@ -1,7 +1,11 @@
- R2 R1 - R1
- R2 R1 - C
- R2 - R1 R1
- R2 C - R1
- R2 C - C
- R2 - C R1
- R2 - C C
- R1 R2 - R1
- R1 R2 - C
- R1 R1 R1 R1
- R1 R1 R1 C
@@ -10,12 +14,14 @@
- R1 R1 C C
- R1 - R2 R1
- R1 - R2 C
- R1 - R1 R2
- R1 C R1 R1
- R1 C R1 C
- R1 C - R2
- R1 C C R1
- R1 C C C
- R1 - C R2
- C R2 - R1
- C R2 - C
- C R1 R1 R1
- C R1 R1 C
@@ -24,6 +30,7 @@
- C R1 C C
- C - R2 R1
- C - R2 C
- C - R1 R2
- C C R1 R1
- C C R1 C
- C C - R2

View File

@@ -104,7 +104,7 @@ the number of general chains grows quickly:
})
html.tr({
html.td[14gt]
html.td[4497]
html.td[4997]
html.td[128]
})
})
@@ -137,22 +137,22 @@ signal flows right-to-left).
html.tbody({
html.tr({
html.td[8gt, 4 block]
html.td(tileset("tileset-8-4.txt", summary: [32]))
html.td(tileset("tileset-8-4.txt", summary: [39]))
html.td[16]
})
html.tr({
html.td[10gt, 5 block]
html.td(tileset("tileset-10-5.txt", summary: [101]))
html.td(tileset("tileset-10-5.txt", summary: [135]))
html.td[32]
})
html.tr({
html.td[12gt, 6 block]
html.td[331]
html.td[481]
html.td[64]
})
html.tr({
html.td[14gt, 7 block]
html.td[1114]
html.td[1740]
html.td[128]
})
})

View File

@@ -19,6 +19,7 @@ set* is a system of constructing tile sequences that enforces a particular globa
autoplay: true,
theta: 160,
phi: 20,
radius: 6,
it.text,
)
@@ -86,7 +87,8 @@ Consider this 4gt tileset.
theta: 90,
phi: 90,
speed: 0.33,
radius: 8,
radius: 16,
aspect: 2,
orbit: false,
it.text,
)
@@ -269,6 +271,7 @@ bit-length. For example, the 8-bit tileset for `150` is:
phi: 90,
speed: 0.33,
radius: 8,
aspect: 8,
orbit: false,
it.text,
)