Calcular o número do dia do ano

13

Parece que ainda não temos este, então vamos lá:

O desafio

Escreva um programa ou função que tome uma data como entrada e emita o número do dia do ano. Você não pode usar nenhum built-in para isso!

Regras

  • Como de costume, você pode escrever um programa completo ou uma função.
  • O formato da entrada é com você, mas deve conter um ano, um mês e um dia. Deixe claro qual a sua solução usa!
  • Não são permitidos embutidos relacionados à data! Você tem que fazer o trabalho sozinho. Construções que não estão relacionadas às operações da data estão corretas.
  • A base para o cálculo é o calendário gregoriano.
  • Você tem que levar em consideração os anos bissextos.
  • Você só precisa lidar com anos no intervalo [1, 9999]
  • As brechas padrão são proibidas.
  • Menor contagem de bytes ganha!

Casos de teste

O formato de entrada aqui é AAAA / MM / DD

2016/07/05 -> 187
2000/03/28 -> 88
0666/06/06 -> 157
6789/10/11 -> 284
0004/04/04 -> 95
1337/07/13 -> 194

Feliz codificação!

Denker
fonte
Podemos usar built-in por dias desde uma determinada data? E se um ano é bissexto?
precisa saber é o seguinte
@ Thomas Não são permitidos buildins relacionados à data. Vou esclarecer que, no desafio, obrigado pelo comentário! :)
Denker
@DenkerAffe Por que você proibiu todos os embutidos?
aloisdg movendo-se para codidact.com 17/07

Respostas:

2

Pitão, 31 bytes

+s<X1+L28jC"3Ȕ"4!%|F_jQ*TT4tEE

Obrigado a @Dennis e @Jakube pela parte do ano bissexto . A entrada é AAAA, MM, DD em linhas separadas.

+                          add [day] to
  s <                      sum of first [month]-1 values in the list
      X                    add 1 to
        1                  the second element (January)...
        +L                 \
           28              |
           j               }   lengths of all the months
             C "3Ȕ"       | 
             4             /
        ! %                ... if the year is a leap year; that is, 4 divides...
            |F _ j         fold logical OR over reversed
                   Q       the year
                   *TT     converted to base 100
            4
      t E                 [month]-1
  E                       [day]

Conjunto de teste .

lirtosiast
fonte
8

JavaScript ES6, 81 69 bytes

(y,m,d)=>d+parseInt("03479cehkmpr"[--m],36)+m*28-(y%(y%25?4:16)&&m>1)

Supondo que os meses sejam baseados em 1, caso contrário, eu poderia salvar 2 bytes.

Editar: salvou 12 bytes usando a dica de @ user81655.

Neil
fonte
3

C, 96 102 89 61 bytes

g(y,m,d){printf("%d",m/2*31+--m/2*30-(y%(y%25?4:16)?2:1)+d);}
o79y
fonte
2

Python 3, 152 148 150 bytes

m,d,y=map(int,input().split());n=[0,31,(59,60)[(y%4==0 and y%100!=0)or y%400==0]]
for i in range(m):n+=[n[-1]+(31,30)[i in[1,3,6,8]]]
print(n[-4]+d)

Tira datas no formato "MD YYYY".

Steve Eckert
fonte
1
Você deve usar o Python 2, a menos que precise de recursos específicos do Python 3. Porque, então, você não precisa de colchetes nas suas impressões, o que permite que você salve um byte gravando sua impressão como:print n[m-1]+d
Denker
Na primeira linha, você poderia escrever y% 4 == 0 e y% 100! = 0, eu acho #
Mega Man
2

Python 2, 100 82 bytes

Uma porta Python da resposta de @ Neil :

lambda d,m,y:d+int("03479cehkmpr"[m-1],36)+(m-1)*28-(y%(4if y%25 else 16)and m>2)

Como na resposta anterior, adicionar 17 bytes (99 bytes no total) produzirá um programa completo:

print(lambda d,m,y:d+int("03479cehkmpr"[m-1],36)+(m-1)*28-(y%(4if y%25 else 16)and m>2))(*input())

Resposta anterior:

Como um lambda anônimo:

lambda d,m,y:d+sum(31-(n in(3,5,8,10))for n in range(m-1))-(3if y%4 or(y%400!=0and y%100==0)else 2)

Pode ser convertido em um lambda nomeado por uma penalidade de 2 bytes. Como alternativa, um programa completo (com entrada no formato D,M,Y) pode ser alcançado por 117 bytes:

print(lambda d,m,y:d+sum(31-(n in(3,5,8,10))for n in range(m-1))-(3if y%4 or(y%400!=0and y%100==0)else 2))(*input())
Mac
fonte
Alguns pequenos golfinhos recebem 76 bytes #
Reinstate Monica
0

Python 3, 125 bytes

print((lambda d,m,y:sum([3,not(y%400 and not y%100 or y%4),3,2,3,2,3,3,2,3,2,3][:m-1])+m*28-28+d)(*map(int,input().split())))

Uma outra abordagem para esse problema. O código aproveita as prioridades de execução da álgebra booleana do Python e, como noté a última operação, a conversão para booleano é automática. Quando a soma é feita, o booleano é tratado como 1 ou 0. O formato de entrada é a sequência "AA MM DDDD". Sistema de entrada inspirado no sistema semelhante de @ SteveEckert .

Outra forma como uma função, 91 bytes

def f(d,m,y):return sum([3,not(y%400 and not y%100 or y%4),3,2,3,2,3,3,2,3,2,3][:m])+m*28+d

Nesse caso, a entrada é de três números inteiros, sendo o mês entre 0 e 11. Isso funcionaria no Python 2 também.

SydB
fonte
0

Excel, 106 bytes

=AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100))))+30*B1-31+CHOOSE(B1,1,2,0,1,1,2,2,3,4,4,5,5,6)+C1

Recebe entrada em três células A1= Ano, B1= Mês, C1= Dia.


AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100))))

1 se LeapYear, mais 0

30*B1-31+CHOOSE(B1,1,2,0,1,1,2,2,3,4,4,5,5,6)+C1

Múltiplo de 30, ESCOLHA por dias adicionais, mais dias no mês


Evolução:

=IF(AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)))),1,0)+CHOOSE(B1,0,31,59,90,120,151,181,212,243,273,304,334,365)+C1
=IF(AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)))),1,0)+CHOOSE(B1-1,31,59,90,120,151,181,212,243,273,304,334,365)+C1
=IF(AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)))),1,0)+30*(B1-1)+CHOOSE(B1,0,1,-1,0,0,1,1,2,3,3,4,4,5)+C1
=IF(AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)))),1,0)+30*B1-30+CHOOSE(B1,0,1,-1,0,0,1,1,2,3,3,4,4,5)+C1
=IF(AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)))),1,0)+30*B1-31+CHOOSE(B1,1,2,0,1,1,2,2,3,4,4,5,5,6)+C1
=AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100))))+30*B1-31+CHOOSE(B1,1,2,0,1,1,2,2,3,4,4,5,5,6)+C1
Wernisch
fonte