반응형
문제
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 |