Leap Year
Você recebe um ano year do calendário gregoriano. Retorne true se for um ano bissexto, ou seja, um ano que tem 29 de fevereiro, e false caso contrário.
Um ano é bissexto quando é divisível por 4, exceto os anos divisíveis por 100, que não são bissextos a menos que também sejam divisíveis por 400.
Função
- yearinteger
- o ano a verificar
- Retornaboolean
- verdadeiro quando o ano tem um dia 29 de fevereiro, falso caso contrário
Restrições
1 ≤ year ≤ 106
Exemplos
- Entrada
- year = 2024
- Saída
- true
- Explicação
2024é divisível por4e não é um ano centenário, portanto é um ano bissexto.
- Entrada
- year = 1900
- Saída
- false
- Explicação
1900é divisível por4, mas também é divisível por100e não por400, então a exceção dos anos seculares se aplica, e ele não é um ano bissexto.
- Entrada
- year = 2000
- Saída
- true
- Explicação
2000é divisível por100, o que o excluiria, mas também é divisível por400, o que o inclui novamente. É um ano bissexto.
+16 testes ocultos ao enviar
Dicas
Abra uma de cada vez. Cada uma revela um pouco mais.
Um resto de
0após a divisão por4é a primeira regra. Quais anos a violam?Anos de século quebram essa regra, e múltiplos de
400quebram, por sua vez, a regra dos séculos. Todo múltiplo de400também é múltiplo de100e de4, então a ordem das verificações determina a resposta.Verifique primeiro a divisibilidade por
400, depois por100e, em seguida, por4; deixe que a primeira regra que corresponder determine o resultado. Ou combine-as: divisível por 4 e não por 100, ou divisível por 400.
Solução
Cada regra precisa de apenas um resto, então o trabalho consiste em três verificações de divisibilidade. A armadilha está na ordem: as regras se contradizem em anos como 2000, que é um século e também um múltiplo de 400. Teste primeiro a regra mais específica ou escreva a regra como uma única expressão cujos parênteses mantenham as exceções em seus devidos lugares.
Verifique as regras da mais específica para a menos específica
Intuição
As três regras formam uma cadeia de exceções. Ser divisível por 4 torna o ano bissexto, ser divisível por 100 desfaz isso, e ser divisível por 400 desfaz o desfazimento. Um ano que corresponde a uma regra posterior sempre corresponde também às anteriores: todo múltiplo de 400 é múltiplo de 100, e todo múltiplo de 100 é múltiplo de 4.
Portanto, a regra mais específica que corresponder determina a resposta. Teste 400 primeiro, depois 100 e, por fim, 4, e retorne assim que uma delas corresponder. Para 2000, o primeiro teste já diz sim. Para 1900, o primeiro teste falha e o segundo diz não. Para 2024, os dois primeiros falham e o terceiro diz sim.
Se nenhuma das três corresponder, o ano não é divisível por 4, então é um ano comum.
Algoritmo
- Se
year % 400 == 0, retornetrue. - Se
year % 100 == 0, retornefalse. - Se
year % 4 == 0, retornetrue. - Caso contrário, retorne
false.
def isLeapYear(year):
if year % 400 == 0:
return True
if year % 100 == 0:
return False
if year % 4 == 0:
return True
return FalseUma expressão booleana
Intuição
Leia a regra como duas maneiras de ser um ano bissexto. Ou o ano é divisível por 4 e não é um ano secular, ou é divisível por 400. Essa frase se traduz palavra por palavra em (year % 4 == 0 and year % 100 != 0) or year % 400 == 0.
Confira nos três exemplos. 2024 satisfaz a primeira parte. 1900 não satisfaz a primeira parte porque é um ano secular, e não satisfaz a segunda porque 1900 % 400 é 300. 2000 não satisfaz a primeira parte pelo mesmo motivo que 1900, e satisfaz a segunda.
Você também pode agrupar de outra forma: divisível por 4 e, ou não é um ano secular, ou é múltiplo de 400. As duas formas concordam para todos os anos. A expressão faz, no máximo, as mesmas três verificações que a cadeia de ifs.
Algoritmo
- Calcule
year % 4 == 0 and year % 100 != 0: divisível por 4 e não é um ano secular. - Calcule
year % 400 == 0. - Retorne
truese qualquer uma das partes for verdadeira.
def isLeapYear(year):
# Every 4th year, except centuries, except every 400th year.
return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
Armadilhas e casos extremos
Todos os erros aqui vêm de tratar a regra como um único teste, em vez de uma cadeia de exceções.
- Verificar apenas
year % 4 == 0. Isso dá a resposta certa para todos os anos de1901a2099, e é por isso que o bug fica oculto, e a resposta errada para1900e2100. - Testar
100antes de400em uma cadeia if. O teste de século retornafalsepara2000antes mesmo de o teste de400ser executado. - Omitir a parte de divisibilidade por 4.
year % 100 != 0 or year % 400 == 0considera2023um ano bissexto, porque2023não é um século. - Usar
year / 4quando você queria o resto. A divisão informa quantas vezes4cabe; o resto informa se cabe exatamente.
Perguntas frequentes4
Qual é a regra para um ano bissexto?
Um ano gregoriano é bissexto quando é divisível por 4, a menos que seja divisível por 100. Um ano divisível por 400 é bissexto de qualquer forma. Portanto, 2024 e 2000 são anos bissextos, enquanto 1900 e 2100 não são.
Por que 1900 não é um ano bissexto, mas 2000 é?
Ambos são anos seculares, divisíveis por 100, o que normalmente exclui um ano. 2000 também é divisível por 400, e essa regra prevalece sobre a regra dos anos seculares. 1900 deixa um resto de 300 quando dividido por 400, então continua sendo um ano comum.
Por que existem as regras dos séculos?
Um ano solar dura cerca de 365.2422 dias. Adicionar um dia a cada 4 anos resulta em uma média de 365.25, cerca de 3 dias a mais a cada 400 anos. Pular o dia bissexto em 3 de cada 4 anos de século elimina esses 3 dias. A média passa a ser 365.2425 dias, perto o suficiente para manter o calendário alinhado com as estações por milhares de anos.
Qual é a complexidade de tempo para verificar se um ano é bissexto?
É O(1) em tempo e espaço. A verificação realiza no máximo três operações de resto e algumas comparações, independentemente do tamanho do ano.
Problemas parecidos
Problemas que usam as mesmas ideias. Resolver dois ou três é o que fixa um padrão.
Python
def isLeapYear(year):
# Escreva o código aquiCaso 1
Caso 2
Caso 3
Entrada
year = 2024
Esperado
true