I made some very minimal changes to the script to get it to do something like what you want: all salvos are p1 and a recipe is output if the final pattern has 9 cells and seems to contain a glider moving SE or NW.

Note that it is quite possible that the final pattern could be tub + glider and the script doesn't care if the block has returned to its original position or not. Also it only allows a glider to be produced at the final step. For example, it won't find recipes where a glider is produced at step 3 and then the remaining debris is converted back into a block during later steps.

It seems like there are plenty of 5 glider solutions under these restrictions. (EDIT: Ooops, no it only starts churning out solutions that contain 6 gliders, and for reasons mentioned above it misses dvgrn's 5 glider solution in the other thread). Finally, here is the code:

`import golly as g`

from hashlib import sha256

from itertools import chain

#arbitrary numbers

MAX_GENERATIONS = 256

MAX_POPULATION = 40

MAX_GLIDERS = 6

#NE glider

GLIDER = g.parse('3o$2bo$bo!')

#put any ad-hoc patterns that you want to bombard with slow gliders here.

TARGET_PATTERNS = []#('known_splitter', 'bo$obo$b2o$5bo$4bobo$5bobo$6b2o!')]

#put simple targets here, along with rotational symmetry

SIMPLE_TARGETS = [

('block', '2o$2o!', 4),

# ('blinker', '3o$!', 4),

# ('tub', 'bo$obo$bo!', 4),

# ('boat', 'b2o$obo$bo!', 1),

# ('hive', 'b2o$o2bo$b2o!', 2),

# ('ship', 'b2o$obo$2o!', 2),

# ('loaf', 'b2o$o2bo$bobo$2bo!', 1),

# ('lboat', '2b2o$bobo$obo$bo!', 1),

# ('pond', 'b2o$o2bo$o2bo$b2o!', 4),

# ('tlight', '4bo$4bo$4bo2$3o3b3o2$4bo$4bo$4bo!', 4),

# ('hfarm', '6bo$5bobo$5bobo$6bo2$b2o7b2o$o2bo5bo2bo$b2o7b2o2$6bo$5bobo$5bobo$6bo!', 4),

]

def get_pattern_variants(cells, symmetry):

variants = []

for t in range(0, 4, symmetry):

variants.append(cells)

cells = g.transform(cells, 0, 0, 0, -1, 1, 0)

return variants

TARGETS = []

for name, pattern in TARGET_PATTERNS:

cells = g.parse(pattern)

p = len(cells) / 2

TARGETS.append((name, cells, p))

for name, pattern, sym in SIMPLE_TARGETS:

cells = g.parse(pattern)

variants = get_pattern_variants(cells, sym)

for i, v in enumerate(variants):

p = len(v) / 2

TARGETS.append((name+str(i), v, p))

def patterns_identical(cells1, cells2):

if len(cells1) != len(cells2):

return False

if sum(cells1) != sum(cells2):

return False

return sorted(zip(cells1[::2], cells1[1::2])) == sorted(zip(cells2[::2], cells2[1::2]))

def get_pattern_period(cells):

temp_cells = cells

for p in range(0, 2):

temp_cells = g.evolve(temp_cells, 1)

if patterns_identical(cells, temp_cells):

return p+1

return None

def get_shooting_range(cells):

min_d1 = max_d1 = cells[0] + cells[1]

min_d2 = cells[0] - cells[1]

for i in range(2, len(cells), 2):

min_d1 = min(min_d1, cells[i] + cells[i+1])

max_d1 = max(max_d1, cells[i] + cells[i+1])

min_d2 = min(min_d2, cells[i] - cells[i+1])

min_lane = min_d1 - 6

max_lane = max_d1 + 3

shift = 6 - min_d2 // 2

return min_lane, max_lane, shift

def get_pattern_to_try(cells, lane, parity, offset=50):

glider = g.transform(GLIDER, lane - lane // 2 - offset, lane // 2 + offset)

if parity % 2:

glider = g.evolve(glider, 1)

return list(chain(cells, glider))

offset = 0

def display_solution(start, lanes, debug, last_cells):

global offset

cells = [c for n, c, _ in TARGETS if n == start][0]

i = 100

for lane in lanes:

lane_num, parity = lane

cells = get_pattern_to_try(cells, lane_num, parity, i)

i += 100

g.putcells(cells, 0, offset)

for i, p in enumerate(debug):

g.putcells(p, 100 + 100 * i, offset)

g.putcells(last_cells, 100 + 100 * len(debug), offset)

g.fit()

g.update()

g.show(' '.join(chain([str(start), str(len(lanes))], [str(lane) for lane in lanes])))

offset += 400

randoms = []

for i in range(4096):

randoms.append(int(sha256(str(i)).hexdigest()[:16], 16))

def to_hashable(cells):

if not cells:

return 0

minx = min(cells[::2])

miny = min(cells[1::2])

hash = 0

for i in range(0, len(cells), 2):

hash ^= randoms[64 * (cells[i] & 63) + (cells[i+1] & 63)]

return hash

def deltas(cells):

return len(cells), sum(cells[::2]), sum(cells[1::2])

def bombard_final(start, lanes, cells, period, debug, flipx, flipy):

cells = g.transform(cells, 0, 0, flipx, 0, 0, flipy)

min_lane, max_lane, shift = get_shooting_range(cells)

for lane_num in range(min_lane, max_lane + 1):

for parity in range(period):

lane = (lane_num, parity)

start_cells = get_pattern_to_try(cells, lane[0], lane[1], shift)

new_cells = g.evolve(start_cells, MAX_GENERATIONS)

if len(new_cells) == 18:

n1, dx1, dy1 = deltas(new_cells)

n2, dx2, dy2 = deltas(g.evolve(new_cells, 4))

if n1 != n2:

continue

dx = dx2-dx1

dy = dy2-dy1

if (dx, dy) == (5, 5) or (dx, dy) == (-5, -5):

#Success??

#flip back for display purposes

start_cells = g.transform(start_cells, 0, 0, flipx, 0, 0, flipy)

new_cells = g.transform(new_cells, 0, 0, flipx, 0, 0, flipy)

#add

debug.append(start_cells)

lanes.append(lane)

#display

display_solution(start, lanes, debug, new_cells)

#remove

lanes.pop()

debug.pop()

g.new('')

new_queue = []

for name, cells, _ in TARGETS:

period = get_pattern_period(cells)

new_queue.append( (name, [], cells, period, []) )

seen = set()

for n in range(MAX_GLIDERS):

queue = new_queue

new_queue = []

count = 0

for start, lanes, last, period, debug in queue:

g.show(str((n+1,count,len(queue))))

count += 1

min_lane, max_lane, shift = get_shooting_range(last)

for lane_num in range(min_lane, max_lane + 1):

for parity in range(period):

lane = (lane_num, parity)

start_cells = get_pattern_to_try(last, lane[0], lane[1], shift)

new_cells = g.evolve(start_cells, MAX_GENERATIONS)

if not new_cells or len(new_cells) > 2 * MAX_POPULATION:

continue

new_period = get_pattern_period(new_cells)

if new_period != 1:

continue

new_hashable = to_hashable(new_cells)

if new_hashable in seen:

continue

seen.add(new_hashable)

if new_period > 1:

seen.add(to_hashable(g.evolve(new_cells, 1)))

new_lanes = lanes + [lane]

new_debug = debug + [start_cells]

bombard_final(start, new_lanes, new_cells, new_period, new_debug, 1, 1)

# bombard_final(start, new_lanes, new_cells, new_period, new_debug, 1, -1)

# bombard_final(start, new_lanes, new_cells, new_period, new_debug, -1, -1)

if n + 1 < MAX_GLIDERS:

new_queue.append( (start, new_lanes, new_cells, new_period, new_debug) )