ericagong / algorithm_solving

2 stars 0 forks source link

[구현] 키패드 누르기 #66

Open ericagong opened 1 year ago

ericagong commented 1 year ago

⭐ 성찰

  1. 코딩테스트 상황에서는 하드 코딩이 더 효과적인 경우가 있음을 명심하고, 불가능하다 싶으면, 바로 하드코딩할 수 있는 자세를 가져야 함.
  2. ⭐ Map 초기화를 위해 Constructor 사용 시, new Map(Iterable) 형태로 제공해야하므로, new Map([[k1, v1], [k2, v2], ...])` 형식으로 반드시 new Map([]) 안에 [] 있음에 주의하기!! ⭐

❓ 문제 상황

키패드 누르기

👨‍💻 문제 해결

✅ 1차 풀이: 객체를 이용한 하드코딩

  1. 왼손으로 누르는 경우, 가운데 경우, 오른손으로 누르는 경우를 별도의 객체로 설정. ㄴ 객체의 key = '번호'/'*'/'#' , value = [x,y] ⭐ 이 때, 객체 키로 들어가는 번호는 문자열로 저장됨에 주의
  2. 초기 왼손과 오른손의 좌표를 지정
  3. numbers를 순회하며, 주어진 로직에 따라 다음에 눌러야 할 손을 result에 추가 ㄴ (1) left, right 자료구조에 속해있으면 해당 손으로 누름 ㄴ (2) middle이면, 현재 왼손/오른손 위치에서 가까운 거리에 있는 손으로 누름 ㄴ (3) 거리가 같다면 주사용 손으로 누름

function solution(numbers, hand) { const left = { 1: [0, 0], 4: [1, 0], 7: [2, 0], "*": [3, 0] }; const middle = { 2: [0, 1], 5: [1, 1], 8: [2, 1], 0: [3, 1] }; const right = { 3: [0, 2], 6: [1, 2], 9: [2, 2], "#": [3, 2] };

let cl = left["*"]; let cr = right["#"]; let result = "";

for (num of numbers) { const key = num.toString(); if (Object.keys(left).includes(key)) { result += "L"; cl = left[key]; } else if (Object.keys(right).includes(key)) { result += "R"; cr = right[key]; } else { let dl = Math.abs(cl[0] - middle[key][0]) + Math.abs(cl[1] - middle[key][1]); let dr = Math.abs(cr[0] - middle[key][0]) + Math.abs(cr[1] - middle[key][1]); if (dl < dr) { result += "L"; cl = middle[key]; } else if (dr < dl) { result += "R"; cr = middle[key]; } else { if (hand === "left") { result += "L"; cl = middle[key]; } else { result += "R"; cr = middle[key]; } } } } return result; }


### ✅ 2차 풀이: Map을 이용한 하드코딩
- 상단 풀이에서 Object를 사용할 수 있는 메서드가 더 많은 Map으로 변경한 풀이
- 따라서 `Object.keys()`로 배열로 변한한 뒤, `Array.prototype.includes(key)` 처리하는 부분 -> `Map.prototype.has(key)`로 간단하게 확인 가능
```javascript

function solution(numbers, hand) {
  const left = new Map([
    [1, [0, 0]],
    [4, [1, 0]],
    [7, [2, 0]],
    ["*", [3, 0]],
  ]);
    const middle = new Map([
        [2, [0, 1]],
        [5, [1, 1]],
        [8, [2, 1]],
        [0, [3, 1]],
    ])
    const right = new Map([
        [3, [0, 2]],
        [6, [1, 2]],
        [9, [2, 2]],
        ["#", [3, 2]],
    ])

  let cl = left.get("*");
  let cr = right.get("#");
  let result = "";

  for (num of numbers) {
    if (left.has(num)) {
      result += "L";
      cl = left.get(num);
    } else if (right.has(num)) {
      result += "R";
      cr = right.get(num);
        } else {
            const [tx, ty] = middle.get(num)
            const [lx, ly] = cl
            const [rx, ry] = cr
      let dl =
        Math.abs(lx - tx) + Math.abs(ly - ty);
      let dr =
        Math.abs(rx - tx) + Math.abs(ry - ty);
      if (dl < dr) {
        result += "L";
        cl = [tx, ty];
      } else if (dr < dl) {
        result += "R";
        cr = [tx, ty];
      } else {
        if (hand === "left") {
          result += "L";
          cl = [tx, ty];
        } else {
          result += "R";
          cr = [tx, ty];
        }
      }
    }
  }
  return result;
}