순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때, 각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.
자세한 내용은 해당 사이트에서 확인할 수 있음
(https://programmers.co.kr/learn/courses/30/lessons/67256)
import java.util.*;
class Solution {
static int distance(int[] thumb, int[] num) {
int dis_x = Math.abs(thumb[0] - num[0]);
int dis_y = Math.abs(thumb[1] - num[1]);
return (dis_x+dis_y);
}
public String solution(int[] numbers, String hand) {
// 정답 리스트
StringBuilder answer = new StringBuilder();
// 시작점 위치 부여
int[] l_thumb = {3, 0};
int[] r_thumb = {3, 2};
// 숫자에 위치 부여
int[][] num_pos = new int[10][2];
num_pos[0][0] = 3;
num_pos[0][1] = 1;
for(int i=1; i<num_pos.length; i++) {
num_pos[i][0] = (i-1)/3;
num_pos[i][1] = (i-1)%3;
}
// 숫자를 입력받음
for(int number : numbers) {
switch(number) {
case 1:
case 4:
case 7:
l_thumb = num_pos[number];
answer.append("L");
break;
case 3:
case 6:
case 9:
r_thumb = num_pos[number];
answer.append("R");
break;
default:
// 엄지와 숫자의 거리 계산
int r_dis = distance(r_thumb, num_pos[number]);
int l_dis = distance(l_thumb, num_pos[number]);
// 거리 비교
if(r_dis < l_dis) {
r_thumb = num_pos[number];
answer.append("R");
}
else if(r_dis > l_dis) {
l_thumb = num_pos[number];
answer.append("L");
}
else {
if(hand.equals("right")) {
r_thumb = num_pos[number];
answer.append("R");
}
else {
l_thumb = num_pos[number];
answer.append("L");
}
}
break;
}
}
return answer.toString();
}
}
이 문제의 핵심은 각 버튼에게 어떻게 위치를 부여할 것인가이다.
필자는 2차원 배열로 위치를 나타내었다.
다른 방법도 있겠지만, 배열이 가장 깔끔하다고 생각한다.
// 시작점 위치 부여
int[] l_thumb = {3, 0};
int[] r_thumb = {3, 2};
// 숫자에 위치 부여
int[][] num_pos = new int[10][2];
num_pos[0][0] = 3;
num_pos[0][1] = 1;
for(int i=1; i<num_pos.length; i++) {
num_pos[i][0] = (i-1)/3;
num_pos[i][1] = (i-1)%3;
}
그 다음부턴 간단하다.
숫자를 하나받고, 손가락 위치를 해당 버튼으로 이동해주면 된다.
이때 숫자가 1,4,7이냐 3,6,9이냐 2,5,8,0이냐에 따라 달라지므로 이 부분을 분기 처리해주면 되는데, 나는 switch를 사용하였다.
if-else로 처리하면 if부터 차례대로 조건을 검사하며 내려오지만,
switch는 바로 해당 case로 이동하기 때문이다.
물론 분기가 2개뿐이라 상관은 없겠지만, 가독성 부분에도 switch가 좀 더 낫다고 생각하였다.
// 숫자를 입력받음
for(int number : numbers) {
switch(number) {
// 1, 4, 7 처리
case 1:
case 4:
case 7:
. . .
break;
// 3, 6, 9 처리
case 3:
case 6:
case 9:
. . .
break;
// 2, 5, 8, 0 처리
default:
. . .
break;
}
}
문제를 보면, 버튼에서 각 손가락까지의 거리에 따라 어떤 손으로 누를지가 달라진다.
따라서 distance()를 정의하여 거리를 계산하고, 이를 분기 처리해서 누를 손가락을 정했다.
// 엄지와 숫자 사이의 거리 계산
static int distance(int[] thumb, int[] num) {
int dis_x = Math.abs(thumb[0] - num[0]);
int dis_y = Math.abs(thumb[1] - num[1]);
return (dis_x+dis_y);
}
처음 접했을 때 숫자에 위치를 부여하는데 고심하였다.
배열말고 뭔가 더 효율적인 것이 없을까 고민하다 결국 이도저도 아니게 된 것이다.
해보지도 않고 효율성을 따지는 건 좋지 않다.
너무 많이 생각하지 말고, 일단 시도해보자!
두번째는 거리 계산이었다.
distance()의 return값을 "a^2+b^2"의 형태로 썼더니, 13~20까지 모두 테스트 실패하였다.
이 부분은 솔직히 왜 그런지 잘 모르겠다.
제곱으로 인해서 엇나가는 흐름이 뭐가 있는지 생각을 해봐야 할 것 같다.