14499번 - 주사위 굴리기

1. 주사위 굴리기

A. 📜 문제

위 백준 사이트에 접속하여 문제를 확인해주세요.

B. 💡 내 답안

a. 1차 시도 (성공)

import sys

input = sys.stdin.readline


class Dice:
    def __init__(self):
        """
        :param nums: 주사위에 적힌 번호
        :param top, bottom, front, back, right, left: 현재 각 pos의 인덱스
        """
        self.nums = [0 for _ in range(6)]
        self.top_index = 0
        self.bottom_index = 5
        self.front_index = 4
        self.back_index = 1
        self.right_index = 2
        self.left_index = 3

    def get_top(self) -> int:
        """
        현재 주사위의 top 위치에 적힌 번호를 반환
        """
        return self.nums[self.top_index]

    def put_bottom(self, array: list, x: int, y: int):
        """
        현재 array의 값에 따라 다르게 array의 값을 변경해줘야함.
         따라서, array를 iterable객체로 parameter를 받음

        :param array: 지도 정보
        :param x: 현재 x축
        :param y: 현재 y축
        """
        if array[x][y] == 0:
            # 주사위를 굴렸을 때, 이동한 칸에 쓰여 있는 수가 0인 경우
            array[x][y] = self.nums[self.bottom_index]
        else:
            # 0이 아닌 경우
            self.nums[self.bottom_index] = array[x][y]
            array[x][y] = 0

    def roll(self, d: int):
        """
        주사위 굴리기
         미리 주사위의 인덱스를 지역변수로 저장하고 self변수를 변경해줌

        :param d: 주사위가 굴러갈 방향
        """
        # 0 동 1 서 2 북 3 남
        top = self.top_index
        bottom = self.bottom_index
        right = self.right_index
        left = self.left_index
        front = self.front_index
        back = self.back_index

        if d == 0:
            self.top_index = left
            self.bottom_index = right
            self.right_index = top
            self.left_index = bottom
        if d == 1:
            self.top_index = right
            self.bottom_index = left
            self.right_index = bottom
            self.left_index = top
        if d == 2:
            self.top_index = front
            self.bottom_index = back
            self.front_index = bottom
            self.back_index = top
        if d == 3:
            self.top_index = back
            self.bottom_index = front
            self.front_index = top
            self.back_index = bottom

    def __str__(self):
        return f"top = {self.top_index}번, {self.nums[self.top_index]}, " \
               f"bottom = {self.bottom_index}번, {self.nums[self.bottom_index]}, " \
               f"right = {self.right_index}번, {self.nums[self.right_index]}, " \
               f"left = {self.left_index}번, {self.nums[self.left_index]}, " \
               f"front = {self.front_index}번, {self.nums[self.front_index]}, " \
               f"back = {self.back_index}번, {self.nums[self.back_index]}"


if __name__ == "__main__":
    n, m, x, y, k = list(map(int, input().split()))
    array = [list(map(int, input().split())) for _ in range(n)]
    commands = list(map(lambda x: int(x)-1, input().split()))
    dice = Dice()

    ds = ((0, 1), (0, -1), (-1, 0), (1, 0))

    for command in commands:
        dx = x + ds[command][0]
        dy = y + ds[command][1]

        if 0 <= dx < n and 0 <= dy < m:
            x, y = dx, dy

            dice.roll(command)
            dice.put_bottom(array, x, y)
            print(dice.get_top())

            # print(dice)
            # print(array)


a. 🙄 회고

내 풀이

  • 주사위를 어떤 방식으로 처리할지 고민하다가, 그냥 class 객체로 만들었다.

결론

  • 생각보다 구현문제는 class로 만들면 쉽게 풀리는게 많은 것 같다.
    • class로 구현하는 과정에서 문제를 잘게 분해하고 구현해나가서 그런걸지도 모르겠다.

C. 🧐 문제 해설

이해한 내용을 바탕으로 작성했습니다.

주사위는 아래 모양처럼 생각하면 된다.

주사위에서 할 수 있는 행동(method)는 3가지이다.

  1. 주사위 윗면에 적힌 번호를 출력하는 것
  2. 주사위 아랫면에 적힌 번호를 갱신하는 것
    1. 지도에 적힌 값에 따라 지도도 갱신하기
  3. 주사위를 굴리는 것

위 행동을 수월하게 진행하기 위해서 주사위에 모든면에 대한 index를 class 변수에 기록하고 시작한다.

주사위가 굴러갈때 모든 면의 번호가 바뀌는 것은 아니다.

굴러가는 방향의 4가지 면만 상호적으로 번호가 바뀐다.

직접 주사위를 만들어서 굴려보는게 더 직관적일텐데, 주사위를 동쪽으로 굴린다면 앞면과 뒷면에 적힌 번호는 바뀌지 않는다. 윗면, 아랫면, 오른쪽면, 왼쪽면만 바뀐다.

바뀌는 것도 다이나믹하게 바뀌는 것은 아니고, 굴러가는 방향으로 밀어낸다고 생각하면 편하다.
동쪽으로 굴린다면, 윗면은 오른쪽면으로 이동할 것이고, 오른쪽면은 아랫면으로 이동하고, 아랫면은 왼쪽면으로 이동하고, 왼쪽면은 윗면으로 이동한다.

누군가는 숫자를 이용해서 주사위 굴리는 것을 풀겠지만, 난 그럴 자신이 없다. 그리고 그렇게 코드를 작성하여 남들을 쉽게 이해시킬 자신도 없다.
그래서 조금은 길어보이더라도 직관적으로 보이게 코드를 작성했다.

동쪽으로 굴러가면, 아래 그림과 같은 모양일 것이다.

참고문헌

baekjoon. https://www.acmicpc.net/problem/14499. Baekjoon. (accessed Mar 4, 2022)

이 글이 도움이 되었나요?

신고하기
0분 전
작성된 댓글이 없습니다. 첫 댓글을 달아보세요!
    댓글을 작성하려면 로그인이 필요합니다.