키패드 누르기

알파로그·2023년 3월 12일
0

✏️ 문제 설명

전화 키패드에서 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.
맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며,
엄지손가락을 사용하는 규칙은 다음과 같습니다.

  • 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
  • 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
  • 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
  • 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
  • 4-1. 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.

순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때,
각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.

✏️ 제한 사항

  • numbers 배열의 크기는 1 이상 1,000 이하입니다.
  • numbers 배열 원소의 값은 0 이상 9 이하인 정수입니다.
  • 왼손 엄지손가락을 사용한 경우는 L, 오른손 엄지손가락을 사용한 경우는 R을 순서대로 이어붙여 문자열 형태로 return 해주세요.

✏️ 문제 풀이

📍 첫번째 풀이 - 실패

이클립스 에디터에서는 정상적으로 작동하는데
문제 풀이 컴파일러에서는 뒤에서 3번째 값이 자꾸 L 로 나온다..
디버깅 하면서 리뷰를 아무리해도 문제점을 못찾겠다..
애초에 디버깅이 이클립스밖에 안되기 때문에 이클립스는 잘 작동되서 문제를 찾기가 어렵다..

📍 실패 원인 분석

numbers 1번 요소가 3번이기 때문에 무조건 오른손이 누르고
5번 요소가 2번인데
왼손은 8번에 위치 / 오른손은 3번에 그대로 있다
1칸 차이로 오른손이 2번으로 이동

문제의 8번 요소는 5번
오른손은 그대로 3번 / 왼손은 4번
양손다 1칸 밖에 차이가 안난다
따라서 주로쓰는 손인 오른손이 와야한다
하지만 콘솔은 왼손이 나온다..
도대체 무엇이 문제인가.....

버전이 다른문제인가??

public static void main(String[] args) {
		
		int []numbers = {1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5};
		String answer = "";
		String hand = "right";
		
		//-----------------------------------------//
		
        // 번호를 나름대로 쉽게 관리하기 위해 번호들을 2차원 배열에 담았다.
		int [][] nb = {
				{1, 4, 7, 11},    // 왼손이 누르는 부분
				{2, 5, 8, 0},   // 양손 다 누를 수 있는 부분
				{3, 6, 9, 12},    // 오른손이 누르는 부분
				};
        
        // 눌러야 하는 거리를 구하기 위해서 0,1 번 요소는 현재 위치,
        // 2, 3 번 요소는 현 위치 (0,1) 과 눌러야하는 곳의 위치를 뺀 값을 넣을 예정이다.
		int []h1 = {0,3,0,0};
		int []h2 = {2,3,0,0};
        // 오른손 왼손잡이 개념이 있기 때문에 코드의 중복을 없애기 위해
        // 왼손잡이일 경우 h1 이 왼손, 오른손 잡이일경우 h2가 왼손이 되게 코드를 만들어봤다.
		String hand2 = "";
		if (hand == "right") {
			hand = "R"; hand2 = "L";
			h1[0] =2; h2[0] =0;
		}else {hand ="L"; hand2= "R";}
    
		  // 본격적으로 버튼을 누르는 손을 확인하는 코드 (2차원 배열이기 때문에 j for문 k for 문 이중으로 만들었다.)
		for (int i = 0; i<numbers.length ; i++) {
    
      // 코드의 효율성을 위해 원하는 값을 찾을경우 break를 걸어두었는데
      // 2차원 배열이기 때문에 j for문에서 한번 더 break 를 걸어 줘야 했다.
      // 값을 찾지 않아도 break 가 발동 되는걸 막기위해 값을 찾은후 3번 요소에 표시를 해두었고
      // 다시 새로운 루프를 돌기위해 3번 요소를 초기화 해주었다.
			h1[3]= 0; 
			for (int j = 0; j<3 ; j++) {      // 2차원 배열의 첫번째 값
				for (int k = 0 ; k<4 ; k++) {   // 2차원 배열의 두분째 값
        
                  // 덩어리를 크게 3가지로 나누었다.
                  // 0번 라인은 왼손만 누를 수 있어서 조건을 0으로 걸어놓았더니
                  // j 의 좌표가 특정되지 않아서 && 로 두가지 조건 모두 충족시킬수 있게 만들었다.
					if (numbers[i] == nb[0][k] && numbers[i] == nb[j][k]) {
						if (hand.equals("L")) {
							answer += "L";
							h1[0] =j ; h1[1] = k; h1[3]= 11;    //좌표 수정 밎 3번 요소 표시
						}else {
							answer += "L";
							h2[0] =j ; h2[1] = k; h1[3]= 11;
						}break;
            
            // 오른손만 누를 수 있는 위치
					}else if(numbers[i] == nb[2][k] && numbers[i] == nb[j][k]) {
						if (hand.equals("R")) {
							answer += "R";
							h1[0] =j ; h1[1] = k; h1[3]= 11;
						}else {
							answer += "R";
							h2[0] =j ; h2[1] = k; h1[3]= 11;
						}break;
					}
          
              // 양손 모두 누를 수 있는 위치
					else if (numbers[i] == nb[1][k] && numbers[i] == nb[j][k]) {
                    // 가까운 값을 찾기 위해 각 좌표를 빼주고 자연수로 치환해 음수가 나오는걸 방지했다.
						h1[2] = Math.abs(h1[0]-j); h1[3] = Math.abs(h1[1]-k);
						h2[2] = Math.abs(h2[0]-j); h2[3] = Math.abs(h2[1]-k);
            
                    //주 손의 위치가 반대 손의 위치보다 가깝거나 같을경우
						if(h1[2]+h1[3] <= h2[2]+h2[3]) {
							answer += hand;
							h1[0] =j ; h1[1] = k; h1[3]= 11;
              
                    // 주 손의 위치가 더 멀 경우
						}else {
							answer += hand2;
							h2[0] =j ; h2[1] = k; h1[3]= 11;
						}break;
					}
				}
            // 값을 찾은경우 불필요한 루프를 멈추는 
			if(h1[3] == 11) break;}
		}
		System.out.print(answer);

오류 찾는걸 포기하고 다른방법으로 새로운 코드를 생각해봐야겠다..
오류의 원인은 나중에 실력을 더 쌓은 후 다시 살펴봐야겠다

📍 문제 원인 발견

첫번째 if 문
if (hand == "right") {
가 잘못되었었다..

이유는 모르겠지만 컨파일러에서는 String을 == 로 비교하면 정확한 비교가 안된다
컨파일러에서 String 을 비교할 때 항상
.equals() 를 사용하자
수정하니까 이상없이 작동하네..

지난번에도 이걸로 고생하고 또 당하다니..
앞으로는 이런걸로 시간 허비하지 말자..

[문제 원본]

profile
잘못된 내용 PR 환영

0개의 댓글