[ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค] ์นด๋“œ ์ง ๋งž์ถ”๊ธฐ / ํŒŒ์ด์ฌ
Problem Solving ๐Ÿ”ฅ/ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

[ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค] ์นด๋“œ ์ง ๋งž์ถ”๊ธฐ / ํŒŒ์ด์ฌ

[https://programmers.co.kr/learn/courses/30/lessons/72415]

ํ’€์ด

2021 ์นด์นด์˜ค ๋ฌธ์ œ์ธ, ์นด๋“œ ์ง ๋งž์ถ”๊ธฐ ๋ผ๋Š” ๋ฌธ์ œ์ด๋‹ค.

์ฒ˜์Œ ๋ดค์„ ๋•, ์–ด๋–ป๊ฒŒ ํ’€์–ด์•ผ ํ•  ์ง€ ๊ฐ์ด ์˜ค์ง€ ์•Š์•˜๋‹ค.
๊ทธ๋Ÿฌ๋‹ค ์กฐ๊ฑด์ด 4x4 ๋ฐฐ์—ด์ž„์„ ํ™•์ธํ•˜๊ณ .. "์•„ ์ „๋ถ€ ๋‹ค ํ…Œ์ŠคํŠธ ํ•ด๋ณด๋ผ๋Š”๊ฑฐ๊ตฌ๋‚˜.."
ํŠน์ • ์œ„์น˜์—์„œ ๊ฒฝ์šฐ์˜ ์ˆ˜๋Š” 9๊ฐ€์ง€์ด๋‹ค.

  • 4๋ฐฉํ–ฅ ์ด๋™
  • 4๋ฐฉํ–ฅ Ctrl ์ด๋™
  • Enter

๋ง ๊ทธ๋Œ€๋กœ ๋ชจ๋‘ ๋‹ค ๊ตฌํ˜„ํ–ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ๋ฐฐ์—ด์„ ๋ฌธ์ž์—ด๋กœ ์ˆ˜์ •ํ•ด์„œ ํ’€์—ˆ๋‹ค.
๊ทธ ์ด์œ ๋Š” ํŒŒ์ด์ฌ์—์„œ ๋ฐฐ์—ด์€ mutableํ•œ object ์ด๋ฏ€๋กœ ๊ณ„์† deep copyํ•ด์ฃผ๊ธฐ๊ฐ€ ๊ท€์ฐฎ์•˜๋‹ค.

์†”์งํžˆ ๋‚ด ์ฝ”๋“œ๊ฐ€ ๋งˆ์Œ์— ๋“ค์ง€๋Š” ์•Š๋Š”๋ฐ, ์ƒˆ๋กœ์šด ๋ฌธ์ œ๋ผ ๋‹ค๋ฅธ ๋ถ„๋“ค์ด ํฌ์ŠคํŒ…ํ•œ ์ข‹์€ ์ฝ”๋“œ๋ฅผ ๋ฐœ๊ฒฌํ•˜์ง€๋Š” ๋ชปํ–ˆ๋‹ค.
์นด์นด์˜ค ๋ฌธ์ œ์—์„œ ๊ตฌํ˜„์ด ์กฐ๊ธˆ ํ•˜๋“œํ•œ ๋ฌธ์ œ๊ฐ€ ๋งŽ์ด ๋‚˜์˜ค๋Š”๊ตฌ๋‚˜ ๊นจ๋‹ฌ์•˜๋˜ ๋ฌธ์ œ์˜€๋‹ค.

from collections import deque
import copy

d = [(1, 0), (-1, 0), (0, 1), (0, -1)]

def end_game(b):
    if b.count("0") == 16:
        return True
    return False

def remove_element(b, e):
    b = b.replace(e, "0")
    return b

def move(b, y, x, dy, dx):
    ny, nx = y + dy, x + dx
    if ny >= 0 and ny < 4 and nx >= 0 and nx < 4 and b[ny * 4 + nx] == "0":
        return move(b, ny, nx, dy, dx)
    else:
        if ny >= 0 and ny < 4 and nx >= 0 and nx < 4:
            return (ny, nx)
        else:
            return (y, x)

def solution(board, r, c):
    answer = 0
    b = ""
    for i in range(4):
        for j in range(4):
            b += str(board[i][j])
    q = deque([])

    cnt = 0
    enter = -1 # enter์„ ํด๋ฆญํ–ˆ๋˜ ์œ„์น˜
    q.append((r, c, b, cnt, enter))
    s = set()

    while q:
        y, x, b, c, e = q.popleft()
        pos = 4 * y + x

        if (y, x, b, e) in s:
            continue
        s.add((y, x, b, e))

        if end_game(b):
            return c

        # 4 ๋ฐฉํ–ฅ ์ด๋™
        for (dy, dx) in d:
            ny, nx = y + dy, x + dx
            if ny >= 0 and ny < 4 and nx >= 0 and nx < 4:
                q.append((ny, nx, b, c+1, e))

        # Ctrl + 4 ๋ฐฉํ–ฅ ์ด๋™
        for (dy, dx) in d:
            ny, nx = move(b, y, x, dy, dx)
            if ny == y and nx == x:
                continue
            q.append((ny, nx, b, c+1, e))

        # enter๋ฅผ ํ•˜๋Š” ๊ฒฝ์šฐ
        if b[pos] != 0:
            if e == -1:
                n_e = pos
                q.append((y, x, b, c+1, n_e))
            else:
                if e != pos and b[e] == b[pos]:
                    b = remove_element(b, b[e])
                    q.append((y, x, b, c+1, -1))

    return answer