hoon DevLog

[Java] 프로그래머스 키패드 누르기 자바 본문

코딩테스트/프로그래머스

[Java] 프로그래머스 키패드 누르기 자바

개발한기발자 2022. 6. 18. 12:42
반응형

문제 출처 : https://programmers.co.kr/learn/courses/30/lessons/67256

 

코딩테스트 연습 - 키패드 누르기

[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"

programmers.co.kr


문제에 텍스트가 많아지면

여김없이 찾아오는 난독증.....

하지만 그럼에도 불구하고 풀어야 한다

 

"우리는 답을 찾을 것이다. 늘 그랬듯이."

-인터스텔라-

[나의 풀이]

- 우리가 스마트폰을 사용할 때, 왼손은 왼쪽, 오른손은 오른쪽을 사용하여 고정으로 사용하는 좌/우측 패드 배열 선언

- '*' 과 '#' 버튼은 숫자가 아니므로 계산을 쉽게 하기 위해 각각 *=10, #=12로 대치

- 화면에서 보이는 전체 키패드를 가진 2차원 배열 선언

- 2차원 배열 기준, 왼손의 처음 위치는 '*'(mainKey[3][0]), 오른손은 '#'(mainKey[3][2])이고 그림은 다음과 같다.

1
mainKey[0][0]
2
mainKey[0][1]
3
mainKey[0][2]
4
mainKey[1][0]
5
mainKey[1][1]
6
mainKey[1][2]
7
mainKey[2][0]
8
mainKey[2][1]
9
mainKey[2][2]
*
mainKey[3][0]
0
mainKey[3][1]
#
mainKey[3][2]

 


  
import java.util.Arrays;
public class Solution {
public String solution(int[] numbers, String hand) {
String answer = "";
Integer[] keypadL = {1,4,7,10}; //왼쪽손 고정 키패드, *=10
Integer[] keypadR = {3,6,9,12}; //오른쪽손 고정 키패드, #=12
Integer[][] mainKey = { //실제 키패드판
{1,2,3},
{4,5,6},
{7,8,9},
{10,0,12}
};
int xl = 3; //왼손 엄지 처음 위치
int yl = 0;
int xr = 3; //오른손 엄지 처음 위치
int yr = 2;
for (int i=0; i<numbers.length ; i++) { //누를 버튼 만큼 반복
int pushNo = numbers[i];
int rLen=0, lLen=0; //각 손과 누를 버튼 위치의 거리를 담을 변수
for (int j=0; j< mainKey.length; j++) {
for (int k=0; k< mainKey[k].length ; k++) { //실제 키패드판과 누를 버튼과 같은값 찾을때 까지 반복
if (pushNo == mainKey[j][k]){
if(Arrays.asList(keypadL).contains(pushNo)){ //왼쪽고정
answer += "L";
xl = j;
yl = k;
}else if(Arrays.asList(keypadR).contains(pushNo)){//오른쪽고정
answer += "R";
xr = j;
yr = k;
}else{ //가운데 줄인 경우, 절대값으로 좌/우측 가까운 거리 확인
rLen = Math.abs(xr-j) + Math.abs(yr-k);
lLen = Math.abs(xl-j) + Math.abs(yl-k);
if(rLen < lLen){
answer+="R";
xr = j;
yr = k;
}else if(rLen > lLen){
answer+="L";
xl = j;
yl = k;
}else{ //같을 때 주손으로 판별하기
if (hand.equals("right")){
answer+="R";
xr = j;
yr = k;
}else{
answer+="L";
xl = j;
yl = k;
}
}
}
}else{
continue;
}
}
}
}
return answer;
}
}

으으.....정말 내가 짜고 돌아가는 코드지만 정말 극혐이다...

19년도의 여파였을까? 덕분에 20년도 문제는 선녀였지만...

나의 풀이는 너무 역하다ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

설마 이런 문제도 Stream으로 되는건 아니겠...지??...

[다른 사람의 풀이-1]


  
class Solution {
//0부터 9까지 좌표 {y,x}
int[][] numpadPos = {
{3,1}, //0
{0,0}, //1
{0,1}, //2
{0,2}, //3
{1,0}, //4
{1,1}, //5
{1,2}, //6
{2,0}, //7
{2,1}, //8
{2,2} //9
};
//초기 위치
int[] leftPos = {3,0};
int[] rightPos = {3,2};
String hand;
public String solution(int[] numbers, String hand) {
this.hand = (hand.equals("right")) ? "R" : "L";
String answer = "";
for (int num : numbers) {
String Umji = pushNumber(num);
answer += Umji;
if(Umji.equals("L")) {leftPos = numpadPos[num]; continue;}
if(Umji.equals("R")) {rightPos = numpadPos[num]; continue;}
}
return answer;
}
//num 버튼을 누를 때 어디 손을 사용하는가
private String pushNumber(int num) {
if(num==1 || num==4 || num==7) return "L";
if(num==3 || num==6 || num==9) return "R";
// 2,5,8,0 일때 어디 손가락이 가까운가
if(getDist(leftPos, num) > getDist(rightPos, num)) return "R";
if(getDist(leftPos, num) < getDist(rightPos, num)) return "L";
//같으면 손잡이
return this.hand;
}
//해당 위치와 번호 위치의 거리
private int getDist(int[] pos, int num) {
return Math.abs(pos[0]-numpadPos[num][0]) + Math.abs(pos[1]-numpadPos[num][1]);
}
}

[정리]

- 핵심은 눌러야 할 버튼의 거리계산, 가운데 줄 버튼 시 조건, 주 사용손에 따른 조건을 나누는 것이 관건!

- 각종 조건과 반복을 해야하는 상황이 발생 하다보니 for문과 if문이 많아질 수 밖에 없는 문제...

- 함수를 기능별로 분리해서 코딩하는 방법을 통해, 좀 더 기능별로 알아보기 쉽게 하는 것도 중요할 듯!

 

개인피셜 난이도 : ★☆☆

다소 노가다가 요구되는 문제이지만,

노가다도 빠른 사고로 이해하고 정리하는게 중요한 것 같다!

저번 2019년 문제에 비하면 그렇게 어렵지 않은 문제였다.

모든 알고리즘 문제가 그렇겠지만,

규칙과 패턴을 빨리 파악하는게 중요한 것 같다.

 

뭔가 카카오 문제를 연이어 해결하니 뿌듯하지만,

하지만 이 역시 1단계! 1단계이기 때문에,

정진, 또 정진!!!!!!

 

끝!

728x90
반응형