コード例 #1
0
ファイル: 15.py プロジェクト: drbitboy/AdventOCode
def part1(icode):
    """
  Day 15 part 1

  Create an INTCODE INSTANCE, then run it

  """

    ### Method 1:  explore the space, hope we do not run out of stack

    instance = intcode.INSTANCE(icode, lt_inputs_arg=[])
    instance.run()
    assert not instance.outputs
    assert instance.state == intcode.INSTANCE.READWAIT

    explore_results = explore(instance, (
        0,
        0,
    ), set(), set(), False)
    ######################################################################
    ######################################################################

    ### Method 1:  explore the space, hope we do not run out of stack

    instance = intcode.INSTANCE(icode, lt_inputs_arg=[])
    instance.run()
    assert not instance.outputs
    assert instance.state == intcode.INSTANCE.READWAIT

    wall_results = wall_follower(instance)
    ######################################################################
    ######################################################################

    return (
        dict(explore_results=bfs15(*explore_results),
             wall_results=bfs15(*wall_results)),
        explore_results,
        wall_results,
    )
コード例 #2
0
def run_07_part2(lt_phases, input_signal_arg=0):
    """
  Day 7 part 2:  amplifiers in series with phases and inputs,
                 feedback last instance to first,
                 one pass each
 
  """
    global icode

    ### Get length of phases of, and indices into, list
    N = len(lt_phases)
    R = range(N)

    ### Create an INTCODE INSTANCE stage for each input phase
    instances = [
        intcode.INSTANCE(icode, lt_inputs_arg=lt_phases[i:i + 1]) for i in R
    ]

    ### Add initial input signal to first stage
    instances[0].add_input_data(input_signal_arg)

    ### Cascade stages, including feedback from last to first
    for i in R:
        instances[i].make_cascade(instances[(i + 1) % N])

    while True:

        ### Set result counts
        finis = 0
        readwaits = 0

        for instance in instances:

            ### Loop over each stage
            instance.run()

            ### Update stage result counts
            if instance.state == intcode.INSTANCE.READWAIT: readwaits += 1
            elif instance.state == intcode.INSTANCE.FINI: finis += 1
            else: assert dict()['{0},{1}'.format(readwaits, finis)]

        ### Continue if all stages expect to read another input
        if N == readwaits:
            for instance in instances:
                assert len(instance.inputs) >= instance.input_ptr
            continue

        assert 0 == readwaits
        assert N == finis
        break
    return instances[-1].outputs[-1]
コード例 #3
0
def part1(icode):
    """
  Day 13 part 1

  Create an INTCODE INSTANCE, then run it; this will draw the board by
  loading (X,Y,Type) triplets into list instance.outputs


  """

    instance = intcode.INSTANCE(icode, lt_inputs_arg=[])
    instance.run()
    assert intcode.INSTANCE.FINI == instance.state

    return instance.outputs
コード例 #4
0
def part1(icode):
    """
  Day 15 part 1

  Create an INTCODE INSTANCE, then run it

  """
    instance = intcode.INSTANCE(icode)
    instance.run()

    lt_rows = list()
    lt_row = list()
    result, height = 0, 0

    for i in instance.outputs:

        c = chr(i)
        assert c in sall

        if cnl == c:
            if not lt_row: break
            if lt_rows: assert width == len(lt_row)
            else: width = len(lt_row)
            lt_rows.append(lt_row)
            height = len(lt_rows)
            lt_row = list()

        else:
            pos = len(lt_row)
            if c in sdirs:
                start_xy = pos, height
            elif 1 < height and chash == c:
                c2up = lt_rows[-2][pos]
                c1up = lt_rows[-1][pos - 1:pos + 2]
                if (chash == c2up) and (chash3 == c1up):
                    result += ((height - 1) * pos)
            lt_row.append(c)

    assert not lt_row

    return dict(result=result,
                start_xy=start_xy,
                lt_rows=lt_rows,
                instance_state=instance.state)
