[Programmers]レベル1-クレーン人形をつかむ


質問リンク
https://programmers.co.kr/learn/courses/30/lessons/64061

どうやって解いたの?


1-1. プレートの行と列を変更します。

[0, 0, 0, 0, 0]              [0, 0, 0, 4, 3]
[0, 0, 1, 0, 3]              [0, 0, 2, 2, 5]
[0, 2, 5, 0, 1]     --->     [0, 1, 5, 4, 3]
[4, 2, 4, 4, 2]              [0, 0, 0, 4, 3]
[3, 5, 1, 3, 1]              [0, 3, 1, 2, 1]
      arr                     list(zip(*arr)

💡 2 D配列の行と列を置換する方法

new_arr = list(zip(*arr))

💭 どうしたんですか。WHY?


boardは人形抜去機の形態で表現された2次元配列である.
つまり、人形機の一番上の1行目が板の1行目、2行目が板の2行目となる.
しかし、クレーンが人形を抜くと、単位は板の行ではなく、列になります.
たとえば、起動クレーンの位置が1の場合.
クレーンは板の最初の列の一番上の人形を抜きます.

1-2. board配列をdexに変更します。

board = deque(map(deque, zip(*board)))

💭 どうしたんですか。WHY?

  • 行と置換板は以下のように配列されている.
  • [0, 0, 0, 4, 3]
    [0, 0, 2, 2, 5]
    [0, 1, 5, 4, 3]
    [0, 0, 0, 4, 3]
    [0, 3, 1, 2, 1]
    プレートの行と列を変更すると、抜き機の形状は以下のように考えられます.見慣れた構造が見えないのか?!

    スタックが左に90度傾いた形状と同じです.は、第1入力(LIFO)形式です.つまり、最後に入る要素が最初に現れるということです.
    したがってインデックスが使用されます.

    2.処理異常条件


    問題は例外条件があることを示している.
    クレーンが作動している間は人形が挟まないことはありませんが、クレーンが人形のない場所で作動している場合は、何も起こりません.
    そこで,以下のような例外条件処理を行った.
    if not board[move-1]:    # 비어 있으면 skip, 아무 일도 일어나지 않음
    	continue

    3.クレーンで人形を抜く

    while True:
    	popped_doll = board[move-1].popleft()
        if popped_doll != 0:
        	break
    例えばboard[1]は以下のようになります.
    [0, 0, 0, 4, 3]
    問題の説明によると、黒板の整数を教えています.
  • 0はスペースを表します.
  • 1-100の各数字は異なる人形の形を表し、同じ数字は同じ人形の形を表す.
  • 従って、取締役会[move-1].Popleft()操作は、popの整数が0でない前に実行する必要があります.
    popped dollが非ゼロ整数の場合、対応するwhileゲートから逃げます.

    4.ぬいぐるみをかごに入れる


    抜いた人形をかごに入れると、次のようなことが起こります.
  • で抽出した人形をかごに入れます.(入れるだけです.)
  • かごが空または
  • かごが空でない場合、かごの上部の人形が入れる人形と他の人形が入れる人形は
  • である.
  • で抽出した人形をかごに入れる過程で爆発し、2つの人形が消えてしまう可能性があります.
  • かごの一番上の人形が置く人形と同じなら
  • 上は以下の条件文で表すことができます.
    # 1. 뽑은 인형을 바구니에 넣기만 한다.
    if not basket or basket[-1]!=popped_doll:     
    	basket.append(popped_doll)
    # 2. 뽑은 인형을 바구니에 담는 과정에서 2개의 인형이 터트려져서 사라진다.
    elif basket[-1] == popped_doll:
    	basket.pop()
        answer += 2
    最終コードは以下の通りです.

    💻最終コード

    from collections import deque
    
    def solution(board, moves):
        answer = 0
        # board의 각 열을 덱으로 바꾸기
        board = deque(map(deque, zip(*board)))
        basket = []
        #print(board)
            
        for move in moves:
            #print("move: ", move)
            if board[move-1]:
                while 1:
                    popped_doll = board[move-1].popleft()
                    if popped_doll!=0:
                        break
                    #print("popped_doll: ", popped_doll)
                if not basket or basket[-1]!=popped_doll:
                    basket.append(popped_doll)
                elif basket[-1] == popped_doll:
                    basket.pop()
                    answer += 2
        return answer
    関連サイト
  • プログラマー2019 KACA開発者冬季実習1級-Crain人形を捕まえる

    https://programmers.co.kr/learn/courses/30/lessons/64061