그냥 각 키패드를 좌표 (배열)로 생각하고 하면 전혀 어려울 게 없는 문제다.
그런데 좌표 하드코딩하는 게 자존심 상해서 다른 방법을 찾아 헤매다가 3시간을 날렸다.
근데 기껏 풀고나서 확인해보니 그냥 배열 하드코딩하는 게 더 직관적이고 깔끔하다.
쩝.. 물론 내가 조금 희한하게 풀기도 했다.
아무튼 문제를 풀고 싶어서 찾아온 누군가가 있을 수 있으니 빠르게 설명하겠다.
키패드의 *, 0, #을 10, 11, 12로 치환하고
y축을 각 숫자 n에 대해 n-1/3을 한다면 0,1,2,3을 얻을 수 있다.
x축도 마찬가지로 각 숫자 n에 대해 n-1%3을 한다면 0,1,2를 얻을 수 있다.
이게 배열을 하드코딩하지 않고 푸는 방법이고.
만약 좌표를 하드코딩할 거라면 저건 필요 없다.
다만 n에 대해 n%3을 했을 때 x축은 각각 1,2,0을 얻을 수 있다는 점을 활용해 조건문을 조금이나마 간소화시킬 수 있다.
몰라도 푸는 것에 아무 지장 없음.
성의 없어보일 수도 있지만 여기까지 봤으면 다 본 것이다.
혹시 여기까지 봤어도 못 풀겠다면 조금만 더 내려보자.
1. n은 우리가 임의로 11이라고 정한 거지 문제에서는 0으로 들어온다.
n을 변경해주고 있는지 확인해보자.
2. 좌표 거리 계산은 그냥 x축 y축 각각 빼주고 절대값으로 반환 받으면 그만이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
class Solution {
public String solution(int[] numbers, String hand) {
int left = 10;
int right = 12;
StringBuilder sb = new StringBuilder();
for (int n : numbers) {
if ( n == 0 ) { n = 11; }
if ( n%3 == 1 ) {
left = n;
sb.append("L");
}
if ( n%3 == 2 ) {
if (getPosition(left,right,n).equals("LEFT")) {
left = n;
sb.append("L");
}
else if (getPosition(left,right,n).equals("RIGHT")) {
right = n;
sb.append("R");
}
else {
if (hand.equals("left")) {
left = n;
sb.append("L");
} else {
right = n;
sb.append("R");
}
}
}
if ( n%3 == 0 ) {
right = n;
sb.append("R");
}
}
return sb.toString();
}
public String getPosition(int left, int right, int num) {
int leftX = (left-1)/3;
int leftY = (left-1)%3;
int rightX = (right-1)/3;
int rightY = (right-1)%3;
int numX = (num-1)/3;
int numY = (num-1)%3;
int resultL = Math.abs(leftX-numX) + Math.abs(leftY-numY);
int resultR = Math.abs(rightX-numX) + Math.abs(rightY-numY);
if (resultL == resultR) return "DRAW";
return (resultL > resultR) ? "RIGHT" : "LEFT";
}
}
|
cs |
첫번째 방식.
아마 별다른 설명이 없어도 위에 좌표 구하는 방법을 설명해놨으니 다 이해가 될 것이다.
String으로 반환해서 답을 구하는 특이한 행동을 했는데 왜 그랬는지는 모르겠다..
너무 오래동안 한 문제만 보다보니 잠시 영혼이 가출했었나보다.
리팩터링으로 코드를 조금 더 짧게 만들 수는 있지만, 이미 내가 생각한 것보다 너무 복잡하게 만들어져서 의욕을 상실했다
내가 이걸 작성하기 위해 3시간을 썼다고..?
다른 사람들 풀이도 찾아봤는데 큰 틀에서는 별 차이가 없다.
가독성도 여전히 구리다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
class Solution {
public String solution(int[] numbers, String hand) {
int[][] keypad = { {0,0}, {0,1}, {0,2},
{1,0}, {1,1}, {1,2},
{2,0}, {2,1}, {2,2},
{3,0}, {3,1}, {3,2} };
StringBuilder sb = new StringBuilder();
int left = 10;
int right = 12;
for ( int n : numbers ) {
if (n==0) n=11;
if (n%3 == 0) {
right = n;
sb.append("R");
}
if (n%3 == 1) {
left = n;
sb.append("L");
}
if (n%3 == 2) {
int distanceFromLeft = getDistance(keypad[left-1], keypad[n-1]);
int distanceFromRight = getDistance(keypad[right-1], keypad[n-1]);
if ( distanceFromLeft > distanceFromRight ) {
right = n;
sb.append("R");
}
if ( distanceFromLeft < distanceFromRight ) {
left = n;
sb.append("L");
}
if ( distanceFromLeft == distanceFromRight ) {
if ( hand.equals("right") ) {
right = n;
sb.append("R");
} else {
left = n;
sb.append("L");
}
}
}
}
return sb.toString();
}
public static int getDistance(int[] keypadPos, int[] numPos) {
int y = Math.abs(keypadPos[0] - numPos[0]);
int x = Math.abs(keypadPos[1] - numPos[1]);
return x+y;
}
}
|
cs |
두번째 방식. 내 기준에서는 그냥 좌표 하드코딩하는 게 제일 깔끔해 보이더라.
나는 빨리 풀고 공부하고 싶어서 if로 도배했는데 switch를 활용하면 훨씬 더 보기 좋아질 것 같다.
'CS ﹒ Algorithm > Programmers' 카테고리의 다른 글
프로그래머스 문제풀이 (7) 신고 결과 받기 (0) | 2022.08.24 |
---|---|
프로그래머스 문제풀이 (6) 성격 유형 검사하기 (0) | 2022.08.19 |
Java 프로그래머스 문제풀이 (4) 없는 숫자 더하기 (0) | 2022.08.11 |
JAVA 프로그래머스 문제풀이 (3) 소수 만들기 (0) | 2022.07.25 |
프로그래머스 문제 풀이 (2) 완주하지 못한 선수 (0) | 2022.07.24 |