Esempio n. 1
0
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
Esempio n. 3
0
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()