https://school.programmers.co.kr/learn/courses/30/lessons/92341
처음엔 아래 방식으로 계산했다.
시간 계산 편의를 위해 입/출차 시간을 분으로 변환 했다. (시간 * 60 + 분)
차량 번호를 기준으로 맵을 만들고,
입차시 입차 시간을 기록하고, 출차시 (출차 시간 - 입차시간)을 총 주차 시간에 더해준다.
입차기록만 있는 경우 23시59분을 출차로 계산해야하므로 마지막 단계에서 처리해준다.
import java.util.*;
class Solution {
static int[] feesTable;
public int[] solution(int[] fees, String[] records) {
feesTable = fees;
Map<String, Info> infos = new HashMap();
for (String record : records) {
Info info = Info.from(record);
if (!infos.containsKey(info.carNumber)) {
infos.put(info.carNumber, info);
} else {
Info history = infos.get(info.carNumber);
history.update(info);
}
}
return infos.entrySet().stream()
.sorted((e1, e2) -> e1.getKey().compareTo(e2.getKey()))
.mapToInt(e -> e.getValue().fees())
.toArray();
}
static class Info {
static final int IN = 0;
static final int OUT = 1;
String carNumber;
int time;
int inOut;
int duration;
static Info from(String record) {
Info vo = new Info();
String[] split = record.split(" ");
vo.carNumber = split[1];
vo.time = time(split[0]);
vo.inOut = split[2].equals("IN") ? IN : OUT;
return vo;
}
static int time(String time) {
String[] split = time.split(":");
return Integer.parseInt(split[0]) * 60 + Integer.parseInt(split[1]);
}
void update(Info newInfo) {
if (newInfo.inOut == IN) {
this.time = newInfo.time;
this.inOut = IN;
} else {
this.duration += (newInfo.time - this.time);
this.time = 0;
this.inOut = OUT;
}
}
int fees() {
int fees = feesTable[1];
if (this.inOut != OUT) {
this.duration += (23 * 60 + 59 - this.time);
}
int extra = Math.max(0, this.duration - feesTable[0]);
fees += (((int) Math.ceil(1.0 * extra / feesTable[2])) * feesTable[3]);
return fees;
}
}
}
그런데 다른 분 정답을 보니 입출차를 -+로 계산하는 분이 계시더라.. 천재인가..
그래서 아래처럼 다시 풀어봄
import java.util.*;
class Solution {
final int endOfDay = 23 * 60 + 59;
public int[] solution(int[] fees, String[] records) {
Map<String, Integer> cars = new HashMap();
for (String record : records) {
String[] split = record.split(" ");
int min = toMins(split[0]);
String carNumber = split[1];
int weight = split[2].equals("IN") ? -1 : 1;
int duration = cars.getOrDefault(carNumber, 0);
duration += (weight * min);
cars.put(carNumber, duration);
}
return cars.entrySet().stream()
.sorted((e1, e2) -> e1.getKey().compareTo(e2.getKey()))
.mapToInt(e -> {
int fee = fees[1];
int duration = e.getValue();
if (duration <= 0) duration += endOfDay;
if (duration > fees[0]) {
fee += extraFee(duration, fees[0], fees[2], fees[3]);
}
return fee;
}).toArray();
}
// xx:xx 의 시간을 n분으로 변환
int toMins(String time) {
String[] split = time.split(":");
return Integer.parseInt(split[0]) * 60 + Integer.parseInt(split[1]);
}
// 기본료를 제외한 추가 요금
int extraFee(int duration, int freeTime, int unitTime, int unitFee) {
return ((int) Math.ceil(1.0 * (duration - freeTime) / unitTime)) * unitFee;
}
}