[프로그래머스 | 파이썬 / 자바스크립트] 주차 요금 계산(2022 KAKAO BLIND RECRUITMENT/ level 2)

2023. 3. 3. 19:45·Problem Solving/프로그래머스
반응형
문제

https://school.programmers.co.kr/learn/courses/30/lessons/92341 

 

프로그래머스

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

programmers.co.kr

 

 

🐍파이썬

전체 코드

import math
def solution(fees, records):
    answer = []
    temp = {}
    parking = {}
    
    for record in records:
        time, car, inout = record.split()
        if car not in temp:
            temp[car] = time
        else:
            if inout == "OUT":
                parkingTime = (int(time.split(":")[0]) * 60 + int(time.split(":")[1])) - (int(temp[car].split(":")[0]) * 60 + int(temp[car].split(":")[1]))
                if car not in parking:
                    parking[car] = parkingTime
                else:
                    parking[car] += parkingTime
                del(temp[car])
                
    for remain in temp.keys():
        parkingTime = 23 * 60 + 59 - (int(temp[remain].split(":")[0]) * 60 + int(temp[remain].split(":")[1]))
        if remain not in parking:
            parking[remain] = parkingTime
        else:
            parking[remain] += parkingTime
            
    for i in parking.keys():
        totalPay = fees[1] + math.ceil(max(0, (parking[i] - fees[0])) / fees[2]) * fees[3]
        parking[i] = totalPay
        
    for i in sorted(parking.items()):
        answer.append(i[1])
        
    return answer

전체코드(코드 + 문제 풀이 설명 주석)

import math
def solution(fees, records):
    answer = []
    temp = {}
    parking = {}
    
    for record in records:
        time, car, inout = record.split()
        if car not in temp: #temp 딕셔너리에 차 번호로 된 key가 존재하지 않는다면
            temp[car] = time    #새로운 key-value(차 번호:입차시간) 저장
        else:   #temp 딕셔너리에 차 번호로 된 key가 존재한다면(입차내역이 존재한다면)
            if inout == "OUT":  #출차시간 확인
                #주차시간 = 출차시간 - 입차시간 (분단위로 계산하기 위해 '시'에 60을 곱함) 
                parkingTime = (int(time.split(":")[0]) * 60 + int(time.split(":")[1])) - (int(temp[car].split(":")[0]) * 60 + int(temp[car].split(":")[1]))
                if car not in parking: #parking 딕셔너리에 차 번호로 된 key가 존재하지 않는다면
                    parking[car] = parkingTime  #새로운 key-value(차 번호:주차시간) 저장
                else:
                    parking[car] += parkingTime #기존 저장된 주차시간에 새로 구한 주차시간 더함
                del(temp[car])  #주차시간을 모두 구한 차는 temp에서 삭제
                
    for remain in temp.keys():  #IN-OUT 쌍이 맞지 않는 차
        parkingTime = 23 * 60 + 59 - (int(temp[remain].split(":")[0]) * 60 + int(temp[remain].split(":")[1]))   #23:59 - 입차시간
        if remain not in parking:   #parking 딕셔너리에 key가 존재하지 않는다면
            parking[remain] = parkingTime   #새로운 key-value(차 번호:주차시간) 저장
        else:
            parking[remain] += parkingTime  #기존 저장된 주차시간에 새로 구한 주차시간 더함
            
    for i in parking.keys():    #전체 parking 요소들에 대해 요금 계산
        totalPay = fees[1] + math.ceil(max(0, (parking[i] - fees[0])) / fees[2]) * fees[3]  #주차시간이 주차기본제공시간보다 작을 경우 (-)가 나오는 것을 방지하기 위해 max(0, ~) 지정
        parking[i] = totalPay   #parking에 주차시간 대신 주차요금을 저장
        
    for i in sorted(parking.items()):   #key를 기준으로 정렬된 사전을 순회하며 2번째 요소(주차요금)를 정답 배열에 append
        answer.append(i[1])
        
    return answer