コード例 #5
0
def part2(icode):
    """
  Day 13 part 2

  Repeatedly run program.  As each round is lost because ball passes the
  paddle, find where that occurred and add joystick movement as needed
  via dt_i

  """

    ### dt_:  dict of joystick non-zero moves
    ### dt_scores:  dict of counts of scores, for detecting infinite loops

    dt_i, dt_scores = dict(), dict()

    ### Initial input:  do nothing

    inputs = [0]

    while True:

        ### Create an INTCODE INSTANCE, put two quarters into coin slot
        ### (memory location 2), add one input datum to dt_i, then run program

        instance = intcode.INSTANCE(icode, lt_inputs_arg=[])
        instance.vm[0] = 2
        instance.add_input_data(*inputs)
        instance.run()

        ### Save last output pointer
        Llast = len(instance.outputs)

        ### If no joystick inputs yet, save initial paddle position

        if not dt_i:
            Lo = len(instance.outputs)
            while True:
                Lo -= 3
                if instance.outputs[Lo + 2] == 3:
                    ### Type 3 is paddle position; save X and Y
                    paddlex, paddley = paddle = instance.outputs[Lo:Lo + 2]
                    paddle_toggle = paddley + paddley - 1
                    break

        if do_debug:
            print(
                '\n========================================================================'
            )
            print((
                'Start',
                Llast,
                instance.outputs[-30:],
            ))
            print(dict(paddle=paddle))

        ### Run program as long as it is waiting for input
        ### - If it is not waiting for input, it ended, either because ball
        ###   passed paddle, or all blocks are gone

        while intcode.INSTANCE.READWAIT == instance.state:
            Lo = len(instance.outputs)
            if do_debug: print((
                    'Read',
                    Lo,
                    instance.outputs[Llast:],
            ))
            Llast = Lo
            instance.add_input_data(dt_i.get(Lo, 0), state_must_be_init=False)
            instance.run()

        if do_debug: print((
                'Endw',
                dict(state=instance.state),
        ))

        x, y, score = instance.outputs[-3:]
        if -1 == x and 0 == y and score > 0:

            ### End of successful round:  all blocks are gone; pickle outputs
            ### for play13.py; exit outer [while True] loop

            with open('13.pickle', 'wb') as fout:
                pickle.dump(dict(lt_outputs=instance.outputs, dt_inputs=dt_i),
                            fout)

            ### Return score and outputs
            return score, instance.outputs

        ### Copy last 200 output triples list (tail); find where ball exited
        ### field, add joystick movement to paddle to catch it next time

        tail = instance.outputs[-600:]

        ### Variable adjust will be None until a ball position on row
        ### [paddley] is found; then ad will be a non-zero integer that is
        ### incremented or decremented for each previous INSTANCE.READWAIT
        ### occurrence, until it hits zero

        adjust = None

        ### Loop until adjust is zero

        Lo = len(instance.outputs)

        while (adjust is None) or adjust:

            ### Get last (x,y,type) triple

            typ, y, x = tail.pop(), tail.pop(), tail.pop()

            if typ == 4:

                ### Triple expresses a ball position

                if not (adjust is None):

                    ### Variable adjust is non-zero integer; Lo is length of
                    ### instance.outputs for this ball position and when
                    ### INSTANCE.READWAIT occurred in last run
                    ### - Variable extra6 accounts for paddle movement data
                    ###   in next run

                    extra6 -= 6

                    ### - Move paddle at INSTANCE.READWAIT when
                    ###   len(instance.outputs) will be (Lo+extra6)

                    delta = adjust > 0 and +1 or -1
                    adjust -= delta
                    paddlex += delta
                    dt_i[Lo + extra6] = delta

                    if do_debug:
                        print(
                            dict(adjust=adjust,
                                 paddlex=paddlex,
                                 paddley=paddley,
                                 Lo=Lo,
                                 Loplus=Lo + extra6,
                                 dtnew=dt_i[Lo + extra6]))

                elif paddley == y:

                    ### Variable adjust is None; initialize joystick variables;
                    ### ball is at x,paddley; paddley is on or above paddle row
                    ### - x is ball position
                    ### - paddlex is paddle position
                    ### - Set adjust to how much paddle must move
                    ### - Add 6 positions per move to account for movement
                    ###   of paddle in instance.outputs list during next loop
                    adjust = x - paddlex
                    extra6 = 6 * abs(adjust)
                    if do_debug:
                        print(
                            dict(adjust=adjust,
                                 x=x,
                                 paddlex=paddlex,
                                 extra6=extra6))
                        sys.stdout.flush()

                    assert adjust

            ### Decrement output pointer

            Lo -= 3

        if do_debug:
            Lo = len(instance.outputs)
            print((
                'Fini',
                Lo,
                instance.outputs[Llast:],
            ))

        Lo = len(instance.outputs)

        ### Find last non-zero score

        score = 0
        while (Lo > 10000) and (not score):
            x, y, typ = instance.outputs[Lo - 3:Lo]
            if (-1 == x) and (0 == y): score = typ
            Lo -= 3

        if score:

            ### Keep track of how many times this non-zero score occurred

            if score in dt_scores: dt_scores[score] += 1
            else: dt_scores[score] = 1

            ### If it occurred 20 times, adjust paddley parameter that
            ### controls paddle adjustment above

            if score and (dt_scores[score] > 19):
                dt_scores[score] = 0
                paddley = paddle_toggle - paddley
                if do_debug:
                    print((
                        'Score',
                        dict(score=score,
                             score_count=dt_scores[score],
                             paddley=paddley),
                    ))

        assert intcode.INSTANCE.FINI == instance.state

        sys.stdout.flush()
