코딩 테스트/Level 3

[PCCP 기출문제] 4번 / 수레 움직이기

컴닥 2024. 11. 30. 07:20
반응형

https://school.programmers.co.kr/learn/courses/30/lessons/250134

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

꽤 지저분한 IF문들을 파이썬의 언패킹과 튜플 비교를 이용해서 깔끔하게 정리하려고 노력했다. 
= 파이써닉한 코드를 쓰려고 노력했다능.. 

from collections import deque
from copy import deepcopy


def solution(maze):
    def can_go(y_, x_, visited):
        return 0 <= y_ < height and 0 <= x_ < width and maze[y_][x_] != 5 and not visited[y_][x_]

    queue = deque()
    height, width = len(maze), len(maze[0])
    red_start = blue_start = None
    red_visited = [[False for _ in range(width)] for _ in range(height)]
    blue_visited = [[False for _ in range(width)] for _ in range(height)]
    for y in range(height):
        for x in range(width):
            if maze[y][x] == 1:
                red_start = (y, x)
                red_visited[y][x] = True
            elif maze[y][x] == 2:
                blue_start = (y, x)
                blue_visited[y][x] = True
    queue.append((red_start, blue_start, 0, red_visited, blue_visited))
    while queue:
        red, blue, step, red_visited, blue_visited = queue.popleft()
        (red_y, red_x), (blue_y, blue_x) = red, blue
        if maze[red_y][red_x] == 3 and maze[blue_y][blue_x] == 4:
            return step
        if maze[red_y][red_x] == 3:
            for dy, dx in ((1, 0), (-1, 0), (0, 1), (0, -1)):
                new_blue_y, new_blue_x = new_blue = blue_y + dy, blue_x + dx
                if can_go(*new_blue, blue_visited) and new_blue != red:
                    blue_visited[new_blue_y][new_blue_x] = 1
                    queue.append((red, new_blue, step + 1, red_visited, blue_visited))
        elif maze[blue_y][blue_x] == 4:
            for dy, dx in ((1, 0), (-1, 0), (0, 1), (0, -1)):
                new_red_y, new_red_x = new_red = red_y + dy, red_x + dx
                if can_go(*new_red, red_visited) and new_red != blue:
                    red_visited[new_red_y][new_red_x] = 1
                    queue.append((new_red, blue, step + 1, red_visited, blue_visited))
        else:
            red_visited_copied = deepcopy(red_visited)
            for red_dy, red_dx in ((1, 0), (-1, 0), (0, 1), (0, -1)):
                new_red_y, new_red_x = new_red = red_y + red_dy, red_x + red_dx
                if not can_go(*new_red, red_visited):
                    continue
                blue_visited_copied = deepcopy(blue_visited)
                for blue_dy, blue_dx in ((1, 0), (-1, 0), (0, 1), (0, -1)):
                    new_blue_y, new_blue_x = new_blue = blue_y + blue_dy, blue_x + blue_dx
                    if can_go(*new_blue, blue_visited) and new_red != new_blue and (new_red != blue or new_blue != red):
                        red_visited_copied[new_red_y][new_red_x] = True
                        blue_visited_copied[new_blue_y][new_blue_x] = True
                        queue.append((new_red, new_blue, step + 1, red_visited_copied, blue_visited_copied))
    return 0

 

반응형