💡 key를 기준으로 딕셔너리 정렬하기

  • sorted() 함수 사용
dic = {'0000': 14600, '5961': 5000, '0148': 34400}
newD = sorted(dic.items())
print(newD)
# [('0000', 14600), ('0148', 34400), ('5961', 5000)]
# items() 함수는 key-value 쌍이 튜플 형태로 구성된 리스트를 반환한다.

(참고:https://tinyurl.com/2jr73pop)

 

[Python] 딕셔너리 정렬하기

파이썬 딕셔너리에 입력된 key 값과 value 값들을 정렬해야 할 때가 있습니다.그럴 때 해결할 수 있는 방법을 사용해보려고 합니다. 각각 Key를 이용한 방법과 Value를 이용한 방법이 있습니다.딕셔

kkamikoon.tistory.com

 

 

다른 풀이 방법

from collections import defaultdict
from math import ceil

class Parking:
    def __init__(self, fees):
        self.fees = fees
        self.in_flag = False
        self.in_time = 0
        self.total = 0

    def update(self, t, inout):
        self.in_flag = True if inout=='IN' else False
        if self.in_flag:  self.in_time = str2int(t)	#inout=='IN'
        else:             self.total  += (str2int(t)-self.in_time)

    def calc_fee(self):
        if self.in_flag: self.update('23:59', 'out')
        add_t = self.total - self.fees[0]
        return self.fees[1] + ceil(add_t/self.fees[2]) * self.fees[3] if add_t >= 0 else self.fees[1]

def str2int(string):
    return int(string[:2])*60 + int(string[3:])

def solution(fees, records):
    recordsDict = defaultdict(lambda:Parking(fees))
    for rcd in records:
        t, car, inout = rcd.split()
        recordsDict[car].update(t, inout)
    return [v.calc_fee() for k, v in sorted(recordsDict.items())]

❓ 딕셔너리 defaultdict

일반적인 딕셔너리의 경우, 딕셔너리에 존재하지 않는 key에 대해 접근할 경우 keyError가 발생한다. 반면 defaultdic의 경우 key값이 존재하지 않아도 default값을 줄 수 있어 에러가 발생하지 않는다.

(참고: https://tinyurl.com/2l6vytxa)


import math

def solution(fees, records):
    check = {}

    for record in records:
        time, number, status = record.split()
        time = time.split(':')
        time = int(time[0])*60 + int(time[1])
        if number not in check:
            check[number] = (0, time, status)
        if status == 'IN':
            check[number] = (check[number][0], time, status)
        elif status == 'OUT':
            total_time, in_time, _ = check[number]
            total_time += time - in_time
            check[number] = (total_time, time, status)

    result = {}

    for number in check.keys():
        total_time, time, status = check[number]
        if status == 'IN':
            total_time += 1439 - time
        fee = fees[1]
        if total_time <= fees[0]:
            result[number] = fee
        else:
            fee = fee + math.ceil((total_time - fees[0]) / fees[2]) * fees[-1]
            result[number] = fee

    return list(map(lambda x : x[1], sorted(result.items())))

 

 

🐥자바스크립트
function solution(fees, records) {
    var answer = [];
    let temp = {};
    var parking = {};
    let parkingTime = 0;
    
    for(let i of records){
        let [time, car, inout] = i.split(' ');
        if(car in temp == false){
            temp[car] = time;
        } else{
            if(inout === "OUT"){
                parkingTime = (Number(time.split(':')[0]) * 60 + Number(time.split(':')[1])) - (Number(temp[car].split(':')[0]) * 60 + Number(temp[car].split(':')[1]));
                if(car in parking === false){
                    parking[car] = parkingTime;
                } else{
                    parking[car] += parkingTime;
                }
                delete temp[car];
            }
        }
    }

    for(let i in temp){
        if(i in parking === false){
            parking[i] = 23 * 60 + 59 - (Number(temp[i].split(':')[0]) * 60 + Number(temp[i].split(':')[1]));
        } else{
            parking[i] += 23 * 60 + 59 - (Number(temp[i].split(':')[0]) * 60 + Number(temp[i].split(':')[1]));
        }
    }

    for(let i in parking){
        let parkingPay = fees[1] + Math.ceil((Math.max(0, parking[i] - fees[0])) / fees[2]) * fees[3];
        answer.push([i, parkingPay]);
    }
    return answer.sort((a, b) => a[0] - b[0]).map(v => v[1]);
}

전체코드(코드 + 문제 풀이 설명 주석)

function solution(fees, records) {
    var answer = [];
    let temp = {};
    var parking = {};
    let parkingTime = 0;
    
    for(let i of records){
        let [time, car, inout] = i.split(' ');
        if(car in temp == false){	//temp 딕셔너리에 car key가 없을 경우
            temp[car] = time;	//(차번호:입차시간) 저장
        } else{
            if(inout === "OUT"){	//IN-OUT쌍이 지어진 경우
            	//parkingTime = 현재시간 - 입차시간
                parkingTime = (Number(time.split(':')[0]) * 60 + Number(time.split(':')[1])) - (Number(temp[car].split(':')[0]) * 60 + Number(temp[car].split(':')[1]));
                if(car in parking === false){	//parking 딕셔너리에 car key가 없을 경우
                    parking[car] = parkingTime;	//(차번호:주차시간) 저장
                } else{
                    parking[car] += parkingTime;	//기존 car key에 새로 구한 주차시간 더하기
                }
                delete temp[car];	//IN-OUT쌍이 지어졌고 주차시간을 parking 딕셔너리에 저장했으니 temp 딕셔너리 내용 삭제
            }
        }
    }

    for(let i in temp){	//IN-OUT 쌍이 만들어지지 못한 경우
        if(i in parking === false){	//parking 딕셔너리에 temp key가 없을 경우
        	//(23:59 - 현재시간)을 parking 딕셔너리에 저장
            parking[i] = 23 * 60 + 59 - (Number(temp[i].split(':')[0]) * 60 + Number(temp[i].split(':')[1]));
        } else{
            parking[i] += 23 * 60 + 59 - (Number(temp[i].split(':')[0]) * 60 + Number(temp[i].split(':')[1]));
        }
    }

    for(let i in parking){	//parking 딕셔너리를 순회하며 주차비를 계산
        let parkingPay = fees[1] + Math.ceil((Math.max(0, parking[i] - fees[0])) / fees[2]) * fees[3];
        answer.push([i, parkingPay]);
    }
    return answer.sort((a, b) => a[0] - b[0]).map(v => v[1]);
}

 

 

다른 풀이 방법

function solution(fees, records) {
    const parkingTime = {};
    records.forEach(r => {
        let [time, id, type] = r.split(' ');
        let [h, m] = time.split(':');
        time = (h * 1) * 60 + (m * 1);
        if (!parkingTime[id]) parkingTime[id] = 0;
        if (type === 'IN') parkingTime[id] += (1439 - time);
        if (type === 'OUT') parkingTime[id] -= (1439 - time);
    });
    const answer = [];
    for (let [car, time] of Object.entries(parkingTime)) {
        if (time <= fees[0]) time = fees[1];
        else time = Math.ceil((time - fees[0]) / fees[2]) * fees[3] + fees[1]
        answer.push([car, time]);
    }
    return answer.sort((a, b) => a[0] - b[0]).map(v => v[1]);
}
// 차량번호 오름차순으로 청구요금 담아 배열로 리턴

// 청구요금 구하기
// 기본요금 fee[1] + ( 주차시간 - 기본시간fee[0] ) / fee[2] * fee[3] 

// 기본시간이내 : 기본요금 
// 출차 시간 max = 23:59
// 분 단위는 올림

// 주차시간 구하기 
// records.forEach(r => r.split(' ')

// log 객체에 {차번호: 시간} 저장
// IN 이면 + (24시간(분) - 입차시간)
// OUT이면 -(1430 - 출차시간)
// 24시간 = 1440분

// ex) 05:34 (05 * 60) + 34 = 334

 

 

 

 

 

 

 

반응형
저작자표시 비영리 변경금지 (새창열림)

'Problem Solving > 프로그래머스' 카테고리의 다른 글

[프로그래머스 | 파이썬 / 자바스크립트] 오픈채팅방(2019 KAKAO BLIND RECRUITMENT/ level 2)  (2) 2023.03.06
[프로그래머스 | 파이썬 / 자바스크립트] 과일 장수(연습문제/ level 1)  (0) 2023.03.05
[프로그래머스 | 파이썬] 더 맵게(힙(Heap)/ level 2)  (0) 2023.03.03
[프로그래머스 | 파이썬 / 자바스크립트] 대충 만든 자판(연습문제/ level 1)  (0) 2023.02.28
[프로그래머스 | 파이썬 / 자바스크립트] [1차] 뉴스 클러스터링(2018 KAKAO BLIND RECRUITMENT/ level 2)  (0) 2023.02.28
[프로그래머스 | 파이썬 / 자바스크립트] 연속 부분 수열 합의 개수(연습문제/ level 2)  (0) 2023.02.28
'Problem Solving/프로그래머스' 카테고리의 다른 글
  • [프로그래머스 | 파이썬 / 자바스크립트] 과일 장수(연습문제/ level 1)
  • [프로그래머스 | 파이썬] 더 맵게(힙(Heap)/ level 2)
  • [프로그래머스 | 파이썬 / 자바스크립트] 대충 만든 자판(연습문제/ level 1)
  • [프로그래머스 | 파이썬 / 자바스크립트] [1차] 뉴스 클러스터링(2018 KAKAO BLIND RECRUITMENT/ level 2)
청량리 물냉면
청량리 물냉면
프로그래밍 공부를 하고 있습니다. 공부 내용 정리 겸 정보 공유를 목적으로 합니다.
    반응형
  • 청량리 물냉면
    노력중인 블로그
    청량리 물냉면
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • 프로그래밍 N
        • Programming
        • C | C++
        • Java N
        • Python
      • 웹 프로그래밍
        • HTML | CSS
        • JavaScript | TypeScript
        • React
        • Vue.js
        • Next.js
        • Spring & Spring Boot
        • JSP & Servlet
        • DB
      • 웹 프로젝트
        • 웹 프로젝트
        • 🥨스낵몰
        • 👨‍👨‍👧‍👧소셜 가계부
        • 🌜꿈 일기장
        • 🔮포트폴리오 사이트
        • 🏃‍♂️팀 프로젝트: 일정관리 프로그램
        • 📈팀 프로젝트: AI기반 주식 분석 플랫폼
        • 😺Just Meow It: 고양이의 조언
      • 앱 프로그래밍
        • Flutter
        • Kotlin
      • Problem Solving
        • 백준
        • 프로그래머스
        • SWEA
      • Computer Science
        • 알고리즘
        • 컴퓨터 네트워크
        • 이산수학
      • Developer
        • 후기
        • 자료정리
        • 취업 | 취준
        • 웹개발 교육 프로그램
        • TIL
  • 블로그 메뉴

    • 홈
    • Github
  • 공지사항

    • 프로그래밍 공부 중😊
  • 인기 글

  • 태그

    mysql
    강의내용정리
    AWS
    ZeroCho
    자바스크립트
    프로그래머스
    spring boot
    프로젝트
    웹사이트
    클론 프로젝트
    SWEA
    공식문서
    블로그 제작
    컴퓨터네트워크
    뉴렉처
    파이썬
    bfs
    구현
    Til
    포트폴리오
    Next.js
    백준
    자바
    리액트
    플러터
    타입스크립트
    Jiraynor Programming
    알고리즘
    React
    d3
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
청량리 물냉면
[프로그래머스 | 파이썬 / 자바스크립트] 주차 요금 계산(2022 KAKAO BLIND RECRUITMENT/ level 2)
상단으로

티스토리툴바