Leap Year
그레고리력의 연도 year를 받습니다. 2월 29일이 있는 윤년이면 true를 반환하고, 그렇지 않으면 false를 반환하세요.
연도가 4로 나누어떨어지면 윤년입니다. 단, 100으로 나누어떨어지는 연도는 윤년이 아니며, 400으로도 나누어떨어지는 경우에만 윤년입니다.
함수
- yearinteger
- 확인할 연도
- 반환값boolean
- 해당 연도에 2월 29일이 있으면 true, 그렇지 않으면 false
제약 조건
1 ≤ year ≤ 106
예제
- 입력
- year = 2024
- 출력
- true
- 설명
2024는4로 나누어떨어지고 세기 연도가 아니므로 윤년입니다.
- 입력
- year = 1900
- 출력
- false
- 설명
1900은4로 나누어떨어지지만100으로도 나누어떨어지고400으로는 나누어떨어지지 않으므로, 세기 예외가 적용되어 윤년이 아닙니다.
- 입력
- year = 2000
- 출력
- true
- 설명
2000은100으로 나누어떨어지므로 윤년에서 제외될 수 있지만,400으로도 나누어떨어지므로 다시 윤년이 됩니다. 윤년입니다.
제출 시 숨은 테스트 +16개
힌트
하나씩 열어 보세요. 열 때마다 조금 더 알려 줍니다.
4로 나눈 나머지가0인 것이 첫 번째 규칙입니다. 이 규칙에 맞지 않는 연도는 무엇인가요?세기 연도는 이를 깨고,
400의 배수는 다시 세기 규칙을 깹니다.400의 모든 배수는100과4의 배수이기도 하므로, 검사를 수행하는 순서에 따라 답이 달라집니다.먼저
400으로 나누어떨어지는지 확인하고, 그다음100, 그다음4로 나누어떨어지는지 확인한 뒤, 가장 먼저 일치하는 규칙을 적용하세요. 또는 다음 조건을 결합하세요. 4로 나누어떨어지고 100으로는 나누어떨어지지 않거나, 400으로 나누어떨어지는 경우입니다.
풀이
각 규칙에는 나머지가 하나씩만 필요하므로, 세 번의 나눗셈 가능 여부 검사만 하면 됩니다. 함정은 순서에 있습니다. 이 규칙들은 2000처럼 세기의 해이면서 400의 배수인 해에 대해 서로 모순됩니다. 가장 구체적인 규칙을 먼저 검사하거나, 괄호로 예외를 제자리에 둔 하나의 식으로 규칙을 작성하세요.
규칙을 가장 구체적인 것부터 가장 포괄적인 것 순으로 확인하세요
핵심 아이디어
세 가지 규칙은 예외의 사슬을 이룹니다. 4로 나누어떨어지면 윤년이 되고, 100으로 나누어떨어지면 이를 뒤집으며, 400으로 나누어떨어지면 그 뒤집기를 다시 뒤집습니다. 나중 규칙에 해당하는 연도는 항상 앞선 규칙에도 해당합니다. 400의 배수는 모두 100의 배수이고, 100의 배수는 모두 4의 배수이기 때문입니다.
따라서 해당하는 규칙 중 가장 구체적인 규칙이 답을 결정합니다. 먼저 400을 검사하고, 그다음 100, 마지막으로 4를 검사한 뒤 하나라도 해당하면 바로 결과를 반환합니다. 2000은 첫 번째 검사에서 바로 그렇다고 판정됩니다. 1900은 첫 번째 검사에 실패하고 두 번째 검사에서 아니라고 판정됩니다. 2024는 앞의 두 검사에 실패하고 세 번째 검사에서 그렇다고 판정됩니다.
세 가지 규칙 중 어느 것에도 해당하지 않으면 그 연도는 4로 전혀 나누어떨어지지 않으므로 평년입니다.
알고리즘
year % 400 == 0이면true를 반환합니다.year % 100 == 0이면false를 반환합니다.year % 4 == 0이면true를 반환합니다.- 그렇지 않으면
false를 반환합니다.
def isLeapYear(year):
if year % 400 == 0:
return True
if year % 100 == 0:
return False
if year % 4 == 0:
return True
return False하나의 불리언 표현식
핵심 아이디어
이 규칙을 윤년이 되는 두 가지 경우로 읽어 보세요. 연도가 4로 나누어떨어지면서 세기가 아니거나, 400으로 나누어떨어지는 경우입니다. 이 문장을 그대로 옮기면 (year % 4 == 0 and year % 100 != 0) or year % 400 == 0입니다.
세 가지 예에 적용해 보세요. 2024는 첫 번째 조건을 만족합니다. 1900은 세기이므로 첫 번째 조건을 만족하지 않고, 1900 % 400이 300이므로 두 번째 조건도 만족하지 않습니다. 2000은 1900과 같은 이유로 첫 번째 조건을 만족하지 않지만, 두 번째 조건은 만족합니다.
다른 방식으로 묶을 수도 있습니다. 4로 나누어떨어지면서 세기가 아니거나 400의 배수인 경우입니다. 두 형식은 모든 연도에 대해 같은 결과를 냅니다. 이 표현식이 수행하는 검사는 if 체인의 검사와 같거나 더 적으며, 최대 세 번입니다.
알고리즘
year % 4 == 0 and year % 100 != 0을 계산합니다. 4로 나누어떨어지고 세기가 아닙니다.year % 400 == 0을 계산합니다.- 둘 중 하나라도 참이면
true를 반환합니다.
def isLeapYear(year):
# Every 4th year, except centuries, except every 400th year.
return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
함정과 경계 사례
여기서 모든 실수는 규칙을 예외의 연쇄가 아니라 하나의 검사로 취급하는 데서 비롯됩니다.
year % 4 == 0만 확인하는 경우입니다.1901부터2099까지 모든 연도에 대해 올바른 답을 내므로 버그가 숨어 있다가,1900과2100에 대해서는 잘못된 답을 내게 됩니다.- if 체인에서
400보다 먼저100을 검사하는 경우입니다. 세기 연도 검사가400검사가 실행되기도 전에2000에 대해false를 반환합니다. - 4로 나누어떨어지는 조건을 빠뜨리는 경우입니다.
year % 100 != 0 or year % 400 == 0은2023이 세기 연도가 아니므로 윤년이라고 판단합니다. - 나머지를 구하려던 곳에
year / 4를 사용하는 경우입니다. 나눗셈은4가 몇 번 들어가는지 알려 주고, 나머지는 정확히 나누어떨어지는지 알려 줍니다.
자주 묻는 질문4
윤년의 규칙은 무엇인가요?
그레고리력에서 연도가 4로 나누어떨어지면 윤년입니다. 단, 100으로 나누어떨어지는 경우는 제외합니다. 400으로 나누어떨어지는 연도는 예외 없이 윤년입니다. 따라서 2024년과 2000년은 윤년이지만, 1900년과 2100년은 윤년이 아닙니다.
1900년은 왜 윤년이 아니지만 2000년은 윤년인가요?
둘 다 100으로 나누어떨어지는 세기 연도로, 일반적으로 윤년에서 제외됩니다. 2000은 400으로도 나누어떨어지므로 세기 연도 규칙보다 우선하는 규칙이 적용됩니다. 1900은 400으로 나누었을 때 나머지가 300이므로 평년으로 유지됩니다.
세기 규칙은 왜 존재하나요?
태양년은 약 365.2422일입니다. 4년마다 하루를 더하면 평균이 365.25일이 되는데, 이는 400년마다 약 3일이 너무 많습니다. 100년 단위 연도 4개 중 3개에서 윤일을 건너뛰면 이 3일이 빠집니다. 평균은 365.2425일이 되어, 수천 년 동안 달력이 계절과 맞도록 하기에 충분히 정확합니다.
윤년인지 확인하는 시간 복잡도는 얼마인가요?
시간과 공간 모두 O(1)입니다. 검사에는 나머지 연산이 최대 세 번, 비교 연산이 몇 번만 필요하며, 연도의 크기와는 관계없습니다.
비슷한 문제
같은 아이디어를 쓰는 문제입니다. 두세 개를 풀면 패턴이 몸에 익습니다.
Python
def isLeapYear(year):
# 여기에 코드를 작성하세요케이스 1
케이스 2
케이스 3
입력
year = 2024
기대값
true