Programmers LV.2 아날로그 시계 - PCCP 기출문제 3번 - Python3
문제 설명
시침, 분침, 초침이 있는 아날로그시계가 있습니다. 시계의 시침은 12시간마다, 분침은 60분마다, 초침은 60초마다 시계를 한 바퀴 돕니다. 따라서 시침, 분침, 초침이 움직이는 속도는 일정하며 각각 다릅니다. 이 시계에는 초침이 시침/분침과 겹칠 때마다 알람이 울리는 기능이 있습니다. 당신은 특정 시간 동안 알람이 울린 횟수를 알고 싶습니다.
(세부사항 프로그래머스 사이트 확인 - 글 하단에 링크 첨부)
알람이 울리는 횟수를 센 시간을 나타내는 정수 h1, m1, s1, h2, m2, s2가 매개변수로 주어집니다. 이때, 알람이 울리는 횟수를 return 하도록 solution 함수를 완성해주세요.
제한사항
- 0 ≤ h1, h2 ≤ 23
- 0 ≤ m1, m2 ≤ 59
- 0 ≤ s1, s2 ≤ 59
- h1시 m1분 s1초부터 h2시 m2분 s2초까지 알람이 울리는 횟수를 센다는 의미입니다.
- h1시 m1분 s1초 < h2시 m2분 s2초
- 시간이 23시 59분 59초를 초과해서 0시 0분 0초로 돌아가는 경우는 주어지지 않습니다.
입출력 예

