백준 12100 2048 (Easy) python

gobeul·2023년 10월 23일

알고리즘 풀이

목록 보기
50/70
post-thumbnail

퍼즐게임 구현문제!
상하좌우 이동을 각각 함수로 구현해서 풀이했는데 풀고나니 역시 코드가 비슷했다.
이를 한번에 조합할 수 있는 방법을 고민해보는 것도 좋을듯

📜 문제 바로 가기 : 2048 (Easy)

제출코드

파이썬

import sys
input = sys.stdin.readline

N = int(input())
original_board = [list(map(int, input().split())) for _ in range(N)]

# 0,  1,  2,  3
# 상, 하, 좌, 우

def recur(s=0, lst=[]):
    global ans
    if s == 5:
        ans = max(ans, playGame(lst))
        return    
    for i in range(4):
        recur(s+1, lst+[i])

def playGame(commands):
    board = [i[::] for i in original_board]

    for com in commands:
        if com == 0 :
            up(board)
        elif com == 1:
            down(board)
        elif com == 2:
            left(board)
        else:
            right(board)
    
    v = 0
    for i in board:
        v = max(v, max(i))

    return v

def up(board):
    for j in range(N):
        for i in range(N-1):
            if board[i][j] == 0:
                continue

            for k in range(i+1, N):
                if board[k][j] != 0:
                    if board[i][j] == board[k][j]:
                        board[i][j] *= 2
                        board[k][j] = 0
                    break

    
    for j in range(N):
        for i in range(N):
            if board[i][j] != 0:
                for k in range(i):
                    if board[k][j] == 0:
                        board[k][j] = board[i][j]
                        board[i][j] = 0
                        break

def down(board):
    for j in range(N):
        for i in range(N-1, 0, -1):
            if board[i][j] == 0:
                continue

            for k in range(i-1, -1, -1):
                if board[k][j] != 0:
                    if board[i][j] == board[k][j]:
                        board[i][j] *= 2
                        board[k][j] = 0
                    break
    
    for j in range(N):
        for i in range(N-1, -1, -1):
            if board[i][j] != 0:
                for k in range(N-1, i, -1):
                    if board[k][j] == 0:
                        board[k][j] = board[i][j]
                        board[i][j] = 0
                        break


def left(board):
    for i in range(N):
        for j in range(N-1):
            if board[i][j] == 0:
                continue

            for k in range(j+1, N):
                if board[i][k] != 0:
                    if board[i][j] == board[i][k]:
                        board[i][j] *= 2
                        board[i][k] = 0
                    break
    
    for i in range(N):
        for j in range(N):
            if board[i][j] != 0:
                for k in range(j):
                    if board[i][k] == 0:
                        board[i][k] = board[i][j]
                        board[i][j] = 0
                        break

def right(board):
    for i in range(N):
        for j in range(N-1, 0, -1):
            if board[i][j] == 0:
                continue

            for k in range(j-1, -1, -1):
                if board[i][k] != 0:
                    if board[i][j] == board[i][k]:
                        board[i][j] *= 2
                        board[i][k] = 0
                    break
    
    for i in range(N):
        for j in range(N-1, -1, -1):
            if board[i][j] != 0:
                for k in range(N-1, j, -1):
                    if board[i][k] == 0:
                        board[i][k] = board[i][j]
                        board[i][j] = 0
                        break


def debug():
    board = [i[::] for i in original_board]

    # up(board)
    # left(board)
    right(board)
    
    print("===debug===")
    for i in board:
        print(*i)
    print("===========")


ans = 0
recur()
print(ans)

# debug()

접근방법

recur() 함수를 통해 5번의 이동키로 만들 수 있는 모든 경우의 수를 구하고 그걸 바탕으로 실제 플레이해보면서 가장 큰 값을 기록했다.
이동횟수가 5번으로 적었기에 별다른 백트래킹은 고민해보지 않았다.

profile
뚝딱뚝딱

0개의 댓글