PS/프로그래머스

[프로그래머스] 이모티콘 할인행사

Hamp 2024. 9. 21. 20:52
반응형

문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

입력

users:[[Int]] = 각 유저의 구매 정보를 갖고 있다 [원하는 할인율, 플러스 구매 전향 기준 금액]

이모티콘이 원하는 할인율이 이상이 아니면 구매 x
만약 현재까지 구매한 금액이 플러스 구매 전향 기준 금액 이상일 경우
모두 구매 취소하고 플러스로 전향

출력

result = [Int] = [플러스 가입자 수, 이모티콘 총 구매 금액]

항상 플러스 가입자 수가  많아야하며 만약 가입자 수가 갔다면 구매 금액이 높은 최선의 결과를 찾아내자.

해석

1. 이모티콘 별 할인율 가능한 경우의 수를 구한다. [ 중복 순열 사용] , 할인율은 10 ~ 40%까지 , 10%단위로 나눠져있다.

2. 할인율 계산 함수 필요

3. 결과 구조체를 만든다. 구조체는 서비스 가입자 수와 구매 비용을 프로퍼티로 갖고있다.

4. 결과 구조체는 Comparable 프로토콜을 채택해 비교 가능하게 만든다.

5. 비교 조건은 서비스 가입자 -> 구매 비용 순으로 우선순위를 비교

코드

import Foundation

// 모든 할인율 경우의 수를 나타내는 중복 순열
func Rpermutation<T>(_ elements: [T], _ k: Int) -> [[T]] {
    var result = [[T]]()
    
    func Rpermut(_ now: [T]) {
        if now.count == k {
            result.append(now)
            return
        }
        
        for i in 0..<elements.count {
            Rpermut(now + [elements[i]])
        }
    }
    Rpermut([])
    return result
}

struct Result: Comparable {
    
    let emotionPlus: Int 
    let sales: Int 
    
    static func <(lhs: Self, rhs: Self) -> Bool {
        
        // 이모티콘 서비스 가입자 수가 같다면 구매 비용이 높은 것이 우선
        if lhs.emotionPlus == rhs.emotionPlus {
            return lhs.sales < rhs.sales
        }
        
        return lhs.emotionPlus < rhs.emotionPlus
    }
}

// 할인율 계산한 최종 금액 계산 함수
func discount(_ cost: Int,_ percent: Int) -> Int {
    return (cost * (100 - percent)) / 100
}

func solution(_ users:[[Int]], _ emoticons:[Int]) -> [Int] {
    
    var result: Result = Result(emotionPlus: 0, sales: 0)
    
    let discountPermu = Rpermutation([10, 20, 30, 40], emoticons.count)
    
    for percents in discountPermu {
        
        var emotionPlusCount: Int = 0 // 현재 할인율을 적용했을 때 이모티콘 서비스 가입자 수
        var totalSales: Int = 0 // 현재 할인율 적용했을 때 총 구매 비용
        
        for user in users {

            let preferPercent: Int = user[0] // 원하는 할인율
            let emotionPlusGoalCost: Int = user[1]
            var overTheGoal: Bool = false // 이모티콘 서비스 구매의향 금액을 넘었는지
            var sales: Int = 0 // 현재 유저의 
            
            for (cost, percent) in zip(emoticons, percents) {
            

                if preferPercent > percent { continue } // 원하는 할인율 이상이 아니면 무시

                let discountedCost: Int = discount(cost, percent)
                sales += discountedCost
              
                if sales >= emotionPlusGoalCost { // 구매 금액이 이모티콘 서비스 구매의향 금액 넘어가면 flag on
                    overTheGoal = true 
                    break
                }

            }
            
            
            if overTheGoal {
                emotionPlusCount += 1
            } else {
                totalSales += sales
            }
        }
        
        let newResult: Result = Result(emotionPlus: emotionPlusCount, sales: totalSales)
        
        result = max(result, newResult)

    }
    
    return [result.emotionPlus, result.sales]
}

 

반응형