2023. 10. 20. 17:18ㆍ파이썬(Python)
1. 시간 계산
- 만약 2시 34분에서 5시 43분이 되려면 몇 분이 흘러야 할까?
- 이럴 경우 5시 43분과 2시 34분 사이의 거리와 같다.
- 위 그림에서 0시 0분에서 2시 34분까지의 거리를 A라고 한다.
- 0시 0분에서 5시 43분까지의 거리를 B라고 한다.
- 2시 34분과 5시 43분 사이의 거리는 C이므로 B에서 A를 뺀 값과 같다.
- 이를 계산의 편의성으로 시를 분으로 고치면 2시 34분은 2*60+34=154분이 되고 A는 154가 된다.
- 5시 43분은 5*60+43=343분이 되고 A는 343이 된다.
- 따라서 C는 343 - 154 = 189가 되고 189분이 소요되었다는 것을 알 수 있다.
a, b, c, d = map(int, input().split())
t1 = a*60+b
t2 = c*60+d
print(f'{a}시 {b}분부터 {c}시 {d}분까지 소요된 시간은 {t2-t1}분입니다.')
2 34 5 43
2시 34분부터 5시 43분까지 소요된 시간은 189분입니다.
Q) 시간 계산
- a시 b분부터 c시 d분까지 몇 시간 몇 분 소요되었는지 출력하라
- 0 <=a <=c <=23
- 0 <=b <=d <=59
- 조건이 맞지 않으면 재입력을 요구하라.
while True:
a, b, c, d = map(int, input().split())
if a >= c and b > d:
print('다시 입력해 주세요.')
continue
t1 = a*60+b
t2 = c*60+d
minute = t2-t1
hour = minute // 60
minute -= 60*hour
break
print(f'{a}시 {b}분부터 {c}시 {d}분까지 소요된 시간은 {hour}시간 {minute}분입니다.')
>> 2 34 2 32
다시 입력해 주세요.
>> 2 34 5 43
2시 34분부터 5시 43분까지 소요된 시간은 3시간 9분입니다.
- 입력한 시가 같아도 후에 입력한 분이 더 크면 오류이므로 다시 입력하라는 메시지를 출력한다.
- 입력한 두 시간의 차이를 분 (minute)으로 계산한다.
- 분을 60으로 나누어 시간 (hour)을 계산한다.
- minute을 hour에 60을 곱한 값을 빼서 minute을 갱신한다.
2. 날짜 계산
- 2월 10일부터 10월 12일까지 며칠이 있을까? (2월은 28일까지 있다고 가정하자.)
- 1월 1일부터 2월 10일까지 일수를 A라 한다.
- 1월 1일부터 10월 12일까지 일수를 B라 한다.
- B에서 A를 뺀 일 수가 2월 11일부터 10월 12일이므로 2월 10일을 포함하기 위해 1을 더한다. (이 값이 C가 된다.)
- A는 31+10 = 41이다.
- B는 31+28+31+30+31+30+31+31+30+12 = 285이다.
- C = 285-41+1 = 245이다.
- 따라서 2월 10일부터 10월 12일까지 245일이다.
m1, d1, m2, d2 = map(int, input().split())
month = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
def count_days(m1, d1):
days = 0
for m in range(1, m1):
days += month[m]
days += d1
return days
days = count_days(m2, d2)-count_days(m1, d1)+1
print(f'{m1}월 {d1}일부터 {m2}월 {d2}일까지 {days}일 있다.')
2 10 10 12
2월 10일부터 10월 12일까지 245일 있다.
3. 날짜, 시간 혼합 계산
- 만약 5월 8일 11시 10분부터 6월 29일까지 10시 30분까지 얼마나 걸릴까?
m1, d1, h1, n1, m2, d2, h2, n2 = map(int, input().split())
def count_days(m, d):
days = 0
month = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
for m in range(1, m):
days += month[m]
days += d
return days
def count_time(h, n):
return h*60+n
days = count_days(m2, d2) - count_days(m1, d1)
time = count_time(h2, n2) - count_time(h1, n1)
if time < 0:
days -= 1
time = 24*60+time
hour, minute = time // 60, time % 60
print(f'{m1}월 {d1}일 {h1}시 {n1}분 부터 {m2}월 {d2}일 {h2}시 {n2}분까지 {days}일 {hour}시간 {minute}분 걸립니다.')
>> 5 8 11 10 6 29 10 30
5월 8일 11시 10분 부터 6월 29일 10시 30분까지 51일 23시간 20분 걸립니다.
- count_days : 날짜를 계산하는 함수이다. 1월 1일부터 m2월 d2일까지의 일 수와 1월 1일부터 m1월 d1일까지의 일 수의 차이를 구한다. (days)
- count_time : 시간을 계산하는 함수이다. 0시 0분부터 h2시 n2분까지의 시간과 0시 0분부터 h1시 n1분까지의 시간의 차이를 구한다. (time)
- 만약 5월 8일 11시 10분부터 6월 29일까지 10시 30분이라면 time의 값이 음수가 나온다. time은 -40이다.
- 또한 days는 52일이 나오는데 이는 5월 8일 11시 10분부터 6월 29일까지 11시 10분을 의미한다.
- 따라서 52일 0시간 0분에서 40분을 빼야 한다.
- 즉, time이 음수이면 24시간인 1440분 (24*60)에서 time을 더한다.
- time의 값은 분이기 때문에 60을 나누어 몫은 시간이 되고 나머지는 분이 된다.
4. 요일 구하기
- 만약, 2020년 10월 13일이 화요일이라 가정하면, 2023년 10월 13일은 어떤 요일인지 구하라.
- 윤년일 경우 2월은 29일까지이다.
y1, m1, d1, weekday = input('날짜와 요일을 입력하라. ').split()
y1, m1, d1 = int(y1), int(m1), int(d1)
y2, m2, d2 = input('요일을 구할 날짜를 입력하라. ').split()
y2, m2, d2 = int(y2), int(m2), int(d2)
week = ['Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat', 'Sun']
month = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
def leap_year(y):
if y % 4 == 0:
if y % 100 == 0:
if y % 400 == 0:
return True
return False
return True
return False
def count_days(y, m, d):
if leap_year(y):
month[2] = 29
else:
month[2] = 28
return sum(month[:m])+d
a = count_days(y1, m1, d1)
b = 0
for y in range(y1, y2):
if leap_year(y):
b += 366
else:
b += 365
b += count_days(y2, m2, d2)
c = b-a+week.index(weekday)
print(week[c % 7])
>> 날짜와 요일을 입력하라. 2020 10 13 Tue
>> 요일을 구할 날짜를 입력하라. 2035 10 13
Sat
- y1, m1, d1을 입력하여 요일을 설정한 후 y2, m2, d2의 요일을 구해야 한다.
- y1년 m1월 d1일부터 y2년 m2월 d2일까지 총며칠이 있는지 계산하여 요일을 구한다.
- A는 y1년 1월 1일부터 y1년 m1월 d1일까지의 일 수이다.
- B는 y1년 1월 1일부터 y2년 m2월 d2일까지의 일 수이다.
- C는 B에서 A를 뺀 값이므로 y1년 m1월 d1일의 다음 날부터 y2년 m2월 d2일까지의 일 수이다.
- 일 수를 구하기 위해 윤년인지 확인한다. 윤년은 4의 배수이면서 100의 배수가 아니어야 한다.
- 또는 100의 배수이지만 400의 배수이면 윤년이다.
- 만약 윤년이면 2월은 29일까지이므로 month 리스트 (월의 일 수)의 2번째 index 값을 29로 바꾼다.
- 윤년이 아니면 2월은 28일이다.
- A를 구하기 위해 month의 리스트에서 0~m1-1 index의 합을 구한 후 d를 더한다. (count_days 함수)
- B를 구하기 위해 y1부터 y2-1까지의 반복문을 통해 윤년인지 확인한다.
- 윤년이면 366일을 더하고 아니면 365일을 더한다. (1년은 365일 또는 366일)
- 남은 일 수인 y2년 1월 1일부터 y2년 m2월 d2일까지 count_days 함수로 계산한다.
- A, B로 인해 C를 구하고 weekday의 index를 추가로 더한다.
- C를 7로 나눈 나머지가 month의 index가 되고, 그 값은 y2년 m2월 d2일의 요일이 된다.
Q) 위 문제처럼 요일을 구하는데 이전 날짜의 요일까지 구하여라.
예를 들어, 2023년 10월 19일이 목요일이라면 2021년 10월 19일은 무슨 요일인가?
y1, m1, d1, weekday = input('날짜와 요일을 입력하라. ').split()
y1, m1, d1 = int(y1), int(m1), int(d1)
y2, m2, d2 = input('요일을 구할 날짜를 입력하라. ').split()
y2, m2, d2 = int(y2), int(m2), int(d2)
week = ['Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat', 'Sun']
month = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
def leap_year(y):
if y % 4 == 0:
if y % 100 == 0:
if y % 400 == 0:
return True
return False
return True
return False
def count_days(y, m, d):
if leap_year(y):
month[2] = 29
else:
month[2] = 28
return sum(month[:m])+d
def solve_weekday(y_input, m_input, d_input, y_solve, m_solve, d_solve):
a = count_days(y_input, m_input, d_input)
b = 0
for y in range(y_input, y_solve):
if leap_year(y):
b += 366
else:
b += 365
b += count_days(y_solve, m_solve, d_solve)
return b-a
if (y1, m1, d1) > (y2, m2, d2):
c = solve_weekday(y2, m2, d2, y1, m1, d1)
print(week[(c % 7)*(-1)+week.index(weekday)])
else:
c = solve_weekday(y1, m1, d1, y2, m2, d2)+week.index(weekday)
print(week[c % 7])
>> 날짜와 요일을 입력하라. 2023 10 19 Thr
>> 요일을 구할 날짜를 입력하라. 2003 10 19
Sun
- C를 구하는 과정을 함수로 나타내었다. 구하는 과정은 '요일 구하기' 문제를 참고하여라. (solve_weekday)
- 요일이 설정된 날짜 y1, m1, d1과 구해야 할 날짜 y2, m2, d2를 튜플로 묶어 크기 비교를 한다.
- y2, m2, d2의 날짜가 y1, m1, d1보다 더 앞에 왔다면 c에서 7을 나눈 나머지에 -1을 곱하여 weekday의 index만큼 더한다.
- 그 값이 y2, m2, d2의 요일의 index가 된다.
- 예를 들어, c가 16이고 설정된 날짜의 요일이 목요일이다.
- 16일 전의 요일을 구하는 것이므로 2주 전의 이틀 전의 요일을 구한다.
- 16을 7로 나눈 나머지가 2이고 결국 목요일의 index가 3이면 이틀 전은 index가 1인 화요일이 된다.
Q) 요일 개수 구하기
- 2개의 날짜를 입력하고 첫 번째 입력하는 날짜에는 요일을 설정하여 입력한다.
- 개수를 구할 요일을 입력한다.
- 날짜 사이의 요일의 개수를 구하라.
- 예를 들어, 2023년 10월 20일이 금요일이라면 2023년 12월 25일까지 일요일의 개수는 10개이다.
y1, m1, d1, weekday = input('날짜와 요일을 입력하라. ').split()
y1, m1, d1 = int(y1), int(m1), int(d1)
y2, m2, d2 = input('날짜를 입력하라. ').split()
y2, m2, d2 = int(y2), int(m2), int(d2)
count_weekday = input('개수를 구할 요일을 입력하라 ')
week = ['Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat', 'Sun']
month = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
def leap_year(y):
if y % 4 == 0:
if y % 100 == 0:
if y % 400 == 0:
return True
return False
return True
return False
def count_days(y, m, d):
if leap_year(y):
month[2] = 29
else:
month[2] = 28
return sum(month[:m])+d
def solve_weekday(y_input, m_input, d_input, y_solve, m_solve, d_solve):
a = count_days(y_input, m_input, d_input)
b = 0
for y in range(y_input, y_solve):
if leap_year(y):
b += 366
else:
b += 365
b += count_days(y_solve, m_solve, d_solve)
return b-a
def counting_day(weekday, c):
d = week.index(count_weekday) - week.index(weekday)
if d < 0:
c -= 7+d
else:
c -= d
print(c//7+1)
if (y1, m1, d1) > (y2, m2, d2):
c = solve_weekday(y2, m2, d2, y1, m1, d1)
weekday2 = week[(c % 7)*(-1)+week.index(weekday)]
counting_day(weekday2, c)
else:
c = solve_weekday(y1, m1, d1, y2, m2, d2)
counting_day(weekday, c)
>> 날짜와 요일을 입력하라. 2023 10 20 Fri
>> 날짜를 입력하라. 2023 12 25
>> 개수를 구할 요일을 입력하라 Sun
10
- 입력한 두 날짜 사이의 총일수를 먼저 구한다. (solve_weekday 함수로 c를 구한다.)
- 예를 들어 2023년 10월 20일부터 2023년 12월 25일까지 66일이다.
- 2023년 10월 20일을 금요일로 설정했고 개수를 구할 요일이 일요일이라면 금요일에서 2일 후인 10월 22일이 일요일이다.
- 따라서 2023년 10월 22일부터 2023년 12월 25일까지 64일이고, 이는 9주 하고 1일이다. (64를 7로 나눠 몫이 9, 나머지가 1이다.)
- 예를 들어 1주일이면 금요일에서 시작해서 금요일에서 끝나므로 금요일이 2개이다.
- 즉 1주일에 2개가 되므로 n주일에 n+1개가 된다.
- counting_day 함수에서 d는 설정한 요일에서 개수를 구할 요일까지 이동할 수를 구하는 것이다.
- week의 index를 구하고 d를 구해 d만큼 c의 개수를 뺀다.
- 만약 후에 입력한 날짜가 전에 입력한 날짜보다 빠르면 후에 입력한 날짜의 요일을 먼저 구한다. (weekday2)
- counting_day에서 weekday2를 이용해 d를 구한다.
'파이썬(Python)' 카테고리의 다른 글
[Python] 특정 구간의 개수 구하기 - 겹치는 지점, 겹치는 구간 (0) | 2023.10.29 |
---|---|
[Python] 진수 변환 - 2진법 표현, 10진법 표현, 진수에서 진수 변환, 아스키 코드 (0) | 2023.10.23 |
[Python] - 객체 정렬, 등수 표현, 객체 정렬 문제 풀이 (정보 정렬, 좌표 거리, 정렬된 위치 탐색) (0) | 2023.09.22 |
[Python] 우선 순위 객체 정렬, 다양한 조건의 객체 정렬 - class, tuple, lambda, cmp_to_key (0) | 2023.09.14 |
[Python] 객체 정렬 - 클래스, 튜플 객체 정렬. lambda. 오름차순. 내림차순. 문자열 사전순 (0) | 2023.02.11 |