Programmers_완전탐색_모의고사

Seoyong Lee·2021년 6월 22일
0

Algorithm / Data Structure

목록 보기
21/22
post-thumbnail

조건

1번 수포자: 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, ...
2번 수포자: 2, 1, 2, 3, 2, 4, 2, 5, 2, 1, 2, 3, 2, 4, 2, 5, ...
3번 수포자: 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, ...

1번 문제부터 마지막 문제까지의 정답이 순서대로 들은 배열 answers가 주어졌을 때, 가장 많은 문제를 맞힌 사람이 누구인지 배열에 담아 return 하도록 solution 함수를 작성해주세요.

입출력 예시

-입력: [1,2,3,4,5]
-출력: [1]

-입력: [1,3,2,4,2]
-출력: [1,2,3]

풀이

첫 번째 도전

function solution(answers) {
  let answer = [];

  // 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 
  let sol1 = new Array(answers.length).fill(0);
  for (let i = 0; i < answers.length; i++) {
    if (i > 4) sol1[i] = sol1[i - 5];
    else sol1[i] = i + 1;
  }

  // 2, 1, 2, 3, 2, 4, 2, 5, 2, 1, 2, 3, 2, 4, 2, 5
  let sol2 = new Array(answers.length).fill(2);
  for (let i = 0; i < answers.length; i++) {
    if (i % 2 === 1) {
      if (i > 7) sol2[i] = sol2[i - 8]; 
      else if (i === 5) sol2[i] = 4;
      else if (i === 7) sol2[i] = 5;
      else sol2[i] = i; 
    }
  }
  // 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, ...
  let sol3 = new Array(answers.length).fill(0);
  for (let i = 0; i < answers.length; i++) {
    // ...
  }
  const scoring = function(solution) {

  }
  return answer;
}

첫 풀이는 다음과 같이 수도코드를 작성하고 각각의 수포자 배열을 answers의 개수에 맞게 처음부터 구성하려 시도하였다. 그러나 중간에 비효율 적이라는 것을 깨닿고 중단하였다. 또한 Array.from() 등의 메소드로 해결해 보려 하였으나 콜백 함수 작성을 어떻게 해야할지, 또한 한 순회가 끝나면 다시 1부터 시작하는 부분을 어떻게 구현할지에서 막혔다.

  1. 입출력 체크
  2. answers의 길이 만큼 각 수포자의 풀이 배열 설정 ?
  3. answers와 각 풀이 비교
  4. 가장 많이 맞은 풀이 return

두 번째 도전

function solution(answers) {
  let answer = [];
  let list = [
    [1,2,3,4,5],
    [2,1,2,3,2,4,2,5],
    [3,3,1,1,2,2,4,4,5,5]
  ]
  let point = [0,0,0]
  for (let i = 0; i < answers.length; i++) {
    if (answers[i] === list[0][i % 5]) // 1번이 맞춘 경우
      point[0]++;
    if (answers[i] === list[1][i % 8]) // 2번이 맞춘 경우
      point[1]++;
    if (answers[i] === list[2][i % 10]) // 3번이 맞춘 경우
      point[2]++;
  }
  // 가장 높은 점수를 받은 수포자 max 탐색
  let max = 0;
  for (let j = 0; j < point.length; j++) {
    if (point[j] > max)
      max = point[j];
  }
  // answer 배열에 max 추가 
  for (let k = 0; k < point.length; k++) {
    if (max === point[k])
      answer.push(k + 1);
  }
  return answer;
}

문제를 완전히 다르게 접근하여 처음부터 세 수포자의 배열 list를 구성하고 각각이 문제를 맞추었는지만 카운트 하여 point에 보관하는 식으로 작성하였다. 각 수포자 배열의 길이로 해당 인덱스를 나누어주면 다시 처음 반복으로 돌아간다는 것도 검색을 통해 알아낸 유용한 방법이었다.

프로그래머스의 다른 풀이 중 이렇게 더욱 정리된 방법도 있었다.

function solution(answers) {
  let answer = [];
  let a1 = [1, 2, 3, 4, 5];
  let a2 = [2, 1, 2, 3, 2, 4, 2, 5]
  let a3 = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5];

  let a1c = answers.filter((a, i)=> a === a1[i % a1.length]).length;
  let a2c = answers.filter((a, i)=> a === a2[i % a2.length]).length;
  let a3c = answers.filter((a, i)=> a === a3[i % a3.length]).length;
  let max = Math.max(a1c, a2c, a3c);
  if (a1c === max) {answer.push(1)};
  if (a2c === max) {answer.push(2)};
  if (a3c === max) {answer.push(3)};

  return answer;
}

위와 같이 length를 잡아서 바로 비교하면 추가적인 반복문이 불필요해진다!

profile
코드를 디자인하다

0개의 댓글