コード例 #6
0
ファイル: 11.py プロジェクト: drbitboy/AdventOCode
def run_11(start_color):
    """
  Day 11 part 1
 
  """
    global icode

    ### Create an INTCODE INSTANCE
    instance = intcode.INSTANCE(icode, lt_inputs_arg=[])

    st_whites, xypair, dir, output_ptr = set(), (
        0,
        0,
    ), 0, 0
    st_painted_once = set()

    if start_color == white: st_whites.add(xypair)

    instance.run()

    while intcode.INSTANCE.READWAIT == instance.state:
        Lo = len(instance.outputs)
        if (Lo - 2) == output_ptr:

            color, turn = instance.outputs[-2:]
            output_ptr += 2

            if white == color: st_whites.add(xypair)
            else: st_whites.discard(xypair)
            st_painted_once.add(xypair)

            dir = (dir + 4 + (turn and 1 or -1)) % 4

            if 0 == dir: xypair = (
                    xypair[0] + 0,
                    xypair[1] - 1,
            )
            elif 1 == dir: xypair = (
                    xypair[0] + 1,
                    xypair[1] + 0,
            )
            elif 2 == dir: xypair = (
                    xypair[0] + 0,
                    xypair[1] + 1,
            )
            else: xypair = (
                xypair[0] - 1,
                xypair[1] + 0,
            )

        else:
            assert not instance.outputs

        instance.add_input_data(*[xypair in st_whites and white or black],
                                state_must_be_init=False)
        instance.run()

    xwhites, ywhites = zip(*st_whites)
    xmin = min(xwhites)
    ymin = min(ywhites)
    width = 1 + max(xwhites) - xmin
    height = 1 + max(ywhites) - ymin
    arr = [[' '] * width for i in range(height)]
    #print((width,height,xmin,ymin,))
    #print((len(arr[0]),len(arr),))
    for x, y in st_whites:
        #print((x,y,))
        arr[y - ymin][x - xmin] = '@'
    return len(st_painted_once), st_whites, '\n'.join(
        [''.join(row) for row in arr])
コード例 #7
0
def part2(icode):
    """
  Day 15 part 2

  """

    dt_part1_results = part1(icode)

    lt_rows = dt_part1_results['lt_rows']
    start_xy = dt_part1_results['start_xy']
    current_xy = tuple(list(start_xy))
    current_c = get_c(lt_rows, current_xy)
    start_dir = dt_dirs[current_c]
    current_dir = tuple(list(start_dir))
    assert not (current_xy is start_xy)
    assert not (current_dir is start_dir)

    linear_steps = 0
    lt_commands = list()

    while True:

        if do_debug:
            print(
                dict(lt_commands_last4=lt_commands[-4:],
                     linear_steps=linear_steps,
                     current_c=current_c,
                     current_xy=current_xy,
                     current_dir=current_dir))

        if chash == get_c(lt_rows, current_xy, current_dir):
            linear_steps += 1
            current_xy = move(current_xy, current_dir)
            current_c = chash
            continue

        if 0 < linear_steps: lt_commands.append('{0}'.format(linear_steps))

        linear_steps = False

        for f in (
                turn_rt,
                turn_lt,
        ):
            new_dir = f(current_dir)
            if chash == get_c(lt_rows, current_xy, new_dir):
                current_dir = new_dir
                current_xy = move(current_xy, new_dir)
                linear_steps = 1
                current_c = chash
                lt_commands.append(f is turn_rt and 'R' or 'L')
                break

        if do_debug:
            print(
                dict(linear_steps=linear_steps, Llt_commands=len(lt_commands)))

        if linear_steps: continue
        if lt_commands: break

        ### Try opposite direction via two left turns

        current_dir = turn_lt(turn_lt(current_dir))
        assert chash == get_c(lt_rows, current_xy, current_dir)
        lt_commands.extend(list('LL'))

    s_commands = ','.join(lt_commands)

    dt_fs = splitter.splitter17(s_commands)
    keys = sorted(list(dt_fs.keys()))
    main_routine = s_commands
    for key in keys:
        s_value = dt_fs[key]
        assert 20 > len(s_value)
        main_routine = main_routine.replace(s_value, key)

    s_inputs = cnl.join([main_routine] + [dt_fs[key]
                                          for key in keys] + ['n', ''])
    instance = intcode.INSTANCE(icode,
                                lt_inputs_arg=[ord(s) for s in s_inputs])
    assert 1 == instance.vm[0]
    instance.vm[0] = 2
    instance.run()

    rtn = dict(s_commands=s_commands,
               main_routine=main_routine,
               Loutputs=len(instance.outputs),
               lt_result=[v for v in instance.outputs if v < 0 or v > 127])
    rtn.update(dt_fs)

    return rtn, instance.outputs