[프로그래머스] 카카오 인턴 키패드 누르기

mango·2023년 6월 24일
0

* Things I leant

1. 유클리드 거리 계산법 vs 피타고라스 정리 계산법

(0,0) 에서 (1,1) 까지의 거리는,

  • 유클리드 계산법으로 가로 1 + 세로 1 해서 2
  • 피타고라스 계산법으로 대각선 길이이므로 루트2

즉, 유클리드 계산법은 대각선으로 가로질러 이동하지 못할 때의 거리 계산법이다.

2. HashMap value로 array 넣기

        int [] currentP = new int[2];
        HashMap<Integer, int[]> hm = new HashMap<Integer, int[]>();

3. 자바에 getDistance라는 함수는 없는걸로..

4. 절대값 함수 Math.abs()

import java.Math.*;

int a = Math.abs(-199); 	// a = 199

5. 자바는 String a += 'O'; 하면 바로 덧붙어짐 즉, +로 string 붙일 수 있음

6. String 비교

a.equals(b) == true

* 알고리즘

  1. 키패드 마다 좌표를 만듦
  2. 현재 오른손과 왼손의 위치도 right와 left로 만듦
  3. 1,4,7 3,6,9는 L, R로 지정하고 위치도 넣어줌
  4. 2,5,8,0은 유클리드 거리 계산법(x좌표, y좌표 절대값 후 더하기)으로 계산하여 가까운 손을 지정

* 자바코드

- (1차 시도)

거리계산을.. 피타고라스 정리로 접근함
-> Math 함수 pow랑 sqrt 도 몰라서 검색 전에 구현도 못함
-> getDistance 함수가 있는줄 알았는데 자꾸 에러나서 있는지 없는지도 모르겠음

그리고 같은 기능은 함수화 해야하는데 callbyvalue, callbyinstance 헷깔려서 함수화도 안함
-> 엉망진창 코드다 진심

HashMap에 숫자의 위치 저장하려 했는데 HashMap에 Object 넣는 개념도 헷깔려서 이것도 구현 못함;

import java.util.*;

class Solution {
    public String solution(int[] numbers, String hand) {
        String answer = "";
        int left[] = {0, 0};
        int right[] = {0, 0};
        //ArrayList<Integer> currentP = new ArrayList<Integer>();
        int [] currentP = new int[2];
        HashMap<Integer, int[]> hm = new HashMap<Integer, int[]>();
            
        int num = 1;
        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
//                currentP.add(0, i);
//                currentP.add(1, j);
                currentP[0] = i;
                currentP[1] = j;
                hm.put(num, currentP);
                num++;
            }
        }
        
        for(int i = 0; i < numbers.length; i++){
            if (numbers[i] == '1' ||numbers[i] == '4' ||numbers[i] == '7'){
                answer += 'L';
                left = hm.get(numbers[i]);
            }
            else if (numbers[i] == '3' ||numbers[i] == '6' ||numbers[i] == '9'){
                answer += 'R';
                right = hm.get(numbers[i]);
            }
            else
            {
                double distanceL = getDistance(hm.get(numbers[i])[0], hm.get(numbers[i])[1], left[0], left[1]);
                double distanceR = getDistance(hm.get(numbers[i])[0], hm.get(numbers[i])[1], right[0], right[1]);
                if(distanceL < distanceR){
                    answer += 'L';
                    left = hm.get(numbers[i]);
                }
                else if(distanceL > distanceR){
                    answer += 'R';
                    right = hm.get(numbers[i]);
                }
                else{
                    if(hand.equals("right")){
                        answer += 'R';
                        right = hm.get(numbers[i]);
                    }
                    else{
                        answer += 'L';
                        left = hm.get(numbers[i]); 
                    }
                }
            }
            System.out.println(getDistance(1, 1, 2, 2));
        }
        
        return answer;
    }
}

- 이상한거에서 계속 시간 쏟음

-> 잘못된 코드

계속 2,2로만 들어가서 한 1시간 이것 붙잡고 있었다. 아니 도대체 왜? 이해할 수가 없었는데 드디어 이해감.
1:{0,1}
2:{0,2}
3:{0,3}
4:{1,0}
내가 원하던 hm의 모양은 이거였다. 근데 계속 2,2만 들어가는것

currentP가 한번 선언되었기 때문에, 값이 달라져도 currentP는 하나밖에 만들어지지 않아서 안에 값이 for문을 돌며 달라져도 주소는 계속 똑같았기 때문에 결국 마지막 값인 2,2로 모두 지정된 것

-> 올바른 코드

  • new로 currentP도 계속 선언해주면서 9개의 currentP를 만들고 값을 지정해줬더니 원하던 대로 들어감.

- (2차 시도)

import java.util.*;

class Solution {
    public String solution(int[] numbers, String hand) {
        String answer = "";
        int left[] = {3, 0};
        int right[] = {3, 2};
        int [] currentP;
  		// 키패드 숫자와 좌표값 설정해줄 HashMap 선언
        HashMap<Integer, int[]> hm = new HashMap<Integer, int[]>();

  		// 키패드와 키패드 좌표값 설정
        int num = 1;
        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
                currentP = new int[2];
                
                currentP[0] = i;
                currentP[1] = j;
                hm.put(num, currentP);
                num++;
            }
        }
        // 0은 따로 설정해줌
  		int [] temp = {3,1};
        hm.put(0, temp);
        
  		
        for(int i = 0; i < numbers.length; i++){
            //1,4,7은 왼손
            if (numbers[i] == 1 ||numbers[i] == 4 ||numbers[i] == 7){
                answer += 'L';
                left = hm.get(numbers[i]);
            }
            //3,6,9는 오른손
            else if (numbers[i] == 3 ||numbers[i] == 6 ||numbers[i] == 9){
                answer += 'R';
                right = hm.get(numbers[i]);
            }
                                          
            //여기서 거리는 피타고라스 정리 거리 아님!!!!
			//유클리드 거리 계산법이라고, 가로 세로로 가는 방법 = 절대값과 합으로 계산                           
            else
            {
                int distanceL = Math.abs(hm.get(numbers[i])[0] - left[0]) + Math.abs(hm.get(numbers[i])[1] - left[1]);
                int distanceR = Math.abs(hm.get(numbers[i])[0] - right[0]) + Math.abs(hm.get(numbers[i])[1] - right[1]);
                                          
                if(distanceL < distanceR){
                    answer += 'L';
                    left = hm.get(numbers[i]);
                }
                else if(distanceL > distanceR){
                    answer += 'R';
                    right = hm.get(numbers[i]);
                }
  				// 거리가 같을 때는 잡이를 보고 결정
                else{
                    if(hand.equals("right")){
                        answer += 'R';
                        right = hm.get(numbers[i]);
                    }
                    else{
                        answer += 'L';
                        left = hm.get(numbers[i]); 
                    }
                }
            }
        }
        
        return answer;
    }
}
  


-> 함수화 해서 코드 많이 줄일 수 있을 것 같은데 귀찮다...

profile
앎의 즐거움을 아는 나는 mango ♪

0개의 댓글