[Level2] 13. 60 ~ 64 (dp 미완성!)




연습문제 먼저 풀고, 자료구조 하기 && 연습문제 푸는 동안은 하루 5문제!


60. 행렬의 곱셈 🤔

프로그래머스

function solution(arr1, arr2) {
  let answer = [];
  let sum = 0;
  let temp = [];
  for (let i = 0; i < arr1.length; i++) {
    for (let k = 0; k < arr2[0].length; k++) {
      for (let j = 0; j < arr2.length; j++) {
        sum = sum + arr1[i][j] * arr2[j][k];
      }
      temp.push(sum);
      sum = 0;
    }
    answer.push(temp);
    temp = [];
  }
  return answer;
}

후.. 우선… 행렬의 곱셈 방법을 까먹었다.
선형대수학때 배우고 처음 보는 느낌…ㅋㅋㅋㅋ
수학적 풀이방식을 검색해본뒤에 열심히 짜보려 했지만,,, 실패였다.ㅠ
다른 분의 코드를 참고해서 풀었다.
2중 for문으로만 하려다보니 막혔는데 3중 for문을 쓰면 되는 일이었다.
하지만 아직 뭔가 규칙성을 찾아서 3중 for문을 쓰는게 어렵게 느껴진다ㅠㅠ
이문제는 익숙해질때까지 매일 보면서 행렬에 익숙해지도록 해야겠다..!


best 풀이

function solution(arr1, arr2) {
    return arr1.map((row) => arr2[0].map((x,y) => row.reduce((a,b,c) => a + b * arr2[c][y], 0)))
}
function change124(n) {
  return n === 0 ? '' : change124(parseInt((n - 1) / 3)) + [1, 2, 4][(n - 1) % 3];
}

이게 말이 되냐구….
나는 언제 이렇게,,,, 할 수 있게 되는 것일까..
내 코드부터 제대로 체화되고 해석해보자


61. JudenCase 문자열 만들기

programmers

function solution(s) {
  return s
    .replace(/\b\w{1}/g, (item) => item.toUpperCase())
    .replace(/\B\w/g, (item) => item.toLowerCase());
}

이제 더이상 정규식이 두렵지는 않다.!
다만 각각의 문법?을 아직 외우지 못해서 필요한 문법을 검색해서 조합하고 있다.
꾸준히 문제 풀어보면서 익숙해질 수 있도록 하자!

  • 원하는걸 뽑아내는건 match
  • 찾아서 바꾸는건 replace



best 풀이

function solution(s) {
    return s.split(" ").map(v => v.charAt(0).toUpperCase() + v.substring(1).toLowerCase()).join(" ");
}

다른 분들의 풀이를 보니 나만 정규식으로 풀었다..ㅋㅋㅋ


62. 124 나라의 숫자

programmers

function solution(n) {
  let answer = "";

  while (n > 0) {
    switch (n % 3) {
      case 1:
        answer = "1" + answer;
        n = Math.floor(n / 3);
        break;
      case 2:
        answer = "2" + answer;
        n = Math.floor(n / 3);
        break;
      case 0:
        answer = "4" + answer;
        n = n / 3 - 1;
        break;
    }
  }

  return answer;
}

재귀로 풀던 나… 반성하자
규칙성을 찾으려고 했는데 못찾았는데 좀 더 시각을 넓히는 노력을 해야겠다.
아니 근데 도대체 이런 규칙성을 찾는 실력은 어떻게 해야 길러지는것인가….




best 풀이

function change124(n) {
  var answer = "";
    var array1_2_4 = new Array(4, 1, 2); //3%3 = 0, 1%3 = 1, 2%3 = 2

  while(n) {
    answer = array1_2_4[n % 3] + answer;
    n = Math.floor((n - 1) / 3);
  }

  return answer;
}

나의 풀이를 좀 더 깔끔하게 담아낸 코드같다!


63. 피보나치 수

programmers

function solution(n) {
  let answer = [];
  for (let i = 0; i <= n; i++) {
    if (i <) answer.push(i);
    if (i >= 2) {
      let sum = answer[i - 1] + answer[i - 2];
      answer.push(sum % 1234567);
    }
  }
  return answer[n];
}

후.. 이문제 다른사람들도 말이 많은데 너무 불친절했다.
설명만 보면 아래 코드처럼 피보나치 수를 구한 후 최종값만 나머지값을 구하라는 건줄 알았는데,
그렇게 하면 7번째 테스트케이스부터 런타임 에러가 났다.
질문하기 에서 다른사람들의 내용을 반영하여, 재귀의 n을 구할때마다 모듈러연산을 해줘야한다는 것을 알게 됐다.
결과적으로 다른 분의 코드를 참고했는데, 계속 재귀를 도느니, 한번 구한 값은 배열에 넣어서 이후 참조하게 하는게 효율성 테스트에 더 적합한 것 같다.

const recursive = (n) => {
  if (n === 0) return 0;
  if (n === 1) return 1;

  return (n = recursive(n - 1) + recursive(n - 2));
};

function solution(n) {
  return recursive(n) % 1234567;
}



64. 땅따먹기

programmers

function solution(land) {
  var answer = 0;
  let prevIndex, tempIndex;
  for (let i = 0; i < land.length; i++) {
    let max = 0;
    land[i].forEach((item, index) => {
      if (item > max && prevIndex != index) {
        max = item;
        tempIndex = index;
      }
    });
    prevIndex = tempIndex;
    answer += max;
  }
  return answer;
}

단순하게 위에 행부터 가장 큰 수를 고른 후, 그 아래 행은 같은 열이 아닌 가장 큰 수를 고르는 방식으로 했는데,
문제를 잘 못 이해했다.
[[1,2,3,5]
[5,6,7,100]
[4,3,2,1]]
얘룰 둘오 이 경우, 100을 가져가기 위헤 1행에서 3을 선택해야 한다.
따라서 이 문제는 단순 풀이가 아닌 dp를 사용해야하는 문제다.
dp는 다음에 다룰 예정이니 오늘은 이문제를 여기까지만 다루고 다음에 와서 풀기로..!