


난이도 : Level 1
문제 출처
schedules : 출근 희망 시각
timelogs : 일주일 동안 출근한 시각
startday : 이벤트를 시작한 요일
가 주어진다.
일주일동안 출근 희망 시각 schedules + 10분에 늦지 않고 출근한 직원들에게 상품을 준다고 한다.
토,일요일 출근 시각은 영향을 끼치지 않을 때, 상품을 받을 직원 수를 return해야 한다.
시 * 100 + 분
ex) 7시 30분 -> 730 이런식으로 계산하므로
만약 +10분을 했을 때 60분을 넘어간다면 시간을 더해주는 로직이 하나 필요해보였다.
timelogs 에 '토','일' 을 뺀 배열도 필요해보였다.이렇게 만든 1번 배열 - 직원의 희망출근 시각 + 10분 한 값과,
2번 배열 - timelogs에 '토','일 을 뺀 월화수목금 출근 시각을 비교해가면서
출근시간을 전부 잘 지킨 직원의 수를 +=1 하여 count를 반환해줬다.
function solution(schedules, timelogs, startday) {
const weekendMap = {
1: [5, 6],
2: [4, 5],
3: [3, 4],
4: [2, 3],
5: [1, 2],
6: [0, 1],
7: [0, 6],
};
// timelogs에서 토요일 ,일요일 빼기
const filteredTimelogs = timelogs.map((timelog) => timelog.filter((time, idx) => {
return idx !== weekendMap[startday][0] && idx !== weekendMap[startday][1]
}))
// filteredTimelogs = [[710,700,650,631,659],[800,800,759,810,809],[1105,600,1059,1001,1100]]
// ---
// schedules의 값에 + 10 한것을 870 -> 910 이렇게 변환 작업
const deadlines = []
for (let schedule of schedules) {
let plusTen = schedule + 10 // 865
// 865가 905 가 되어야 함
// 10의 자리 수가 6 이라면, ( 10을 더하니까 바로 7 이상이 될 순 없음 )
// 해당 자리 수 0으로 만들고, 100의 자리수에 + 1해주기
const StrPlusTen = String(plusTen) // "865"
// 뒤에서부터 2번째 수 = 10의 자리 (앞에서 부터 셀 경우 또 두자리 or 한자리)
if (StrPlusTen[StrPlusTen.length-2] === "6"){
plusTen -= 60
plusTen += 100
}
deadlines.push(plusTen)
}
// deadlines = [710,810,1110]
let count = 0
for (let i = 0; i< schedules.length; i++){
// [710,700,650,631,659] ,
if (filteredTimelogs[i].every((time) => { return time <= deadlines[i]})) {
count += 1
}
}
return count
}
def solution(schedules, timelogs, startday):
# getExceptWeekend 함수 만들기 중단, 상수 딕셔너리로 만들기로 결정
weekend_map = {
1: [5, 6],
2: [4, 5],
3: [3, 4],
4: [2, 3],
5: [1, 2],
6: [0, 1],
7: [0, 6],
}
# timelogs에서 토요일, 일요일 빼기
filtered_timelogs = []
for timelog in timelogs:
filtered = []
for idx, time in enumerate(timelog):
if idx != weekend_map[startday][0] and idx != weekend_map[startday][1]:
filtered.append(time)
filtered_timelogs.append(filtered)
# schedules의 값에 10분 더하기
deadlines = []
for schedule in schedules:
plus_ten = schedule + 10
str_plus_ten = str(plus_ten)
# 뒤에서 두 번째 숫자가 6이면, 분이 60분대가 된 것
# 예: 850 + 10 = 860 -> 900으로 변환
if str_plus_ten[-2] == "6":
plus_ten -= 60
plus_ten += 100
deadlines.append(plus_ten)
count = 0
for i in range(len(schedules)):
if all(time <= deadlines[i] for time in filtered_timelogs[i]):
count += 1
return count
JS에서 array.every 메서드가 파이썬에서는 all() 함수이다.
all() 안에 있는 조건이 전부 참이어야 True 반환된다.
처음에는 startday에 따라 토요일, 일요일 인덱스의 값을 구해보려다가,
접어두고 상수 객체로 선언해 꺼내썼다.
하지만 요일은 7일 주기로 반복되기 때문에, 직접 계산으로도 구할 수 있다.
토요일은 숫자로 6이다.
startday에서 토요일까지 며칠 떨어져 있는지를 구하면, 그 값이 곧 timelog 배열에서의 토요일 인덱스가 된다.
예를 들어 startday별 토요일 인덱스를 직접 써보면 다음과 같다.
| startday | 시작 요일 | 토요일 index |
|---|---|---|
| 1 | 월요일 | 5 |
| 2 | 화요일 | 4 |
| 3 | 수요일 | 3 |
| 4 | 목요일 | 2 |
| 5 | 금요일 | 1 |
| 6 | 토요일 | 0 |
| 7 | 일요일 | 6 |
startday가 1부터 6까지일 때는 다음 식으로 토요일 인덱스를 구할 수 있다.
6 - startday
예를 들어 startday = 1이면,
6 - 1 = 5
이므로 토요일 인덱스는 5가 된다.
startday = 6이면,
6 - 6 = 0
이므로 토요일 인덱스는 0이 된다.
그런데 startday = 7, 즉 일요일부터 시작하는 경우에는 문제가 생긴다.
6 - 7 = -1
토요일이 일요일보다 숫자상으로 앞에 있기 때문에 음수가 나온다.
하지만 배열 인덱스는 0부터 6까지만 사용할 수 있다.
따라서 음수가 나오지 않도록 한 바퀴를 돌리는 처리가 필요하다.
요일은 7일 주기로 반복되므로, 먼저 7을 더해준다.
6 - startday + 7
그리고 결과가 7 이상이 될 수도 있으므로, 다시 7로 나눈 나머지를 사용한다.
그래서 토요일 인덱스는 다음과 같이 구할 수 있다.
const saturdayIndex = (6 - startday + 7) % 7;
일요일은 항상 토요일 다음 날이다.
따라서 기본적으로 일요일 인덱스는 다음과 같다.
saturdayIndex + 1
하지만 토요일 인덱스가 6인 경우에는 문제가 생긴다.
예를 들어 saturdayIndex = 6이면,
6 + 1 = 7
이 된다.
배열 인덱스는 0부터 6까지만 존재하므로, 7이 아니라 다시 0으로 돌아와야 한다.
그래서 일요일 인덱스도 7로 나눈 나머지를 사용한다.
const sundayIndex = (saturdayIndex + 1) % 7;
const saturdayIndex = (6 - startday + 7) % 7;
const sundayIndex = (saturdayIndex + 1) % 7;
정리하면, 토요일 인덱스는 startday에서 토요일까지의 거리이고,
일요일 인덱스는 토요일 인덱스의 다음 칸이다.
요일처럼 일정한 주기로 반복되는 값은
%연산을 사용하면 깔끔하게 처리할 수 있다.