코딩테스트 입문


✔️ 문제 설명

머쓱이는 RPG게임을 하고 있습니다. 게임에는 up, down, left, right 방향키가 있으며 각 키를 누르면 위, 아래, 왼쪽, 오른쪽으로 한 칸씩 이동합니다. 예를 들어 [0,0]에서 up을 누른다면 캐릭터의 좌표는 [0, 1], down을 누른다면 [0, -1], left를 누른다면 [-1, 0], right를 누른다면 [1, 0]입니다. 머쓱이가 입력한 방향키의 배열 keyinput와 맵의 크기 board이 매개변수로 주어집니다. 캐릭터는 항상 [0,0]에서 시작할 때 키 입력이 모두 끝난 뒤에 캐릭터의 좌표 [x, y]를 return하도록 solution 함수를 완성해주세요.

  • [0, 0]은 board의 정 중앙에 위치합니다. 예를 들어 board의 가로 크기가 9라면 캐릭터는 왼쪽으로 최대 [-4, 0]까지 오른쪽으로 최대 [4, 0]까지 이동할 수 있습니다.

제한사항

  • board은 [가로 크기, 세로 크기] 형태로 주어집니다.
  • board의 가로 크기와 세로 크기는 홀수입니다.
  • board의 크기를 벗어난 방향키 입력은 무시합니다.
  • 0 ≤ keyinput의 길이 ≤ 50
  • 1 ≤ board[0] ≤ 99
  • 1 ≤ board[1] ≤ 99
  • keyinput은 항상 up, down, left, right만 주어집니다.
  • 👉 문제 보러가기

입출력 예

keyinput board result
[“left”, “right”, “up”, “right”, “right”] [11, 11] [2, 1]
[“down”, “down”, “down”, “down”, “down”] [7, 9] [0, -4]

입출력 예 설명

입출력 예 설명 #1

  • [0, 0]에서 왼쪽으로 한 칸 오른쪽으로 한 칸 위로 한 칸 오른쪽으로 두 칸 이동한 좌표는 [2, 1]입니다.

입출력 예 설명 #2

  • [0, 0]에서 아래로 다섯 칸 이동한 좌표는 [0, -5]이지만 맵의 세로 크기가 9이므로 아래로는 네 칸을 넘어서 이동할 수 없습니다. 따라서 [0, -4]를 return합니다.


✔️ 문제 풀이

(1) Pseudo-Code

1. 가로 크기와 세로 크기가 제한되어 있기 때문에 제한된 크기를 담는 리스트를 만든다.
2. 처음 시작 좌표를 만든다. (x=0, y=0)
3. 입력되는 키값을 통해 좌표를 측정하기 위해 연산기호를 사용해 다음과 같이 설정한다. left(x-1), right(x+1), top(y+1), down(y-1)
4. 키값을 입력받았을 때 위치가 끝부분이 아니라면 위치변화를 주고, 위치가 공간의 끝부분에 있다면 Pass로 이동하지 않도록 설정한다.

(2) 코드 작성

def solution(keyinput, board):
    ax0 = [board[0]//2*-1, board[0]//2]
    ax1 = [board[1]//2*-1, board[1]//2]
    
    x = 0 # 처음 시작 좌표 (x)
    y = 0 # 처음 시작 좌표 (y)
    
    for k in keyinput:
        if k == "left":
            if x <= ax0[0]:
                pass
            else:
                x -= 1
        elif k == "right":
            if x >= ax0[-1]:
                pass
            else:
                x += 1
        elif k == "up":
            if y >= ax1[-1]:
                pass
            else:
                y += 1
        elif k == 'down':
            if y <= ax1[0]:
                pass
            else:
                y -= 1
    
    return [x, y]

(3) 코드 결과

  • 성능요약 : 메모리 10.1 MB, 시간 0.00 ms
  • 채점결과 : 정확성 100.0, 합계 100.0/100.0

(4) 코드 리뷰 및 회고

  • for문과 if문을 같이 써서 코드가 긴 편인 것 같다.
  • for문과 if문을 동시에 사용해야되는 경우, 코드를 조금 더 간단하게 만들 수 있는 방법을 찾아보다가 삼항연산자로 if문을 줄일 수 있다는 것을 알게되었다.
    • 삼항연산자를 통해 if문을 한 줄로 적을 수 있다.
    • (참일때 값) if (조건) else (거짓일때 값)
  • 이 외에도 코드를 조금 더 간결하게 작성하기 위해 다른사람들의 코드를 보고 따라하는 연습을 통해 더 다양한 방식으로 문제를 해결할 수 있도록 연습을 해보아야겠다.


🌞 실패 코드 공유

def solution(keyinput, board):
    ax0 = [board[0]//2*-1, board[0]//2]
    ax1 = [board[1]//2*-1, board[1]//2]
    
    x = 0 # 처음 시작 좌표 (x)
    y = 0 # 처음 시작 좌표 (y)
    
    for k in keyinput:
        if k == "left":
            x -= 1
        elif k == "right":
            x += 1
        elif k == "up":
            y += 1
        elif k == 'down':
            y -= 1
    
    # 만약 크기를 벗어나는 경우 값을 재할당
    if x <= ax0[0]:
        x = ax0[0]
    elif x >= ax0[-1]:
        x = ax0[-1]
    
    if y <= ax1[0]:
        y = ax1[0]
    elif y >= ax1[-1]:
        y = ax1[-1]
    
    return [x, y]


채점 결과, 테스트 8에서 실패 뜨는 것을 확인


위 코드로 채점을 해보았을 때, 테스트 8번에서 실패가 떴다.
이유를 생각해보다가 문득 문제를 너무 쉽게 생각한 것같다는 생각이 들었다.

✔️ 만약 x범위(-4~+4), y범위(-3~+3)인 상황에서 down down down down down down up을 한다면 위 코드로 생각하면 결과는 [0, -5]가 반환될 것이다.
✔️ 하지만 down은 y가 -3인 이후로는 -3으로 고정되었다가 up이 입력되면 -3에서 -2로 올라갈 것이다.
✔️ 문제가 실패했던 이유는 좌표의 최소, 최대의 범위를 제대로 설정해주지 않은 점이다.
✔️ 키값을 다 숫자로 처리하고 난 뒤에 좌표의 최소, 최대 범위를 넘어가면 범위 설정을 해주었기 때문에 오류가 발생한 것이다.
✔️ 이 점을 깨닫고 키값을 입력받을 때 만약 x의 범위가 벗어나지 않는다는 가정하에 캐릭터의 좌표를 움직여주었고 그게 아니라면 pass를 하여 좌표 변동이 없도록 설정해주었다.

문제를 풀 때, 쉬워보인다고 너무 자만하지 말아야겠다..


👩🏻‍💻개인 공부 기록용 블로그입니다
오류나 틀린 부분이 있을 경우 댓글 혹은 메일로 따끔하게 지적해주시면 감사하겠습니다.

댓글남기기