본문 바로가기

알고리즘/프로그래머스

프로그래머스 - 실패율

programmers.co.kr/learn/courses/30/lessons/42889

 

코딩테스트 연습 - 실패율

실패율 슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다. 원인은 신규 사용자와 기존 사용자 사이에 스

programmers.co.kr


 

먼저

stages를 반복문을 돌려서 해당 스테이지에 도달한 사람이 몇번인지 계산을 해준다

만약 끝까지 모두 깬 사람이 있다면 그 스테이지는 추가하지 않고 처음부터 마지막 스테이지까지 도달한 플레이어 수를 1씩 늘려준다

 

예를들어 [2, 1, 2, 6, 2, 4, 3, 3] 문제의 배열에서

3번째 2 값을 기준으로 보면

만약 반복문을 통해 2를 만나면 이 유저는 2번 스테이지에 멈춰 있다는 뜻

그래서 결과 배열에 해당 인덱스 값에 실패 유저를 1 증가시켜준다

그리고 반복문을 돌려서 그 전 스테이지까지 지금 같은 경우는

1 ~ 2 스테이지까지 도달한 유저수를 1씩 더해준다

 

그리고 반복문을 하나 더 돌려서 실패율을 계산해주는데

만약 도달한 플레이어 수가 0이라면 실패율은 0으로 고정값으로 설정한다.

 

그리고 정렬, 기준은 실패율을 기준으로 내림차순 만약 실패율이 같다면 스테이지 번호가 적은 순으로 정렬해준다.

 

func solution(_ N:Int, _ stages:[Int]) -> [Int] {
    
    //result0 - 도달했으나 클리어못한사람 // 1 - 스테이지에 도달한 플레이어 수
    var result = Array(repeating: Array(repeating: 0, count: 2), count: N)
    
    var answer = [Int: Double]()
    
    for stage in stages {
        if stage > N {
            
            for i in 0 ... N - 1 {
                result[i][1] += 1
            }
        } else {
            result[stage - 1][0] += 1
            
            for i in 0 ... stage - 1 {
                result[i][1] += 1
            }
        }
    }
    
    for (index, r) in result.enumerated() {
        if r[1] == 0 {
            answer.updateValue(0.0, forKey: index + 1)
        } else {
            answer.updateValue(Double(r[0]) / Double(r[1]), forKey: index + 1)
        }
    }

    return answer.sorted { $0.1 == $1.1 ? $0.0 < $1.0 : $0.1 > $1.1 }.map { $0.0 }
}

 

 

처음엔 filter를 이용해서 문제를 해결하려고 했다.

 

이렇게 도달한 유저, 실패한 유저를 필터로 뽑아서 작성했는데 코드는 성공한 코드의 반도 되지 않아 보기는 좋은데

실제로 돌려보니 몇개가 시간문제로 해결되지 않았다.

for i in 0 ... N - 1 {
    let count = stages.filter { $0 >= i }.count
    let fail = stages.filter { $0 == i }.count
}