[프로그래머스] 67256_키패드 누르기 JAVA

최진민·2021년 9월 1일
0

Algorithm_Programmers

목록 보기
10/26
post-thumbnail

67256_키패드 누르기

문제 설명

스마트폰 전화 키패드의 각 칸에 다음과 같이 숫자들이 적혀 있습니다.

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

  • 엄지손가락은 상하좌우 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 이하인 정수입니다.
  • hand는 "left" 또는 "right" 입니다.
    "left"는 왼손잡이, "right"는 오른손잡이를 의미합니다.
  • 왼손 엄지손가락을 사용한 경우는 L, 오른손 엄지손가락을 사용한 경우는 R을 순서대로 이어붙여 문자열 형태로 return 해주세요.

입출력 예 (설명은 생략)


소스코드

import java.util.HashMap;
import java.util.Stack;

class Solution {
    private static StringBuilder sb = new StringBuilder();
    private static Stack<Pos> curL = new Stack<>();
    private static Stack<Pos> curR = new Stack<>();
    private static int disL = 0;
    private static int disR = 0;

    public String solution(int[] numbers, String hand) {
        String answer = "";
        int x, y;
        HashMap<Integer, Pos> hm = new HashMap<>();
        hm.put(1, new Pos(0, 0));
        hm.put(2, new Pos(1, 0));
        hm.put(3, new Pos(2, 0));
        hm.put(4, new Pos(0, 1));
        hm.put(5, new Pos(1, 1));
        hm.put(6, new Pos(2, 1));
        hm.put(7, new Pos(0, 2));
        hm.put(8, new Pos(1, 2));
        hm.put(9, new Pos(2, 2));
        hm.put(0, new Pos(1, 3));

        Pos indicate;
        String lr;
        curL.add(new Pos(0, 3));
        curR.add(new Pos(2, 3));

        for (int number : numbers) {
            switch (number) {
                case 1:
                    sb.append("L");
                    curL.add(hm.get(1));
                    break;
                case 4:
                    sb.append("L");
                    curL.add(hm.get(4));
                    break;
                case 7:
                    sb.append("L");
                    curL.add(hm.get(7));
                    break;
                case 3:
                    sb.append("R");
                    curR.add(hm.get(3));
                    break;
                case 6:
                    sb.append("R");
                    curR.add(hm.get(6));
                    break;
                case 9:
                    sb.append("R");
                    curR.add(hm.get(9));
                    break;
                case 2:
                    indicate = hm.get(2);
                    disL = calculateDistance(indicate, curL.peek());
                    disR = calculateDistance(indicate, curR.peek());
                    lr = returnLR(disL, disR, hand);
                    sb.append(lr);
                    if (lr.equals("L")) {
                        curL.add(indicate);
                    } else {
                        curR.add(indicate);
                    }
                    break;
                case 5:
                    indicate = hm.get(5);
                    disL = calculateDistance(indicate, curL.peek());
                    disR = calculateDistance(indicate, curR.peek());
                    lr = returnLR(disL, disR, hand);
                    sb.append(lr);
                    if (lr.equals("L")) {
                        curL.add(indicate);
                    } else {
                        curR.add(indicate);
                    }
                    break;
                case 8:
                    indicate = hm.get(8);
                    disL = calculateDistance(indicate, curL.peek());
                    disR = calculateDistance(indicate, curR.peek());
                    lr = returnLR(disL, disR, hand);
                    sb.append(lr);
                    if (lr.equals("L")) {
                        curL.add(indicate);
                    } else {
                        curR.add(indicate);
                    }
                    break;
                case 0:
                    indicate = hm.get(0);
                    disL = calculateDistance(indicate, curL.peek());
                    disR = calculateDistance(indicate, curR.peek());
                    lr = returnLR(disL, disR, hand);
                    sb.append(lr);
                    if (lr.equals("L")) {
                        curL.add(indicate);
                    } else {
                        curR.add(indicate);
                    }
                    break;
            }
        }

        return answer = sb.toString();
    }

    private static int calculateDistance(Pos indicate, Pos cur) {
        return Math.abs(indicate.x - cur.x) + Math.abs(indicate.y - cur.y);
    }

    private static String returnLR(int l, int r, String hand) {
        String res;

        if (l < r) {
            res = "L";
        } else if (l > r) {
            res = "R";
        } else {
            if (hand.equals("right")) {
                res = "R";
            } else {
                res = "L";
            }
        }
        return res;
    }

    private static class Pos {
        int x;
        int y;

        public Pos(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
}

Comment

  • HashMapStack을 이용하여 왼손|오른손과 입력받는 수의 거리의 최소를 비교하여 결과를 출력하도록 했다.
  • refactoring을 거치면 좀 더 단순한 코드가 나올 것 같다.

profile
열심히 해보자9999

0개의 댓글