아래와 같은 조건에서 순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때, 각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해라.
엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.
import Foundation
func solution(_ numbers:[Int], _ hand:String) -> String {
var result: String = ""
var leftLocation: [Int] = [0,0]// 두 개의 요소로 좌표를 나타내도록 했음 [0] -> x좌표, [1] -> y좌표
var rightLocation: [Int] = [2,0]
for i in numbers {
if i == 1 || i == 4 || i == 7 {
switch i {
case 1:
result.append("L")
leftLocation = [0, 3]
case 4:
result.append("L")
leftLocation = [0, 2]
case 7:
result.append("L")
leftLocation = [0, 1]
default:
break
}
} else if i == 3 || i == 6 || i == 9 {
switch i {
case 3:
result.append("R")
rightLocation = [2, 3]
case 6:
result.append("R")
rightLocation = [2, 2]
case 9:
result.append("R")
rightLocation = [2, 1]
default:
break
}
} else { // i 가 2, 5, 8, 0인 경우
switch i {
case 2: // [1,3]
if abs(leftLocation[0] - 1) + abs(leftLocation[1] - 3) > abs(rightLocation[0] - 1) + abs(rightLocation[1] - 3) {
result.append("R")
rightLocation = [1, 3]
} else if abs(leftLocation[0] - 1) + abs(leftLocation[1] - 3) < abs(rightLocation[0] - 1) + abs(rightLocation[1] - 3){
result.append("L")
leftLocation = [1, 3]
} else if abs(leftLocation[0] - 1) + abs(leftLocation[1] - 3) == abs(rightLocation[0] - 1) + abs(rightLocation[1] - 3){
if hand == "right" {
result.append("R")
rightLocation = [1, 3]
} else {
result.append("L")
leftLocation = [1, 3]
}
}
case 5: // [1,2]
if abs(leftLocation[0] - 1) + abs(leftLocation[1] - 2) > abs(rightLocation[0] - 1) + abs(rightLocation[1] - 2) {
result.append("R")
rightLocation = [1, 2]
} else if abs(leftLocation[0] - 1) + abs(leftLocation[1] - 2) < abs(rightLocation[0] - 1) + abs(rightLocation[1] - 2) {
result.append("L")
leftLocation = [1, 2]
} else if abs(leftLocation[0] - 1) + abs(leftLocation[1] - 2) == abs(rightLocation[0] - 1) + abs(rightLocation[1] - 2){
if hand == "right" {
result.append("R")
rightLocation = [1, 2]
} else {
result.append("L")
leftLocation = [1, 2]
}
}
case 8: // [1,1]
if abs(leftLocation[0] - 1) + abs(leftLocation[1] - 1) > abs(rightLocation[0] - 1) + abs(rightLocation[1] - 1) {
result.append("R")
rightLocation = [1, 1]
} else if abs(leftLocation[0] - 1) + abs(leftLocation[1] - 1) < abs(rightLocation[0] - 1) + abs(rightLocation[1] - 1) {
result.append("L")
leftLocation = [1, 1]
} else if abs(leftLocation[0] - 1) + abs(leftLocation[1] - 1) == abs(rightLocation[0] - 1) + abs(rightLocation[1] - 1){
if hand == "right" {
result.append("R")
rightLocation = [1, 1]
} else {
result.append("L")
leftLocation = [1, 1]
}
}
case 0: // [1,0]
if abs(leftLocation[0] - 1) + abs(leftLocation[1]) > abs(rightLocation[0] - 1) + abs(rightLocation[1]) {
result.append("R")
rightLocation = [1, 0]
} else if abs(leftLocation[0] - 1) + abs(leftLocation[1]) < abs(rightLocation[0] - 1) + abs(rightLocation[1]) {
result.append("L")
leftLocation = [1, 0]
} else if abs(leftLocation[0] - 1) + abs(leftLocation[1]) == abs(rightLocation[0] - 1) + abs(rightLocation[1]){
if hand == "right" {
result.append("R")
rightLocation = [1, 0]
} else {
result.append("L")
leftLocation = [1, 0]
}
}
default:
break
}
}
}
return result
}
나는 숫자의 키패드를 *이 (0, 0)이고 #이 (2, 0)인 좌표계로 생각했다.
i가 1, 4, 7인 경우와 3, 6, 9인 경우, 그리고 2, 5, 8, 0인 경우로 나눠주었다. 첫 번째 경우와 두 번째 경우는 각각 왼손과 오른손으로 정해져있기 때문에 switch를 이용하여 numbers요소에 대해 L, R을 각각 배열에 넣어줄 수 있도록 하였다. 거리를 계산해야되기 때문에 두 개의 요소를 갖고 있는 배열로 현재 좌표를 나타내주었다.
다음으로 키패드에서 가운데 줄의 번호를 누르는 경우를 보자. 거리가 가까운 손가락으로 눌러줘야하기 때문에 거리를 계산해야한다. 이때 주의할 것은 대각선으로 움직이는 것이 아닌 상하좌우로만 움직일 수 있으므로 거리를 계산할 때에는 두 번호의 |x좌표 차| + |y좌표 차| 를 이용해 구해야한다.
처음에 2580 케이스에서 두 번호의 |x좌표 차| + |y좌표 차|가 왼손이 클 경우, 오른손이 클 경우, 그리고 else 이렇게 나눠줬었다. 근데 테스트케이스에서 실패가 떠서 반례가 있나 계속해서 고민했지만 찾지 못했고 혹시나해서 else대신 "=="를 이용하여 같을 경우로 바꿔주었더니 통과되었다. 크다/ 작다의 나머지가 같은 것이 아니라는 것인데 조금 더 알아봐야 될 것 같다.
좌표를 미리 번호마다 지정해준다면 코드가 더 짧아졌을 것이다. 내 눈엔 이렇게 하는 것이 직관적으로 잘 보인다고 생각하는데 효율성을 따져봐야하므로 다른 방법들도 생각해봐야되는 것 같다.