입출력 예 설명
입출력 예 #4
- 11시 59분 30초부터 11시 59분 59초까지 초침과 시침/분침이 겹치는 일은 없습니다.
- 12시 0분 0초에 초침과 시침, 분침이 겹칩니다. 이때 알람이 한 번 울립니다.
11시 59분 30초부터 12시 0분 0초까지 초침과 시침/분침이 겹치는 횟수는 1이며 따라서 알람이 한 번 울립니다.
입출력 예 #5
- 약 11시 58분 59.917초에 초침과 시침이 겹칩니다. 이때 알람이 한 번 울립니다.
11시 58분 59초부터 11시 59분 0초까지 초침과 시침/분침이 겹치는 횟수는 1이며 따라서 알람이 한 번 울립니다.
입출력 예 #6
- 약 1시 5분 5.085초에 초침과 분침이 겹칩니다. 이때 알람이 한 번 울립니다.
- 약 1시 5분 5.424초에 초침과 시침이 겹칩니다. 이때 알람이 한 번 울립니다.
1시 5분 5초부터 1시 5분 6초까지 초침과 시침/분침이 겹치는 횟수는 2며 따라서 알람이 두 번 울립니다.
입출력 예 #7
0시 0분 0초부터 23시 59분 59초까지 초침과 시침/분침이 겹치는 횟수는 2852며 따라서 알람이 총 2852번 울립니다.
통과된 코드
def pos(type, h, m, s):
if type == "hour":
pos = h * 5 + m / 12 + s / 720
pos = pos - 60 if pos >= 60 else pos
elif type == "min":
pos = m + s / 60
pos = pos - 60 if pos >= 60 else pos
elif type == "sec":
pos = s - 60 if s >= 60 else s
else:
raise ValueError("Invalid type. Please use 'hour', 'min', or 'sec'.")
return pos
def is_slower_and_same_than(h1, m1, s1, h2, m2, s2):
if h1 > h2:
return False
if h1 == h2:
if m1 > m2:
return False
if m1 == m2:
if s1 > s2:
return False
return True
return True
def one_sec_flow(h, m, s):
s += 1
if s == 60:
s = 0
m += 1
if m == 60:
m = 0
h += 1
return h, m, s
def solution(h1, m1, s1, h2, m2, s2):
h, m, s = h1, m1, s1
cnt = 1 if pos("hour", h, m, s) == pos("min", h, m, s) == pos("sec", h, m, s) else 0
about_to_be_same = 0
while is_slower_and_same_than(h, m, s, h2, m2, s2):
cnt += about_to_be_same
about_to_be_same = 0
pos_h = pos("hour", h, m, s)
pos_m = pos("min", h, m, s)
pos_s = pos("sec", h, m, s)
next_pos_h = pos("hour", h, m, s + 1)
next_pos_m = pos("min", h, m, s + 1)
next_pos_s = pos("sec", h, m, s + 1)
if next_pos_h == next_pos_m == next_pos_s:
about_to_be_same += 1
print("hour and min: ", h, m, s, pos_h, pos_m, pos_s)
else:
if pos_h > pos_s and next_pos_h <= (60 if next_pos_s == 0 else next_pos_s):
about_to_be_same += 1
print("hour: ", h, m, s, pos_h, pos_m, pos_s)
if pos_m > pos_s and next_pos_m <= (60 if next_pos_s == 0 else next_pos_s):
about_to_be_same += 1
print("min: ", h, m, s, pos_h, pos_m, pos_s)
h, m, s = one_sec_flow(h, m, s)
return cnt
풀이
우선 위 코드에 사용된 3가지 함수들에 대핸 간단히 설명하자면 다음과 같다.
1. pos(type, h, m, s): 현재 시각을 매개변수로 받아 type에 따라 (시침, 분침, 초침) 총 60칸으로 나뉘어진 시계 칸 위치 중 어디에 위치해 있는지를 계산한다.
2. is_slower_and_same_than(h1, m1, s1, h2, m2, s2): h1, m1, s1이 h2, m2, s2의 시간보다 느리거나 같은지 비교한다.
3. one_sec_flow(h, m, s): 1초 씩 증가하기 위해 사용됨
메인 코드의 풀이는 다음과 같다.
시간을 1초 씩 증가시키며 시침, 분침, 초침의 현재 위치 & 1초 뒤의 위치를 비교해 겹치는 횟수를 센다.
주의할 점은 아래와 같다.
- 시침, 분침, 초침이 모두 겹칠 경우에는 알림이 한 번만 울린다. 이에 1초 뒤 시침, 분침, 초침의 위치가 모두 같아지는지 확인해야 한다.
- 처음에 울릴 경우도 생각한다. (e.g. 12:00에 시작했을 때 바로 한 번 울림) 이에 처음 cnt 변수를 설정할 때, 시침, 분침, 초침의 위치가 모두 같다면 1로 아니라면 0으로 설정한다.
- 정수가 아니라 그 사이에 알림이 울릴 수 있기에, about_to_be_same 변수를 활용해 알림이 울리는 횟수를 센다.
초침과 시침 혹은 초침과 분침이 겹치는지 확인할 때는 (지금은 시침이 앞서 있지만) && (1초 뒤에는 초침이 앞서 있음) 로 확인한다.
실행 결과
| 테스트 1 〉 | 통과 (57.34ms, 10.3MB) |
| 테스트 2 〉 | 통과 (68.17ms, 10.2MB) |
| 테스트 3 〉 | 통과 (19.72ms, 10.3MB) |
| 테스트 4 〉 | 통과 (58.48ms, 10.4MB) |
| 테스트 5 〉 | 통과 (1.66ms, 10.4MB) |
| 테스트 6 〉 | 통과 (28.63ms, 10.3MB) |
| 테스트 7 〉 | 통과 (70.56ms, 10.3MB) |
| 테스트 8 〉 | 통과 (64.22ms, 10.3MB) |
| 테스트 9 〉 | 통과 (90.17ms, 10.3MB) |
| 테스트 10 〉 | 통과 (97.77ms, 10.5MB) |
| 테스트 11 〉 | 통과 (45.96ms, 10.2MB) |
| 테스트 12 〉 | 통과 (9.29ms, 10.3MB) |
| 테스트 13 〉 | 통과 (123.17ms, 10.3MB) |
| 테스트 14 〉 | 통과 (78.57ms, 10.4MB) |
| 테스트 15 〉 | 통과 (0.03ms, 10.3MB) |
| 테스트 16 〉 | 통과 (45.01ms, 10.4MB) |
| 테스트 17 〉 | 통과 (47.26ms, 10.3MB) |
| 테스트 18 〉 | 통과 (10.67ms, 10.3MB) |
| 테스트 19 〉 | 통과 (162.55ms, 10.4MB) |
| 테스트 20 〉 | 통과 (158.61ms, 10.3MB) |
https://school.programmers.co.kr/learn/courses/30/lessons/250135
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
'computer science > algorithm' 카테고리의 다른 글
| [프로그래머스] 완주하지 못한 선수 | Python3 LV.1 (0) | 2023.06.09 |
|---|---|
| [프로그래머스] 햄버거 만들기 | Python3 LV.1 (1) | 2023.06.08 |
| [프로그래머스] 성격 유형 검사하기 | Python3 LV.1 (0) | 2023.06.07 |
| [프로그래머스] 바탕화면 정리 | Python3 LV.1 (0) | 2023.06.06 |
| [프로그래머스] 옹알이 (1) | Python3 LV.0 (1) | 2023.06.05 |