문과 코린이의, [C#] 기록/C# CodingTest

[문과 코린이의 IT 기록장] C# 프로그래머스(Programmers) - 호텔 대실

벼리네 2023. 3. 9. 11:43
반응형

[문과 코린이의 IT 기록장] C# 프로그래머스(Programmers) - 호텔 대실

[문과 코린이의 IT 기록장] C# 프로그래머스(Programmers) - 호텔 대실


 

코딩테스트 연습 | 프로그래머스 스쿨

개발자 취업의 필수 관문 코딩테스트를 철저하게 연습하고 대비할 수 있는 문제를 총망라! 프로그래머스에서 선발한 문제로 유형을 파악하고 실력을 업그레이드해 보세요!

school.programmers.co.kr


1. Problem

1) 문제 설명

호텔을 운영 중인 코니는 최소한의 객실만을 사용하여 예약 손님들을 받으려고 합니다. 한 번 사용한 객실은 퇴실 시간을 기준으로 10분간 청소를 하고 다음 손님들이 사용할 수 있습니다.
예약 시각이 문자열 형태로 담긴 2차원 배열 book_time이 매개변수로 주어질 때, 코니에게 필요한 최소 객실의 수를 return 하는 solution 함수를 완성해주세요.

2) 제한 사항

  • 1 ≤ book_time의 길이 ≤ 1,000
    • book_time[i]는 ["HH:MM", "HH:MM"]의 형태로 이루어진 배열입니다
      • [대실 시작 시각, 대실 종료 시각] 형태입니다.
    • 시각은 HH:MM 형태로 24시간 표기법을 따르며, "00:00" 부터 "23:59" 까지로 주어집니다.
      • 예약 시각이 자정을 넘어가는 경우는 없습니다.
      • 시작 시각은 항상 종료 시각보다 빠릅니다.

3) 입출력 예

book_time result
[["15:00", "17:00"], ["16:40", "18:20"], ["14:20", "15:20"], ["14:10", "19:20"], ["18:20", "21:20"]] 3
[["09:10", "10:10"], ["10:20", "12:20"]] 1
[["10:20", "12:30"], ["10:20", "12:30"], ["10:20", "12:30"]] 3

2. Solution

1) 내가 푼 정답 1

using System;
using System.Collections.Generic; 
using System.Linq; 

public class Solution {
    class Book
        {
            public int start_time { get; set; }
            public int end_time { get; set; }
        }
    
     static int toMinute(string time)
        {
            string[] splittime = time.Split(':');
            int hour = int.Parse(splittime[0]);
            int minute = int.Parse(splittime[1]);
            return hour * 60 + minute;
        }
    
    public int solution(string[,] book_time) {
         List<Book> bookList = new List<Book>();
            string startTime = "";
            string endTime = "";
            int answer = 0;

            foreach (var item in book_time.ToColumn())
            {
                if (startTime == "")
                {
                    startTime = item;
                }
                else
                {
                    endTime = item;
                    bookList.Add(new Book() { start_time = toMinute(startTime), end_time = toMinute(endTime) + 10 });
                    startTime = ""; endTime = "";
                }
            }

            // 시작 시간대로 정렬
            List<Book> sortBookList = bookList.OrderBy(x => x.start_time).ToList();

            // 방 몇개가 필요한지 체크
            Dictionary<int, int> dicroom = new Dictionary<int, int>(); // idx, end_time
            int cnt = 1;

            foreach (var etime in sortBookList)
            {
                if (dicroom.Count == 0)
                {
                    dicroom.Add(cnt, etime.end_time);
                    cnt++;
                    continue;
;                }

                bool isOk = false;

                for (int i = 1; i <= dicroom.Count; i++)
                {
                    dicroom.TryGetValue(i, out int comptime);

                    if (etime.start_time >= comptime) 
                    {
                        dicroom[i] = etime.end_time;
                        isOk = true;
                        break;
                    }
                }

                if (!isOk)
                {
                    dicroom.Add(dicroom.Count + 1, etime.end_time);
                }

            }

            answer = dicroom.Count;
            return answer;
    }
}

 static class Extension
    {
        public static IEnumerable<T> ToColumn<T>(this T[,] array)
        {
            for (int i = 0; i < array.GetLength(0); i++)
            {
                for (int j = 0; j < array.GetLength(1); j++)
                {
                    yield return array[i, j];
                }
            }
        }
    }

2) 다른 사람 풀이 참고 1

using System;
using System.Collections.Generic; 
using System.Linq; 

public class Solution {
    public int solution(string[,] book_time) {
           int answer = 0;
             int[] room = new int[1500]; // 24시간 * 60분 = 1440분

            for (int i = 0; i < book_time.GetLength(0); i++) // GetLength(0) : 행의 개수
            {
                string[] startTimestr = book_time[i, 0].Split(':');
                string[] endTimeStr = book_time[i, 1].Split(':');

                // 분으로 변경
                int startTime = int.Parse(startTimestr[0]) * 60 + int.Parse(startTimestr[1]);
                int endTime = int.Parse(endTimeStr[0]) * 60 + int.Parse(endTimeStr[1]) + 10;

                // j분에 방이 필요한지 저장.
                for (int j = startTime ; j < endTime; j++)
                {
                    room[j]++;
                }
            }
            for (int i = 0; i < 1500; i++)
            {
                // answer = 같은 시간에 가장 많은 방이 필요할 케이스
                if (answer < room[i]) 
                {
                    answer = room[i];
                }
            }

            return answer;
    }
}

3) 다른 사람 풀이 참고 2

using System;
using System.Collections.Generic; 
using System.Linq; 

public class Solution {
    public int solution(string[,] book_time) {
            int answer = 0;

            int len = book_time.GetLength(0); // 행개수
            
            int[] start = new int[len];
            int[] end = new int[len];
            int[] assigned = new int[len];      // 해당 시간이 방에 할당되었는지 확인
            int[] room_end = new int[len + 1];


            for (int i = 0; i < len; i++)
            {
                // 시작값 분으로 변환해서 저장
                int[] tmp = Array.ConvertAll(book_time[i, 0].Split(':'), int.Parse); 
                // Array로 tmp[]에 2개로 나누어 저장해야 하므로, Array.ConvertAll을 사용해야 함.
                start[i] = tmp[0] * 60 + tmp[1];

                // 종료값 분으로 변환해서 저장
                tmp = Array.ConvertAll(book_time[i, 1].Split(':'), int.Parse);
                end[i] = tmp[0] * 60 + tmp[1] + 10;
            }
            // Sort(Array, Array) : 앞에 있는 배열을 기준으로 두 개의 배열을 오름차순 정렬한다.
            Array.Sort(start, end);

            // 모든 입력값(len)이 다 할당되는 경우까지 돌리기
            while (assigned.Sum() != len)
            {
                for (int i = 0; i < len; i++)
                {
                    // 아직 해당 입력값이 방에 할당되지 않았고, 저장된 종료시간보다 시작시간이 크거나 같다면
                    if (assigned[i] == 0 && room_end[answer] <= start[i]) 
                    {
                        room_end[answer] = end[i]; // 종료시간을 저장
                        assigned[i] = 1; // i번째 입력값은 방에 할당 됨.
                    }
                }
                answer++;
            }

            return answer;
    }
}
반응형