프로그래머스-2018 KAKAO BLIND RECRUITMENT ( 추석 트래픽 by Java )

Flash·2022년 2월 22일
0

Programmers-Algorithm

목록 보기
43/52
post-thumbnail

구현

프로그래머스 2018 KAKAO BLIND RECRUITMENT Level 3 문제 추석 트래픽Java를 이용해 풀어보았다.
시간 값을 비교할 때에 편리한 로직을 배우게 됐다.

문제 링크 첨부한다.
https://programmers.co.kr/learn/courses/30/lessons/17676


시간값 변환해주기

두 개의 시각을 하나의 구간으로 보고, 두 개의 구간끼리 겹치는지 판별해주기 위한 로직이 필요하다. 나는 처음에 HH:mm:ss.sss 형식 그대로 사용해서 시간끼리 서로 비교할 수 있도록 로직을 짜려 했는데 아무리 생각해도 너무 더러웠다.

알고보니 시간에 60*60*1000 배를 해서 ms 단위로 바꿔주고, 분에는 60*1000배를 해서 ms 단위로 바꿔주는 작업을 시간 + 분 + 초를 하면 하나의 고유한 시간값을 구할 수 있었다.

하나의 입력값에 대해 작업 종료 시각과 응답 처리 시간을 파싱해서 받은 후에 위와 같은 작업을 통해 작업 시작 시각과 작업 종료 시각을 위와 같이 변환하여 하나의 Info 클래스에 시작 시각과 끝 시각을 담도록 했다.

Info 클래스의 코드는 다음과 같다.

class Info{
        int start;
        int end;

        Info(String line){
            String[] split = line.split("\\s");
            String endStr = split[1];
            String resStr = split[2];

            String[] endTimeSplit = endStr.split(":");
            int hrs = Integer.parseInt(endTimeSplit[0])*60*60*1000;
            int mins = Integer.parseInt(endTimeSplit[1])*60*1000;
            int secs = (int)(Double.parseDouble(endTimeSplit[2])*1000);
            this.end = hrs + mins + secs;

            resStr = resStr.replaceAll("s","");
            int resTime = (int)(Double.parseDouble(resStr)*1000);

            this.start = this.end - resTime + 1;
        }

        Info(int start, int end){
            this.start = start;
            this.end = end;
        }

        Boolean isOverLap(Info target){
            if(target.end < this.start || this.end < target.start)  return false;
            return true;
        }

        Integer getStart(){ return this.start; }
    }

그럼 이 Info 클래스를 활용해서 입력값으로 주어지는 모든 구간들을 list에 저장해준 후에 시작 시각 기준으로 오름차순 정렬을 해주면 된다.

이를 코드로 표현하면 다음과 같다.

ArrayList<Info> list = new ArrayList<>();

for(String line: lines)
       list.add(new Info(line));
       
list.sort(Comparator.comparing(Info::getStart));

몇 개 구간을 포함하고 있는지

list에 있는 모든 구간에 대해 시작 시각으로부터 1초, 끝 시각으로부터 1초까지의 새로운 Info 객체를 생성해서 list의 모든 구간에 대해 몇 개나 겹치는지 조사를 하며 겹친 개수들을 또다른 list에 저장해준 후에 그 중 가장 큰 값을 꺼내면 문제에서 요구하는 답이다.

이를 코드로 표현하면 다음과 같다.

ArrayList<Integer> overlap = new ArrayList<>();

for(Info cur: list){
//            Info target1 = new Info(cur.start, cur.start+999);
       Info target2 = new Info(cur.end, cur.end+999);
//            int target1OverLapNum = 0;
       int target2OverLapNum = 0;
       for(Info test: list){
//                if(test.isOverLap(target1)) target1OverLapNum++;
           if(test.isOverLap(target2)) target2OverLapNum++;
       }
//            if(overlap.indexOf(target1OverLapNum)<0)    overlap.add(target1OverLapNum);
       if(overlap.indexOf(target2OverLapNum)<0)    overlap.add(target2OverLapNum);
}
Collections.sort(overlap, Collections.reverseOrder());
return overlap.get(0);

시작 시각으로부터 1초까지의 구간인 target1을 주석 처리한 이유는 어차피 필요가 없기 때문이다.

카카오 테크 블로그의 해설을 참고하면 시작과 끝에 대해 모두 1초 지난 구간을 조사해야 된다고 나와있지만, 생각해보니 끝으로부터 1초까지의 구간만 확인해도 다 커버가 될 거라는 생각이 들었고 실제로 수행해보니 모든 테스트 케이스를 다 통과했다.

오늘 문제 풀이는 사실 말보다도 그냥 값을 비교한 후에 겹치는 개수만 뽑아내면 되는 거기 때문에 ms 단위까지 포함하는 시간을 HH:mm:ss.sss 형식 그대로가 아닌 변환된 형태로 저장해주는 것이 가장 주요했다.

profile
개발 빼고 다 하는 개발자

0개의 댓글