def cubical(model, high=False): (pos1, pos2) = bounding_box(model) width = pos2.x - pos1.x + 1 height = pos2.y - pos1.y + 1 depth = pos2.z - pos1.z + 1 (x_cur, x_next) = (0, pos1.x) (y_cur, y_next) = (0, pos2.y + 1) (z_cur, z_next) = (0, pos1.z) prog = move_x(pos1.x) prog += move_z(pos1.z - 1) if high: prog += single(Flip()) prog += clear_all(model, pos1.x, 0, pos1.z - 1, width, height, depth) if high: prog += single(Flip()) prog += move_x(-pos1.x) prog += move_z(-pos1.z + 1) return prog + single(Halt())
def up_pass(model, high=False): prog = single() (pos1, pos2) = bounding_box(model) width = pos2.x - pos1.x + 1 height = pos2.y + 1 depth = pos2.z - pos1.z + 1 prog += move_x(pos1.x) x = pos1.x prog += move_y(1) prog += move_z(pos1.z) z = pos1.z max_bots = min(20, width) # Fission into a line (steps_distr, strips) = fission_fill_right(list(range(2, max_bots + 1)), width) prog += steps_distr if high: prog += single(Flip()) // (single() ** (max_bots - 1)) # Print each strip layer by layer in parallel print_prog = empty() for strip in strips: print_prog //= print_hyperrectangle(model, x, z, strip, height, depth) x += strip prog += print_prog if high: prog += single(Flip()) // (single() ** (max_bots - 1)) prog += fusion_unfill_right(strips) prog += move_x(-pos1.x) prog += move_y(-height) prog += single(Halt()) return prog
def solve_gen(m: 'Model', x_cnt: 'int', z_cnt: 'int', low): (bb_a, bb_b) = bounding_box(m) # For narrow models x_cnt = min(x_cnt, (bb_b.x - bb_a.x + 1) // 2) z_cnt = min(z_cnt, (bb_b.z - bb_a.z + 1) // 2) if not low: yield Cmd.Flip() zones = partition_space(bb_a, bb_b, x_cnt, z_cnt) # Spawn bots # # State is used to spawn bots and to provide initial coords and ids st = State.initial_state(39) yield from st.spawn_bots(x_cnt, z_cnt) bots = st.grid # Navigate solve, and go to safe position for merging tasks = {} for z in range(z_cnt): for x in range(x_cnt): id = bots[z][x] bot = st[bots[z][x]] (a, b) = zones[z][x] d = (x_cnt + z_cnt) - (bot.pos.x + bot.pos.y) tasks[id] = sequence(with_delay(d, agent_gen(m, bot.pos, a, b)), go_to_start(a, bb_b)) for x in merge_tasks(tasks): if type(x) == dict: pos = x else: yield x # # Merging # # Combine rows t = [] for i in range(len(bots)): t.append([x for x in merge_line(bots[i], pos, Diff(1, 0, 0))]) for i in range(len(t[0])): tasks = {} for j in range(len(bots)): tasks.update(t[j][i]) yield from merge_tasks(tasks) # Combine col col = [x[0] for x in bots] for t in merge_line(col, pos, Diff(0, 0, 1)): yield from merge_tasks(t) # Return home for x in navigate(pos[1], Pos(0, 0, 0)): yield x if not low: yield Cmd.Flip() yield Cmd.Halt()