회사에는 N개의 회의실이 있다. 수많은 팀이 모여 토론하고 업무를 처리하기 위해서는 회의실이 필수적이다.
내부망에 아주 간단한 회의실 예약 시스템이 있지만 편의성이 매우 떨어진다. 단순히 예약된 회의의 목록만 표시되기 때문에, 방 별로 비어 있는 시간이 언제인지를 확인하기가 힘든 것이다. 당신은 이를 직접 해결해 보기로 마음 먹었다.
회의실 이용 규칙은 다음과 같다:
회의실은 9시부터 18시까지만 사용 가능하다. 모든 회의의 시간은 이 안에 완전히 포함되어야 한다.
회의는 정확히 한 회의실을 연속한 일정 시간 동안만 점유한다. 즉 각 회의는 (회의실, 시작 시각, 종료 시각)의 정보로 나타낼 수 있다.
회의의 시작과 종료 시각은 시(時, hour) 단위로만 설정 가능하다. 같은 회의실을 사용하는 회의 시간은 서로 겹칠 수 없다. 여기서 겹친다는 것은, 두 회의 모두에 포함되는 시간이 1시간 이상 존재한다는 것을 의미한다. 예를 들어, 10시-12시의 회의와 11시-13시의 회의는 겹치는데, 11시-12시의 시간이 두 회의 모두에 포함되기 때문이다.
한 회의가 끝나는 시각에, 같은 회의실에서 다른 회의가 시작하는 것은 허용된다. 이 경우 두 회의가 겹치지 않기 때문이다.
길이가 0인 회의, 즉 시작 시각과 종료 시각이 동일한 회의는 예약된 바 없으며, 새롭게 잡을 수도 없다.
이미 예약된 M개의 회의에 대한 정보가 주어지면, 회의실별로 비어 있는 시간대를 정리해 출력하는 프로그램을 작성해 보자. 구체적인 형식은 아래를 참고하시오.
1 ≤ N ≤ 50
1 ≤ M ≤ 100
회의실의 이름은 영문 알파벳 소문자로만 이루어져 있으며 길이는 1 이상 10 이하이다.
주어지는 모든 시각은 9 이상 18 이하이다.
회의의 시작 시각은 회의의 종료 시각을 1시간 이상 앞선다.
첫째 줄에 회의실의 수와 예약된 회의의 수를 나타내는 정수 N과 M이 공백을 사이에 두고 주어진다.
이어 N개의 줄에는 각 회의실의 이름이 주어진다.
이어 M개의 줄에는 각 회의가 배정된 회의실의 이름 r과 시작 시각 s, 그리고 종료 시각 t가 공백을 사이에 두고 주어진다.
각 회의실에 대한 정보를 회의실 이름의 오름차순으로 출력한다.
각 회의실에 대한 정보는 다음과 같다.
첫째 줄에는 { Room 회의실이름: } (중괄호 제외)을 출력한다.
둘째 줄에는 예약가능 시간을 출력한다.
예약 가능한 시간대의 개수를 n이라고 할 때, { n available: } (중괄호 제외)을 출력하고, 뒤따른 n개의 줄에 예약 가능한 시간대를 { 09-18 } (하이픈 한개, 중괄호 제외)형태로 출력해야 한다. 한 자리 수의 경우 앞에 0을 붙여 두 자리 수로 만들어야 함에 유의하라.
예약 가능한 시간이 없다면, Not available을 출력한다.
각 회의실에 대한 정보 사이에는 ----- (하이픈 다섯 개)로 구분선이 출력되어야 한다.
3 7
grandeur
avante
sonata
sonata 14 16
grandeur 11 12
avante 15 18
sonata 10 11
avante 9 12
grandeur 16 18
avante 12 15
Roomavante:
Notavailable
-----
Roomgrandeur:
2available:
09-11
12-16
-----
Roomsonata:
3available:
09-10
11-14
16-18
고려해야 할 것도 많고, 처리해야 할 것도 많은 문제다.
회의실별로 길이가 9인 배열을 만들어서 시간대별 예약 여부를 관리했고, 모든 회의실과 각 배열을 객체로 관리했다.
배열의 길이가 9인 이유는 회의 시작 시간인 9시 ~ 17시까지를 체크하기 위함이다.
시간대별 예약 여부를 관리한 배열과 입력예제1 중 sonata와 grandeur는 다음과 같다.
시간대별로 예약이 되어 있으면 1을 더해줬다.
여기까지는 무난했으나, 출력할 부분을 처리하는 게 시간이 많이 걸렸다.
예약 가능 시간을 출력하는 부분을 정리하면 다음과 같다.
start
라는 변수를 -1
로 초기화했다.reserved_check
의 길이만큼 돌면서 start
값을 찾는다.start
를 찾고, 현재 값이 1
이라면 예약 가능한 시간대가 끝나는 부분이므로 available_times
(예약 가능한 시간을 저장하는 배열)에 넣어준다. 그리고 start
를 -1
로 다시 만들어주고, cnt
(예약 가능한 시간대 개수)에 1을 더해준다.start
를 찾았지만 회문이 끝났다면 reserved_check
의 마지막 값이 0
인 경우이므로 available_times
에 해당 시간부터 18시까지를 넣어준다.이 부분만 빨리 해결되었으면 빨리 풀었을텐데 생각보다 시간을 많이 잡아먹은 문제다.
전체 코드는 아래와 같다.
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
let array = []; // input값 저장할 배열
let rooms = {}; // 회의실 현황
rl.on("line", (line) => {
array.push(line.trim());
}).on("close", () => {
// 전체 회의실 수, 예약 건수
[total_rooms, reserved_cnt] = array[0].split(" ").map(Number);
let rooms_name = []; // 회의실 이름만 저장
// 회의실 개수만큼 순회하면서 회의실 이름 배열과 회의실 예약 현황 객체에 넣어주기
for (let i = 1; i <= total_rooms; i++) {
let room_name = array[i];
rooms_name.push(room_name);
rooms[room_name] = new Array(9).fill(0);
}
// 회의실 이름 오름차순 정렬
rooms_name.sort();
// 각 회의실의 예약된 시간에 +1하기
for (let i = total_rooms + 1; i < array.length; i++) {
let [room_name, start_time, end_time] = array[i].split(" ");
for (let j = parseInt(start_time) - 9; j < parseInt(end_time) - 9; j++) {
rooms[room_name][j] += 1;
}
}
// 출력하기
for (let i = 0; i < total_rooms; i++) {
let name = rooms_name[i]; // 회의실 이름
// 1) 회의실 이름 출력
console.log(`Room ${name}:`);
// 2) 예약 가능 시간 출력
let reserved_check = rooms[name]; // 해당 회의실의 사용 가능 여부
let cnt = 0; // 예약 가능한 시간대 개수
let start = -1; // 0이 시작하는 시간
let available_times = []; // 예약 가능한 시간 저장하는 배열
for (let i = 0; i < reserved_check.length; i++) {
// 예약 가능한 시간대 시작 시간 찾기
if (reserved_check[i] === 0 && (i === 0 || reserved_check[i - 1] === 1))
start = i + 9;
// 예약 가능한 시간대 추가 및 cnt에 1 더하기
if (reserved_check[i] === 1 && start !== -1) {
available_times.push(
`${String(start).padStart(2, "0")}-${String(i + 9).padStart(2, "0")}`
);
start = -1;
cnt++;
}
}
// 배열의 마지막 원소가 0인 경우 처리
if (start !== -1) {
available_times.push(`${String(start).padStart(2, "0")}-18`);
cnt++;
}
// 예약 가능한 시간이 없는 경우
if (!cnt) console.log("Not available");
// 예약 가능한 시간이 있는 경우
else {
console.log(`${cnt} available:`);
available_times.forEach((e) => console.log(e));
}
// 3) 구분선 출력
if (i !== total_rooms - 1) console.log("-----");
}
process.exit();
});