Notice
Recent Posts
Recent Comments
Link
복's
[ Programmers - LV2 ] 호텔 대실 본문
728x90
https://school.programmers.co.kr/learn/courses/30/lessons/155651
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
프로그래머스 문제 풀이할 때 시간 관련 문제가 나오면 LocalTime 을 먼저 사용하는데 계속해서 날짜가 넘어가는 케이스를 생각 못해서 엣지 케이스가 생기고, 그 때 마다 LocalDateTime 으로 변경하는 작업을 반복했다...
앞으로는 바로 LocalDateTime 을 사용 하던가, 아니면 시간을 쫌 더 편한 int 단위로 변경해서 풀이하는게 나을 것 같다.
(분 * 60) + 초
[ 📌 분석 ]
문제에서 요구하는 요구 사항이 명확하기 때문에 헷갈리는 부분은 없다고 생각 된다.
- 체크인 한 객실이 가장 많을 때 최대 몇 개?
- 체크 아웃시 10분의 청소 시간이 필요하다.
요구한 대로 구현하는 문제로 방법이야 많지만 나는 손님들이 시간에 맞춰서 찾아왔다가 시간이 되면 체크 아웃하고 나가는 그대로 구현했다.
[ 📌 부분 코드 - Java ]
⚙️ 선언부
Queue<Customer> waitingQ = new PriorityQueue<>(Comparator.comparing(a -> a.srtTime));
Queue<Customer> roomQ = new PriorityQueue<>(Comparator.comparing(a -> a.endTime));
int maxSize = 0;
- waitingQ: 호텔 체크인 대기 손님들 (체크인 시간으로 정렬)
- roomQ: 객실 사용중인 손님들 (체크아웃 시간으로 정렬)
⚙️ Customer
class Customer {
private final int CLEAN_TIME = 10;
LocalDateTime srtTime;
LocalDateTime endTime;
public Customer(int[] srtTime, int[] endTime) {
LocalDate nowDate = LocalDate.now();
this.srtTime = LocalDateTime.of(nowDate, LocalTime.of(srtTime[0], srtTime[1]));
this.endTime = LocalDateTime.of(nowDate, LocalTime.of(endTime[0], endTime[1])).plusMinutes(CLEAN_TIME);
}
}
- 생성자: Date 는 now() 를 기준으로 넣었고, Time 은 주어진 문자열 데이터를 파싱 해서 넣었는데, endTime 의 경우 10 분의 청소 시간을 미리 더해주었다.
⚙️ 메인 로직
while(!waitingQ.isEmpty()) {
Customer cus = waitingQ.poll();
// 사용중인 호텔방 존재 && (체크인과 체크아웃 동시간 || 현 고객 체크인 시간보다 늦은 체크 아웃방)
while(!roomQ.isEmpty() && (roomQ.peek().endTime.equals(cus.srtTime) || cus.srtTime.isAfter(roomQ.peek().endTime))) {
roomQ.poll();
}
roomQ.add(cus);
maxSize = Math.max(maxSize, roomQ.size());
}
- 대기중인 손님이 전부 체크인 할 때 까지 조건으로 두었다. (중요한건 손님들 체크인 후 객실 사용이 가장 몰릴 때이기 때문에 전부 체크아웃 했는지 여부는 필요 없음)
- isAfter 만 사용했을 때, 시간이 동일한 경우가 잡히지 않아서 equals 를 이용해서 체크인 & 체크아웃이 겹치는 시간도 포함해서 확인 후 현재 체크인 하는 고객의 시간을 기준으로 이미 체크아웃 시간이 지난 고객들은 체크아웃 시킨다.
- 현 고객을 넣고, 최대 객실 갱신한다.
[ 📌 전체 코드 - Java ]
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
class Solution {
public int solution(String[][] book_time) {
Queue<Customer> waitingQ = new PriorityQueue<>(Comparator.comparing(a -> a.srtTime));
Queue<Customer> roomQ = new PriorityQueue<>(Comparator.comparing(a -> a.endTime));
int maxSize = 0;
for(String[] times : book_time) {
waitingQ.add(new Customer(getMinAndSec(times[0]), getMinAndSec(times[1])));
}
while(!waitingQ.isEmpty()) {
Customer cus = waitingQ.poll();
// 사용중인 호텔방 존재 && (체크인과 체크아웃 동시간 || 현 고객 체크인 시간보다 늦은 체크 아웃방)
while(!roomQ.isEmpty() && (roomQ.peek().endTime.equals(cus.srtTime) || cus.srtTime.isAfter(roomQ.peek().endTime))) {
roomQ.poll();
}
roomQ.add(cus);
maxSize = Math.max(maxSize, roomQ.size());
}
return maxSize;
}
private int[] getMinAndSec(String times) {
return Arrays.stream(times.split(":")).mapToInt(Integer::parseInt).toArray();
}
class Customer {
private final int CLEAN_TIME = 10;
LocalDateTime srtTime;
LocalDateTime endTime;
public Customer(int[] srtTime, int[] endTime) {
LocalDate nowDate = LocalDate.now();
this.srtTime = LocalDateTime.of(nowDate, LocalTime.of(srtTime[0], srtTime[1]));
this.endTime = LocalDateTime.of(nowDate, LocalTime.of(endTime[0], endTime[1])).plusMinutes(CLEAN_TIME);
}
}
}
[ 📌 결과 ]
[ 📌 마치며... ]
LocalTime... 항상 코드 전부 짜고, 정답 돌려본 후 후회 중이다..
이제는 무조건 LocalDateTime 으로 가도 되지 않을까?
사실 이 문제도 오래전에 처음 봤을 때는 어떻게 풀지 감도 안잡혔는데, 지금은 쉽게 풀어서 놀랐다.
어찌저찌 계속해서 역량이 올라가고 있다는 증거...게...ㅆ...지...?
728x90
'알고리즘 > Programmers' 카테고리의 다른 글
[ Programmers - LV2 ] 순위 검색 (2) | 2024.12.01 |
---|---|
[ Programmers - LV2 ] 리코쳇 로봇 (2) | 2024.09.09 |
[ Programmers - LV2 ] 쿼드압축 후 개수 세기 (1) | 2024.09.08 |
[ Programmers - LV2 ] 광물 캐기 (1) | 2024.09.01 |
[ Programmers - LV2 ] [3차] 파일명 정렬 (0) | 2024.08.25 |