230412_Algorithm

majungha·2023년 4월 13일
1

알고리즘

목록 보기
23/71

오늘의 알고리즘 👍

📝 1. 실패율


  • 슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다.
  • 원인은 신규 사용자와 기존 사용자 사이에 스테이지 차이가 너무 큰 것이 문제였다.
  • 이 문제를 어떻게 할까 고민 한 그녀는 동적으로 게임 시간을 늘려서 난이도를 조절하기로 했다.
  • 역시 슈퍼 개발자라 대부분의 로직은 쉽게 구현했지만, 실패율을 구하는 부분에서 위기에 빠지고 말았다. 오렐리를 위해 실패율을 구하는 코드를 완성하라.
  • 실패율은 다음과 같이 정의한다.
  • 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수
  • 전체 스테이지의 개수 N, 게임을 이용하는 사용자가 현재 멈춰있는 스테이지의 번호가 담긴 배열 stages가 매개변수로 주어질 때,
  • 실패율이 높은 스테이지부터 내림차순으로 스테이지의 번호가 담겨있는 배열을 return 하도록 solution 함수를 완성하라.

▷ 입출력 예

solution(5, [2, 1, 2, 6, 2, 4, 3, 3]) // [3,4,2,1,5]
solution(4, [4,4,4,4,4]) // [4,1,2,3]

▷ 해결 못함 ❌

▷ 수업 풀이

function solution(N, stages) {
  // 모든 스테이지의 번호를 오름차순 형태로 정렬
  stages.sort((a, b) => (a > b ? 1 : -1));

  const infos = [];
  for (let i = 1; i <= N; i++) {
    infos.push({
      stage: i, // 현재 스테이지의 번호
      users: 0, // 스테이지를 클리어 하지 못한 유저의 수
      fail: 0, // 실패율
    });
  }

  let allUsers = stages.length; // (이전 스테이지를 클리어하지 못한 유저를 제외한) 모든 유저의 수
  for (let i = 0; i < stages.length; i++) {
    if (infos[stages[i] - 1]) {
      infos[stages[i] - 1].users++;

      // 현재 스테이지의 번호와 다음 스테이지의 번호가 동일하지 않을 경우
      // = 현재 스테이지의 합산이 완료되는 시점
      if (stages[i] !== stages[i + 1]) {
        infos[stages[i] - 1].fail = infos[stages[i] - 1].users / allUsers;
        // 현재 스테이지를 클리어하지 못한 유저 수만큼 전체 유저수에서 삭감
        allUsers -= infos[stages[i] - 1].users;
      }
    }
  }

  return infos
    .sort((a, b) => {
      return a.fail > b.fail ? -1 : 1;
    })
    .map((el) => el.stage);
}

❗ indexOf, lastIndexOf

arr = [1, 1, 2, 2, 3, 3, 3]
arr.indexOf(2, 2) // indexOf는 앞에서부터 끝까지 찾는다. 두번째 인자가 있다면 그 인덱스 번호부터 찾는다
arr.lastIndexOf(2) // lastIndexOf는 뒤에서부터 처음까지 찾는다. 두번째 인자가 있다면 그 인덱스 번호부터 찾는다. 
// 전제조건 - 정렬이 되어있어야만 원하는 범위를 가져올 수 있다.

arr.slice(
  arr.indexOf(2),arr.lastIndexOf(2) + 1
)

▷ map(배열) 매서드 사용 풀이

function solution(N, stages) {
  // 모든 스테이지의 번호를 오름차순 형태로 정렬
  stages.sort((a, b) => (a > b ? 1 : -1));
    let allUsers = stages.length;
return new Array(N)
        .fill(1)
            .map((num, i) => {
                const stage = num + i;
                const result = stages.slice(
                    stages.indexOf(stage),
                    stages.lastIndexOf(stage) + 1
                )
                const fail = result.length / allUsers;
                allUsers -= result.length;

                return { stage, fail }; // key값과 value값이 동일
            }).sort((a, b) => a.fail > b.fail ? -1 : 1)
              .map((el) => el.stage)
}

❗ Array.from 매소드

new Array(5).fill(1).map((el, i) => el + i)
Array.from(new Array(5), (_, i) => 1 + i) // Array.from은 두번째 인자로 무엇을 넣을건지 설정해줄 수 있다.(fill매서드 사용 안해도 결과가 똑같음)

▷ 위 코드 리팩토링

function solution(N, stages) {
  // 모든 스테이지의 번호를 오름차순 형태로 정렬
  stages.sort((a, b) => (a > b ? 1 : -1));
    let allUsers = stages.length;
return Array.from(new Array(N, (_, i) => 1 + i))
            .map((stage) => {
                const result = stages.slice(
                    stages.indexOf(stage),
                    stages.lastIndexOf(stage) + 1
                )
                const fail = result.length / allUsers;
                allUsers -= result.length;

                return { stage, fail }; // key값과 value값이 동일
            }).sort((a, b) => a.fail > b.fail ? -1 : 1)
              .map((el) => el.stage)
}

출처: 프로그래머스
출처: 코드캠프

profile
개발자 블로그 / 항상 겸손한 자세로 배우면서 성장하자 할 수 있다!

0개의 댓글