문제
스마트폰 전화 키패드의 각 칸에 다음과 같이 숫자들이 적혀 있습니다.
이 전화 키패드에서 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.
맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며, 엄지손가락을 사용하는 규칙은 다음과 같습니다.
- 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
- 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
- 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
- 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
- 4-1. 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.
순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때, 각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.
numbers |
hand |
result |
[1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] |
“right” |
“LRLLLRLLRRL” |
[7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2] |
“left” |
“LRLLRRLLLRR” |
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0] |
“right” |
“LLRLLRLLRL” |
1차답안
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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| class Solution { public String solution(int[] numbers, String hand) { String answer = ""; int [] left = {1,4,7}; int [] right = {3,6,9}; int [] middle = {2,5,8,0}; int leftFg = 0, rightFg = 0, currentFg = 0; int rightLoc= 0, leftLoc = 0, currentLoc = 0; for(int number: numbers) { if (contains(number, left)){ answer += "L"; leftFg = number; currentFg = number; } else if (contains(number, right)) { answer += "R"; rightFg = number; currentFg = number; } else { currentLoc = locationFg(number); rightLoc = Math.abs(currentLoc - locationFg(rightFg)); leftLoc = Math.abs(currentLoc - locationFg(leftFg)); if(rightLoc > leftLoc){ answer += "L"; leftFg = number; currentFg = number; } else if(rightLoc < leftLoc){ answer += "R"; rightFg = number; currentFg = number; } else { if(contains(leftFg, middle) && contains(rightFg, middle)){ if("left".equals(hand)){ answer += "L"; leftFg = number; currentFg = number; } else { answer += "R"; rightFg = number; currentFg = number; } } else if (contains(rightFg, middle)){ answer += "R"; rightFg = number; currentFg = number; } else if (contains(leftFg, middle)){ answer += "L"; leftFg = number; currentFg = number; } else { if("left".equals(hand)){ answer += "L"; leftFg = number; currentFg = number; } else { answer += "R"; rightFg = number; currentFg = number; } } } } } return answer; } public boolean contains(int key ,int[] arrays){ return Arrays.stream(arrays).anyMatch(i -> i == key); } public int locationFg(int key){ switch(key) { case 1: case 2: case 3: return 1; case 4: case 5: case 6: return 2; case 7: case 8: case 9: return 3; default: return 4; } } }
|
CASE1 통과 불가
- 4/5 일경우
테스트 1
입력값 〉 [1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5], “right”
기댓값 〉 “LRLLLRLLRRL”
실행 결과 〉 실행한 결괏값 “LRLLLRLLLRL”이(가) 기댓값 “LRLLLRLLRRL”와(과) 다릅니다.
leftFg = 2
rightFg = 4
currentFg = 5
hand = right 이므로 R값이 들어가야하지만 CASE 문으로 ROW 형태로 관리되었기때문에 해당 관련 로직 해결하지 못함
2차답안
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
| class Solution { public String solution(int[] numbers, String hand) { String answer = ""; int leftFg = 10, rightFg = 12; int rightDis= 0, leftDis = 0; for(int number: numbers) { if(number == 0) number = 11; switch(number % 3) { case 0: answer += "R"; rightFg = number; break; case 1: answer += "L"; leftFg = number; break; case 2: leftDis = Math.abs(number - leftFg) % 3 + Math.abs(number - leftFg) / 3; rightDis = Math.abs(number - rightFg) % 3 + Math.abs(number - rightFg) / 3; if(leftDis > rightDis) { answer += "R"; rightFg = number; } else if(leftDis < rightDis){ answer += "L"; leftFg = number; } else { if("left".equals(hand)){ answer += "L"; leftFg = number; } else { answer += "R"; rightFg = number; } } break; } } return answer; } }
|
중요한 개념으로 거리는 절대값(위치-FG)/3 + 절대값(위치-FG)%3
일떄 만약 ‘5’ 를 검색한다면 left = 4 right = 2 이므로
leftFg
(5-2) /3 => 1
(5-2) %3 => 0
rightFg
(5-4) /3 => 0
(5-4) %3 => 1
leftFg = 0 / rightFg = 0 즉 거리가 같으므로 hand가 right이므로 R값이 + 되어야한다.