I generalised the recipe to arbitrarily large clocks. Here is an incremental recipe for the 6th element of the family:
A script that generates long clocks syntheses (relies on Shinjuku and lifelib) :
Code: Select all
# synthesise_long_clocks.py
# vilc, 2024
# Takes two parameters : the size of the clock and a file name to store the recipe
# Note that this program considers that clock has size 0, cha cha size 1, etc.
# size <= 2 is unsupported, as cheaper specific recipes are known.
from sys import argv
from shinjuku import lt
from shinjuku.transcode import realise_comp, encode_comp, decode_comp
from shinjuku.checks import check_single_line
from shinjuku.search import slock
# Maximum number of ticks that a component may take before stabilising
MAX_TIME = 1000
#-------------------------------------------
xs20_recipe = [
lt.pattern("""x = 19, y = 17, rule = B3/S23
2bo$obo$b2o9$18bo$16b2o$9bobo5b2o$5bo3b2o$6bo3bo$4b3o!"""),
lt.pattern("""x = 64, y = 64, rule = B3/S23
61bobo$61b2o$62bo13$20b2o$19bobo$14bobo2b2o$15b2o$15bo$28b2o$28b2o40$b
2o$obo$2bo!""")
]
extend_wick_recipe = [
lt.pattern("""x = 20, y = 26, rule = B3/S23
15bobo$15b2o$16bo2$17b2o$7bo9bobo$6bobo8bo$4bob2o$3bobo9bo$3bobo8b2o$
4bo9bobo7$bo$b2o8b3o$obo8bo$12bo2$5b3o$5bo11bo$6bo9b2o$16bobo!""")(1, -10),
lt.pattern("""x = 9, y = 15, rule = B3/S23
6bo$5bobo$3bobobo$2bobobo$2bobo$3bobo$4bo$8bo$6b2o$7b2o3$b2o4bo$obo4b
2o$2bo3bobo!""")(2, -5),
lt.pattern("""x = 12, y = 12, rule = B3/S23
5bo$4bobo$2bobobo$bobobo$bobo5bo$2bobo4bobo$4bo4b2o$4b2o2$b2o5b2o$obo
4b2o$2bo6bo!""")(3, -5),
lt.pattern("""x = 12, y = 9, rule = B3/S23
9bobo$9b2o$bo8bo$obo$obo$bo6b2o$bobo3b2o$2bobo4bo$3bo!""")(7, -7),
lt.pattern("""x = 135, y = 107, rule = B3/S23
12bo$10bobo$4bobo4b2o$5b2o$5bo88bo$92b2o$93b2o41$44bo$43bobo$43bobo$
44bob2o$44bobobo81bo$45bo2bo82bo$46b2o81b3o4$128bo$128b2o2b3o$127bobo
2bo$133bo39$3o$2bo$bo3$3b2o$4b2o$3bo!""")(-36, -52),
lt.pattern("""x = 23, y = 31, rule = B3/S23
2bo$obo$b2o$19bo$19bobo$12bobo4b2o$8bo3b2o$6bobo4bo$7b2o6$6bo$5bobo9bo
$5bobo9bobo$6bob2o7b2o$6bobo2bo$7bo2b2o3$19b2o$18b2o$20bo4$21b2o$20b2o
$22bo!""")(2, -19),
lt.pattern("""x = 11, y = 12, rule = B3/S23
5bo$6b2o$5b2o$9b2o$8b2o$10bo$bo3b2o$obobobo$obob2o$bobo$bobo$2bo!""")(7, -11),
]
beehives_to_R_beehives_comp = lt.pattern("""x = 16, y = 17, rule = B3/S23
2bo$obo$b2o$13bo$13bobo$13b2o$2bo3bobo$obo4b2o$b2o4bo6$7bo3bo$6bobobob
o$6bobobobo!""")(-3, -19)
boat_to_beehive_and_bit = lt.pattern("""x = 29, y = 15, rule = B3/S23
28bo$26b2o$15bobo9b2o$9bobo4b2o$10b2o4bo$10bo2$2bo$obo$b2o12bo10bo$13b
2o10bo$9bobo2b2o9bo$10b2o11b2o$10bo11bobo$23bo!""")(-22, -14)
beehive_to_boat_and_bit = [
lt.pattern("""x = 27, y = 22, rule = B3/S23
15bobobobo$15bobobobo$16bo3bo6$20bo$20b2o$14b3o2bobo$16bo7b3o$15bo8bo$
25bo6$3o$2bo$bo!""")(-15, -2),
lt.pattern("""x = 9, y = 8, rule = B3/S23
7bo$6bobo$7bo2$2o$b2o2bo$o3b2o$4bobo!""")(-6, -3)
]
grow_R_beehive = [
lt.pattern("""x = 17, y = 14, rule = B3/S23
o$b2o8bo$2o7bobo$10b2o3bo$14bo$14b3o6$11b2o$11bobo$11bobo!""")(-8, -16),
lt.pattern("""x = 47, y = 34, rule = B3/S23
44bo$44bobo$44b2o2$2bo$obo$b2o6$28bo$29b2o4bo$20bo7b2o4bo$21bo12b3o$
19b3o15$19b2o$19bobo$19bobo!""")(-16, -36),
lt.pattern("""x = 15, y = 21, rule = B3/S23
12bo$11bo$11b3o3$o8bo$b2o7bo$2o6b3o2$3bo8bobo$4b2o6b2o$3b2o8bo7$6b2o$
5bobo$5bobo!""")(-2, -23),
lt.pattern("""x = 19, y = 25, rule = B3/S23
2bo$3bo$b3o$9bo$10b2o$9b2o2$17bo$16bo$2bo13b3o$obo$b2o10$7bo$6bobob2o$
6bobobobo$6bobobobo!""")(-7, -27),
lt.pattern("""x = 62, y = 35, rule = B3/S23
21bo$19bobo$20b2o2$53bo5bobo$2bo50bobo3b2o$obo50b2o5bo$b2o13bobo$17b2o
$17bo7bo$26b2o$25b2o$48bo4bo$47bo4bo$4bo25bo16b3o2b3o$5bo23bo$3b3o23b
3o6$18bo$19bo$17b3o7bo$26bo$26b3o5$37b2o$36bobo$32b2o2bobo$32bobobobo!""")(-37, -37),
lt.pattern("""x = 19, y = 25, rule = B3/S23
16bo$15bo$15b3o$9bo$7b2o$8b2o2$bo$2bo$3o13bo$16bobo$16b2o10$11bo$7b2ob
obo$6bobobobo$6bobobobo!""")(-3, -27)
]
add_excrescence = [
lt.pattern("""x = 23, y = 34, rule = B3/S23
7bo$5bobo$6b2o7$9bo$10bo$2bo5b3o$obo$b2o18bo$20bo$20b3o4$3bo$bobo2bobo
$2b2o2b2o$7bo9$18bo$17bobo$17bobo!""")(-14, -37),
lt.pattern("""x = 42, y = 21, rule = B3/S23
19bo$20b2o19bo$2bo16b2o18b2o$obo37b2o$b2o$16bo$17b2o$11bo4b2o$9bobo15b
o$10b2o14bo$19bo6b3o$19bobo$19b2o6$18bo$17bobo$18bo!""")(-18, -28),
lt.pattern("""x = 29, y = 21, rule = B3/S23
27bo$26bo$26b3o4$25bo$25bobo$25b2o$11bobo$6bobo2b2o$6b2o4bo$7bo$o$b2o$
2o4$15b2o$14bobo!""")(-12, -30)
]
add_snake = lt.pattern("""x = 18, y = 16, rule = B3/S23
12bo$12bobo$12b2o$obo3bo$b2o4bo$bo3b3o3bobo$11b2o$12bo5$13b2ob2o$14bob
2o$13bo$12bo!""")(-12, -23)
add_snake_side_activation = lt.pattern("""x = 15, y = 16, rule = B3/S23
2bo$obo$b2o$8bo3bobo$7bo4b2o$bobo3b3o3bo$2b2o$2bo5$5bo$4bobo$4bobo$5bo!""")(-1, -14)
#-------------------------------------------
activate_snake = lt.pattern("""x = 5, y = 7, rule = B3/S23
bo$2bo$3o3$b2obo$bob2o!""")(-7, -21)
activate_top = lt.pattern("""x = 20, y = 19, rule = B3/S23
3bobo$4b2o$4bo2$17bobo$2bo14b2o$obo15bo$b2o9$10b2o$9bobo$9bobo!""")(-8, -21)
activate_side = [
lt.pattern("""x = 20, y = 27, rule = B3/S23
6bobo$7b2o$7bo3$obo$b2o$bo3$18bo$17bobo$17bobo$18bo3$5b2o$6b2o7bob2o$
5bo9b2obo4$7b3o$9bo$2b2o4bo$3b2o$2bo!""")(-17, -13),
lt.pattern("""x = 20, y = 30, rule = B3/S23
6bobo$7b2o$7bo3$obo$b2o$bo3$18bo$17bobo$17bobo$18bo3$5b2o$6b2o$5bo3$7b
2o$8b2o$7bo4$2b3o$4bo$3bo!""")(-17, -13),
lt.pattern("""x = 14, y = 27, rule = B3/S23
4bo$5b2o$4b2o2$o$b2o$2o7$12bo$11bobo$11bobo$12bo8$b2o$2b2o$bo!""")(-11, -16),
lt.pattern("""x = 14, y = 29, rule = B3/S23
4bo$5b2o$4b2o2$o$b2o$2o5$bo$2b2o$b2o9bo$11bobo$11bobo$12bo10$5b2o$6b2o
$5bo!""")(-11, -16)
]
cleanup_side_1_mod_4 = lt.pattern("""x = 12, y = 31, rule = B3/S23
bo$2bo$3o17$10b2o$11bo$10bo$9bo$10b2o4$10bo$9bobo$9bobo$10bo!""")(-9, -30)
cleanup_side_1_mod_4_2 = lt.pattern("""x = 21, y = 20, rule = B3/S23
obo$b2o$bo14$19bo$18bobo$18bobo$19bo!""")(-18, -19)
cleanup_side_1_mod_4_3 = lt.pattern("""x = 4, y = 38, rule = B3/S23
bo$obo$obo$bo32$b3o$3bo$2bo!""")(0, -3)
cleanup_side_0_mod_4 = lt.pattern("""x = 13, y = 22, rule = B3/S23
11bo$10bobo$10bobo$11bo16$3o$2bo$bo!""")(-10, -3)
cleanup_side_0_mod_4_2 = lt.pattern("""x = 30, y = 49, rule = B3/S23
19bo$20bo$18b3o29$28bo$27bobo$27bobo$28bo12$3o$2bo$bo!""")(-27, -34)
cleanup_side_0_mod_4_3 = lt.pattern("""x = 4, y = 43, rule = B3/S23
2bo$3bo$b3o37$bo$obo$obo$bo!""")(0, -42)
cleanup_side_0_mod_4_4 = lt.pattern("""x = 4, y = 37, rule = B3/S23
bo$obo$obo$bo31$2b2o$bobo$3bo!""")(0, -3)
cleanup_side_2_mod_4 = lt.pattern("""x = 18, y = 39, rule = B3/S23
4bo$5bo$3b3o17$16bo$15bobo$15bobo$16bo14$3o$2bo$bo!""")(-15, -22)
cleanup_side_2_mod_4_2 = lt.pattern("""x = 7, y = 75, rule = B3/S23
5bo$6bo$4b3o35$bo$obo$obo$bo32$b3o$3bo$2bo!""")(0, -40)
cleanup_side_3_mod_4 = lt.pattern("""x = 15, y = 44, rule = B3/S23
bo$2bo$3o17$13bo$12bobo$12bobo$13bo19$2b2o$3b2o$2bo!""")(-12, -22)
cleanup_side_3_mod_4_2 = lt.pattern("""x = 18, y = 73, rule = B3/S23
16bo$17bo$15b3o35$12bo$11bobo$11bobo$12bo26$9bo$9b2o$8bobo2$3o$2bo$bo!""")(-11, -40)
cleanup_top = lt.pattern("""x = 71, y = 22, rule = B3/S23
69bo$bo66bo$2bo65b3o$3o13$42b2ob2o$24b2ob2o13b2obo$25bob2o6b2o9bo$24bo
9bobo2bo7bo$23bo7bo2bobobobo3b3o$24b3o3bobobobobobo2bo!""")(-33, -23)
destroy_beehive_and_boat = lt.pattern("""x = 9, y = 15, rule = B3/S23
6bo$6bobo$6b2o9$b2o$o2bo2b2o$b2o2bobo$6bo!""")(-35, -10)
#-------------------------------------------
cleanups = [
None, None, None,
# 3
lt.pattern("""x = 19, y = 42, rule = B3/S23
16bobo$17b2o$17bo3$15bo$13bobo$14b2o$8bobo$9b2o$9bo2$4bo$5b2o$4b2o5$5b
o$6b2o$5b2o9bo$15bobo$15bobo$16bo10$9b2o$10b2o$9bo$3o13bo$2bo13b2o$bo
7b2o4bobo$10b2o$9bo!""")(-15, -24),
# 4
lt.pattern("""x = 23, y = 23, rule = B3/S23
2bo$obo$b2o17$bobo17bo$2b2o16bobo$2bo17bobo$21bo!""")(-20, -22),
# 5
lt.pattern("""x = 29, y = 46, rule = B3/S23
bo$2bo$3o21$27bo$26bobo$26bobo$27bo17$7b3o$9bo$8bo!""")(-26, -26),
# 6
lt.pattern("""x = 26, y = 33, rule = B3/S23
23bobo$23b2o$24bo23$16bo$15bobo$15bobo$16bo2$bo$2bo$3o!""")(-15, -28),
# 7
lt.pattern("""x = 22, y = 53, rule = B3/S23
bo$2bo$3o$8bo$6bobo$7b2o21$17bo$16bobo$16bobo$17bo14$7b2o$8b2o$7bo5$
19b3o$21bo$20bo!""")(-16, -29),
# 8
lt.pattern("""x = 26, y = 42, rule = B3/S23
19bo$20b2o$19b2o25$24bo$23bobo$23bobo$24bo9$b2o$obo$2bo!""")(-23, -30),
# 9
lt.pattern("""x = 22, y = 69, rule = B3/S23
8bo$9bo$7b3o17$bo$2bo$3o12$20bo$19bobo$19bobo$20bo30$8b3o$10bo$9bo!""")(-19, -36),
# 10
lt.pattern("""x = 10, y = 55, rule = B3/S23
3bobo$4b2o$4bo25$8bo$7bobo$7bobo$8bo22$bo$b2o$obo!""")(-7, -30),
# 11
lt.pattern("""x = 17, y = 64, rule = B3/S23
9bobo$10b2o$10bo11$bo$2bo$3o17$13bo$12bobo$12bobo$13bo21$2b3o$4bo$3bo
3$15bo$15b2o$14bobo!""")(-12, -35),
# 12
lt.pattern("""x = 52, y = 77, rule = B3/S23
2bo$obo$b2o42$50bo$49bobo$49bobo$50bo14$21b3o$23bo$22bo11$49b2o$50b2o$
49bo!""")(-49, -47),
# 13
lt.pattern("""x = 41, y = 79, rule = B3/S23
bo$2bo$3o46$39bo$38bobo$38bobo$39bo25$28b2o$27bobo$29bo!""")(-38, -51),
# 14
lt.pattern("""x = 14, y = 61, rule = B3/S23
5bo$3bobo$4b2o28$12bo$11bobo$11bobo$12bo25$b2o$obo$2bo!""")(-11, -33),
# 15
lt.pattern("""x = 18, y = 67, rule = B3/S23
9bo$7bobo$8b2o28$16bo$15bobo$15bobo$16bo18$3o$2bo$bo11$11b3o$13bo$12bo!""")(-15, -33),
# 16
lt.pattern("""x = 33, y = 70, rule = B3/S23
bo$2bo$3o$16bo$17bo$15b3o25$25bo$24bobo$24bobo$25bo14$b2o$2b2o$bo7$20b
o$20b2o$19bobo9$30b3o$32bo$31bo!""")(-24, -33),
# 17
lt.pattern("""x = 22, y = 44, rule = B3/S23
bo$2bo$3o12$20bo$19bobo$19bobo$20bo24$11b3o$13bo$12bo!""")(-19, -17),
# 18
lt.pattern("""x = 7, y = 73, rule = B3/S23
6bo$4bobo$5b2o34$bo$obo$obo$bo31$2b2o$bobo$3bo!""")(0, -39),
# 19
lt.pattern("""x = 25, y = 95, rule = B3/S23
21bo$22bo$20b3o33$23bo$22bobo$22bobo$23bo31$16b3o$18bo$17bo21$3o$2bo$bo!""")(-22, -38),
# 20
lt.pattern("""x = 13, y = 78, rule = B3/S23
11bo$12bo$10b3o37$4bo$3bobo$3bobo$4bo33$bo$b2o$obo!""")(-3, -42),
# 21
lt.pattern("""x = 17, y = 82, rule = B3/S23
15bo$16bo$14b3o39$7bo$6bobo$6bobo$7bo25$3o$2bo$bo8$10b3o$12bo$11bo!""")(-6, -44),
# 22
lt.pattern("""x = 6, y = 83, rule = B3/S23
4bo$5bo$3b3o39$2bo$bobo$bobo$2bo36$3o$2bo$bo!""")(-1, -44),
# 23
lt.pattern("""x = 27, y = 75, rule = B3/S23
21bo$22bo$20b3o39$19bo$18bobo$18bobo$19bo19$3o$2bo$bo7$25b2o$24bobo$
26bo!""")(-18, -44),
# 24
lt.pattern("""x = 3, y = 37, rule = B3/S23
bo$obo$obo$bo31$3o$2bo$bo!""")(0, -3)
]
#-------------------------------------------
def apply_comp(pattern, comp, x, y, transf="identity", verbose=False):
pattern += comp(transf, x, y)
if verbose:
print(pattern.rle_string())
return encode_comp(pattern), pattern[MAX_TIME]
def apply_recipe(pattern, recipe, x, y, transf="identity", verbose=False):
lines = []
for comp in recipe:
line, pattern = apply_comp(pattern, comp, x, y, transf, verbose)
lines.append(line)
return lines, pattern
def synthesise_beehives_wick(size):
current_pattern = lt.pattern("xs20_2lm88gz122dl8")("rot90")
lines = [encode_comp(line) for line in xs20_recipe]
for i in range(size - 1):
new_lines, current_pattern = apply_recipe(current_pattern, extend_wick_recipe, i * 4, 0)
lines += new_lines
return lines, current_pattern
def beehives_to_R_beehives(size, current_pattern):
lines = []
num = (size // 2) if ((size % 4) in [1, 2, 3]) else ((size // 2) - 1)
dx = 0 if (size % 4) in [2, 3] else 4
for i in range(num):
line, current_pattern = apply_comp(current_pattern, beehives_to_R_beehives_comp, i * 8 + dx, 0)
lines.append(line)
line, current_pattern = apply_comp(current_pattern, beehives_to_R_beehives_comp, 4 * size + 5 - i * 8 - dx, -5, "rot180")
lines.append(line)
line, current_pattern = apply_comp(current_pattern, boat_to_beehive_and_bit, 0, 0)
lines.append(line)
line, current_pattern = apply_comp(current_pattern, boat_to_beehive_and_bit, 4 * size + 5, -5, "rot180")
lines.append(line)
if (size % 4) in [0, 3]:
new_lines, current_pattern = apply_recipe(current_pattern, beehive_to_boat_and_bit, 0, 0)
lines += new_lines
new_lines, current_pattern = apply_recipe(current_pattern, beehive_to_boat_and_bit, 4 * size + 5, -5, "rot180")
lines += new_lines
return lines, current_pattern
def grow_row(pattern, size, length, way, transf, x, y):
# Components :
# 0 : 3G on side
# 1 : 5G backwards
# 2 : 5G forwards
# 3 : 4G with beehive
# 4 : R_beehives_to_beehives (always preceded by 0)
# 5 : 4G with beehive, flipped
lines = []
dx = 0
if length % 4 == 0:
if length == 0:
recipe = [0]
else:
recipe = [2, 1] * (length // 2)
elif length % 4 == 1:
recipe = [3] + ([2, 1] * (length // 2))
elif length % 4 == 2:
recipe = [0, 4] + ([2, 1] * (length // 2 - 1)) + [5]
elif length % 4 == 3:
recipe = [0, 4] + ([2, 1] * (length // 2))
for i in range(len(recipe)):
line, pattern = apply_comp(pattern, grow_R_beehive[recipe[i]], x + way * dx, y, transf)
if recipe[i] != 4:
dx += 4
lines.append(line)
return lines, pattern
def grow_R_beehives(pattern, size):
lines = []
way = (-1)**size
left_x, right_x = (0 if (size == 1) else 4), 4 * size + 4
y = 0
for length in range(size - 1, -1, -1):
way = (-1)**size
way *= -1 if length % 4 in [0, 3] else 1
pos = ("flip_x", right_x, y) if way == -1 else ("identity", left_x, y)
new_lines, pattern = grow_row(pattern, size, length, way, *pos)
lines += new_lines
if way == 1:
if length % 4 in [2, 3]:
left_x += 4
if length % 4 in [0] or (length % 4 == 1 and length > 1):
right_x -= 4
elif way == -1:
if length % 4 in [0] or (length % 4 == 1 and length > 1):
left_x += 4
if length % 4 in [2, 3]:
right_x -= 4
y -= 1
return lines, pattern
def add_activation_seeds(pattern, size):
lines = []
left_dx, left_dy = (0, 0) if (size % 4 in [0, 1]) else (4, -2)
right_dx, right_dy = (4 * size + 4, -1) if (size % 4 in [1, 2]) else (4 * size, -3)
if size % 4 == 0:
line, pattern = apply_comp(pattern, add_snake_side_activation, right_dx, right_dy)
lines.append(line)
for i in range(size // 4):
new_lines, pattern = apply_recipe(pattern, add_excrescence, left_dx + i * 8, left_dy - i * 4)
lines += new_lines
for i in range((size - 1) // 4): # 1 less if size == 0 mod 4
new_lines, pattern = apply_recipe(pattern, add_excrescence, right_dx - i * 8, right_dy - i * 4, "flip_x")
lines += new_lines
for i in range(size // 4):
line, pattern = apply_comp(pattern, add_snake, left_dx + i * 8, left_dy - i * 4)
lines.append(line)
for i in range((size - 1) // 4): # 1 less if size == 0 mod 4
line, pattern = apply_comp(pattern, add_snake, right_dx - i * 8, right_dy - i * 4, "flip_x")
lines.append(line)
return lines, pattern
def half_activation_step(pattern, size):
if size == 3:
pattern += cleanups[size]
return pattern
left_dx, left_dy = (0, 0) if (size % 4 in [0, 1]) else (4, -2)
right_dx, right_dy = (4 * size + 4, -1) if (size % 4 in [1, 2]) else (4 * size, -3)
for i in range(size // 4):
pattern += activate_snake(left_dx + i * 8, left_dy - i * 4)
for i in range((size - 1) // 4): # 1 less if size == 0 mod 4
pattern += activate_snake("flip_x", right_dx - i * 8, right_dy - i * 4)
if size % 2 == 1:
pattern += activate_top(2 * size, -size)
else:
pattern += activate_top("flip_x", 2 * size + 6, -size)
pattern += activate_side[size % 4]
if size <= 24:
pattern += cleanups[size]
if size % 4 == 0:
if size >= 8:
pattern += cleanup_side_0_mod_4
if size >= 20:
pattern += cleanup_side_0_mod_4_2
if size >= 24:
pattern += cleanup_side_0_mod_4_3
pattern += cleanup_top("flip_x", 2 * size + 6, -size)
if size >= 28:
pattern += cleanup_side_0_mod_4_4
if size % 4 == 1:
if size >= 17:
pattern += cleanup_side_1_mod_4
if size >= 21:
pattern += cleanup_side_1_mod_4_2
if size >= 25:
pattern += cleanup_top(2 * size, -size)
pattern += cleanup_side_1_mod_4_3
if size % 4 == 2:
if size >= 22:
pattern += cleanup_top("flip_x", 2 * size + 6, -size)
if size >= 10:
pattern += cleanup_side_2_mod_4
if size >= 26:
pattern += cleanup_side_2_mod_4_2
if size % 4 == 3:
if size >= 15:
pattern += cleanup_side_3_mod_4
if size >= 23:
pattern += cleanup_top(2 * size, -size)
if size >= 27:
pattern += cleanup_side_3_mod_4_2
return pattern
def activation_step(pattern, size):
f_step = half_activation_step(pattern, size)
f_step += f_step("rot180", 5 + 4 * size, -5)
return encode_comp(f_step), pattern[MAX_TIME]
def cleanup(pattern, size):
lines = []
left_dx, left_dy = (0, 0) if (size % 4 in [0, 1]) else (4, -2)
right_dx, right_dy = (4 * size + 4, -1) if (size % 4 in [1, 2]) else (4 * size, -3)
for i in range(size // 4, 6, -1):
line, pattern = apply_comp(pattern, destroy_beehive_and_boat, left_dx + i * 8, left_dy - i * 4)
lines.append(line)
for i in range((size - 1) // 4, 6, -1): # 1 less if size % 4 == 0
line, pattern = apply_comp(pattern, destroy_beehive_and_boat, right_dx - i * 8, right_dy - i * 4, "flip_x")
lines.append(line)
return lines, pattern
def check_lines(lines, size):
prev = ""
for line in lines:
check_single_line(line)
start, _, end = decode_comp(line)
if start != prev:
print("Error : one step does not use the previous's step result as a starting point.")
print(f"Size : {size}")
exit()
prev = end
apgcode_osc = decode_comp(lines[-1])[2]
if apgcode_osc[:3] != "xp2":
print(f"Result for size {size} is not a p2 oscillator.")
exit()
osc = lt.pattern(apgcode_osc)
if (osc.population != (2 * (size ** 2) + 8 * size + 6)): # pop of clock of size n in canonical phase
print(f"Result for size {size} has incorrect population.")
print(f"Expected : {(2 * (size ** 2) + 8 * size + 6)}. Found : {osc.population}.")
print(f"Apgcode : {apgcode_osc}.")
exit()
def synthesise_long_clock(size):
print("Synthesising wick.")
lines, current_pattern = synthesise_beehives_wick(size)
new_lines, current_pattern = beehives_to_R_beehives(size, current_pattern)
lines += new_lines
print("Extending agar on first side.")
new_lines, current_pattern = grow_R_beehives(current_pattern, size)
lines += new_lines
print("Adding activation seeds on first side.")
new_lines, current_pattern = add_activation_seeds(current_pattern, size)
lines += new_lines
current_pattern = current_pattern("rot180", 5 + 4 * size, -5)
print("Extending agar on second side.")
new_lines, current_pattern = grow_R_beehives(current_pattern, size)
lines += new_lines
print("Adding activation seeds on second side.")
new_lines, current_pattern = add_activation_seeds(current_pattern, size)
lines += new_lines
print("Activation step.")
line, current_pattern = activation_step(current_pattern, size)
lines.append(line)
print("Cleaning up debris.")
new_lines, current_pattern = cleanup(current_pattern, size)
lines += new_lines
current_pattern = current_pattern("rot180", 5 + 4 * size, -5)
new_lines, current_pattern = cleanup(current_pattern, size)
lines += new_lines
check_lines(lines, size)
cost = sum([decode_comp(line)[1] for line in lines])
print(f"Synthesis has {len(lines)} stages and costs {cost} gliders.")
return slock(lines)
if __name__ == "__main__":
if len(argv) != 3:
print("Usage : python synthesise_long_clocks.py <size of clock> <output file>")
exit()
size = int(argv[1])
if size <= 2:
print("Size must be strictly greater than 2.")
synthesis = synthesise_long_clock(size)
synthesis.write_rle(argv[2], file_format='mc')
print(f"Synthesis of long^{argv[1]} clock written to file {argv[2]}")
The recipe is fully generic starting with size 25, with variations depending on size mod 4. Here are all four kinds of activation steps :
The synthesis features a way of growing zebra stripes with-the-grain, different from what is used in canada grey or spacefiller syntheses. The most complex was to find the 22 specific cleanups for small cases, because final steps are quite messy. There is, of course, a lot of room for improvements.