문제/프로그래머스

[프로그래머스 / Java] 유연근무제

icodesiuuuu 2025. 3. 6. 00:09

 

https://school.programmers.co.kr/learn/courses/30/lessons/388351

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

 

문제 개요

직원들이 설정한 출근 희망 시각과 실제 출근 시각을 비교하여, 정해진 기간 동안 지각 없이 출근한 직원의 수를 구하는 문제입니다.

  1. 직원은 1주일 동안 출근 희망 시각 + 10분 이내에 출근해야 합니다.
  2. 주말(토요일, 일요일)은 이벤트에 영향을 주지 않습니다.
  3. 출근 시각은 HHMM 형식의 정수로 주어지며, 이를 시간과 분 단위로 변환하여 비교해야 합니다.
  4. 주어진 시작 요일(startday)에 따라 출근 기록을 주중과 주말로 구분하여 검사해야 합니다.

 

접근 방법

  1. 출근 인정 시각 계산
    • 각 직원의 출근 희망 시각(schedules)에서 10분을 더하여 출근 인정 시각을 계산합니다.
    • 예를 들어 700이면 710, 958이면 1008로 변환합니다.
    • 분을 더할 때 60분이 넘어가면 시(hour)를 증가시키고, 분(minute)을 조정해야 합니다.
  2. 요일 계산
    • 이벤트 시작 요일(startday)을 기준으로 한 주간의 출근 요일을 설정합니다.
    • 주말(토, 일)은 검사 대상에서 제외하고, 평일(월~금)의 출근 기록만 확인합니다.
    • startday부터 7일까지 반복하면서 평일인지 확인합니다.
  3. 지각 여부 확인
    • 각 직원별로 평일(월~금) 출근 기록을 검사합니다.
    • 해당 요일의 출근 시각이 출근 인정 시각 이하라면 정상 출근으로 간주합니다.
    • 한 번이라도 지각(출근 인정 시각 초과)하면 해당 직원은 상품을 받을 수 없습니다.

 

 

처음 작성한 코드

import java.util.*;
class Solution {
    public int solution(int[] schedules, int[][] timelogs, int startday) {
        int answer = 0;
        
        for(int i=0; i<schedules.length; i++) {
            if(isPossible(schedules[i], timelogs[i], startday)) answer++;
        }
        
        return answer;
    }
    
    public boolean isPossible(int standard, int[] day, int startday) {
        for(int i=0; i<day.length; i++) {
            if(startday == 6 || startday == 7) {
                startday++;
                if(startday > 7) startday = 1;
                continue;
            }
            
            String s = String.valueOf(standard);
            int hour = 0;
            int min = 0;
            
            if(s.length() == 3) {
                hour = Integer.valueOf(s.substring(0, 1));
                min = Integer.valueOf(s.substring(1, 3));
            } else {
                hour = Integer.valueOf(s.substring(0, 2));
                min = Integer.valueOf(s.substring(2, 4));
            }
            
            min += 10;
            if(min >= 60) {
                hour++;
                min -= 60;
            }
            
            String bucket = "";
            if(min >= 10) {
                bucket = String.valueOf(hour).concat(String.valueOf(min));
            } else {
                bucket = String.valueOf(hour).concat("0".concat(String.valueOf(min)));
            }
            
            if(day[i] > Integer.valueOf(bucket)) return false;
            
            startday++;
            if(startday > 7) startday = 1;
        }
        
        return true;
    }
}

 

 

개선한 코드

import java.util.*;

class Solution {
    public int solution(int[] schedules, int[][] timelogs, int startday) {
        int answer = 0;
        
        for (int i = 0; i < schedules.length; i++) {
            if (isPossible(schedules[i], timelogs[i], startday)) {
                answer++;
            }
        }
        
        return answer;
    }
    
    public boolean isPossible(int standard, int[] day, int startday) {
        int hour = standard / 100;
        int min = standard % 100;
        min += 10;
        
        if (min >= 60) {
            hour++;
            min -= 60;
        }
        
        int maxTime = hour * 100 + min; // 허용되는 최대 출근 시각
        
        for (int i = 0; i < day.length; i++) {
            if (startday == 6 || startday == 7) { // 토, 일은 건너뜀
                startday = (startday % 7) + 1;
                continue;
            }

            if (day[i] > maxTime) {
                return false; // 출근 시간이 허용 범위를 초과하면 실패
            }
            
            startday = (startday % 7) + 1; // 다음 요일로 이동
        }
        
        return true;
    }
}