TIL/알고리즘 공부

프로그래머스 Lv. 2 Swift 알고리즘 - 주차 요금 계산

여의도사노비 2023. 1. 12. 11:42
728x90

논리적인 흐름은 전부 따라갔는데 코드를 짜면서 너무 많은 내용들이 흘러나와...

참지못하고 다른 분들의 코드를 참고한 문제이다 ;(...

 

차량 번호와 이용 시간을 Dictionary 타입으로 잘 저장해두고 In과 Out에 따른 +, - 그리고 Out이 없는 경우의 계산만 잘해주면 된다.

 

 

 

이 문제를 풀면서 생각한 논리적 흐름

  1. 차 별로 얼마나 오래 주차했는지 확인하기 위해 먼저 딕셔너리 형태로 차를 key로 두고 시간과 상태를 value로 둔다.
  2. records에서 제공되는 원소를 공백을 기준으로 나누고 time 상수에 시간 형태로 이루어진("00:00" ) 원소를 ":"를 기준으로 나누어 시간과 분을 분리한다. 그리고 이를 모두 분으로 표현한다.
  3. car[number]의 원소 time에는 그 전과 그 후 원소간의 시간 차이를 누적하여 계산하고, state에는 최신 상태(In & Out)를 업데이트 해준다.
  4. 차의 번호가 낮은 순서대로 요금을 리턴하라고 했으니 sortedCar를 이용하여 순서를 조정해준다.
  5. 만약 차의 상태가 In이라면 최신 상태가 In이라는 뜻이고, 마지막 Out의 값을 lastOut으로 잡고 나간 것으로 간주하여 계산한다.
  6. 기본시간을 초과하지 않았으면 기본피(fee[1]), 초과했다면 기본피 + 초과분(올림적용) * fee[3]으로 계산

 

 

* 참고한 코드

import Foundation

func solution(_ fees:[Int], _ records:[String]) -> [Int] {
    let lastOut = 23 * 60 + 59
    var answer: [Int] = []
    var car: [String:(time: Int, state: String)] = [:]
    
    records.forEach {
        let recordArr = $0.components(separatedBy: " ")
        let time = { () -> Int in
            let timeInfo = recordArr[0].components(separatedBy: ":")
            let hour = Int(timeInfo[0])!
            let min = Int(timeInfo[1])!
            return hour * 60 + min
        }()
        let number = recordArr[1]
        let state = recordArr[2]
        
        if car[number] == nil {
            car[number] = (time: time, state: state)
        } else {
            car[number]! = (time: time - car[number]!.time , state: state)
        }
    }
    
    let sortedCar = car.sorted{ $0.key < $1.key }
    
    sortedCar.forEach {
        var car = $0
        
        if car.value.state == "IN" {
            car.value.time = lastOut - car.value.time
        }
        
        let time = Float(car.value.time) - Float(fees[0])
        
        if time <= 0 {
            answer.append(fees[1])
        } else {
            let moneyPerT = Int(ceil(time/Float(fees[2])))
            answer.append(fees[1] + moneyPerT * fees[3])
        }
    }
    return answer
}
 
 

정리(Today I Learned)

  1. for 문과 forEach문을 어떤 때 각각 써야하는지 아직도 잘 구분이 안간다.
    다만 간단하게라도 forEach에 대해서 정리해보자면 아래와 같다.
    • 컨테이너의 요소를 사용한다
    • 반복문이 아닌 클로저를 사용한다
    • 클로저를 사용하기 때문에 break, continue 사용이 안된다
    • return 을 사용해도 클로저에 대한 호출만 종료된다