Oblicz numer dnia w roku

13

Wygląda na to, że jeszcze go nie mamy, więc zaczynamy:

Wyzwanie

Napisz program lub funkcję, która pobiera datę jako dane wejściowe i wyświetla numer dnia w roku. Nie możesz do tego używać żadnych wbudowanych funkcji!

Zasady

  • Jak zwykle możesz napisać pełny program lub funkcję.
  • Format danych wejściowych zależy od Ciebie, ale musi zawierać rok, miesiąc i dzień. Wyjaśnij, którego używa Twoje rozwiązanie!
  • Niedozwolone są wbudowane funkcje związane z datą! Musisz wykonać pracę sam. Wbudowane, które nie są związane z operacjami daty są w porządku.
  • Podstawą obliczeń jest kalendarz gregoriański.
  • Musisz wziąć pod uwagę lata przestępne.
  • Wystarczy obsłużyć lata w przedziale [1, 9999]
  • Standardowe luki są zabronione.
  • Najniższa liczba bajtów wygrywa!

Przypadki testowe

Format wejściowy to RRRR / 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

Happy Coding!

Denker
źródło
Czy możemy używać wbudowanych dni od określonej daty? A co z tym, czy rok jest rokiem przestępnym?
lirtosiast
@Thomas Niedozwolone są wbudowane funkcje związane z datą. Wyjaśnię to w wyzwaniu, dziękuję za komentarz! :)
Denker
@DenkerAffe Dlaczego zabroniłeś wszystkich wbudowanych?
aloisdg przechodzi na codidact.com

Odpowiedzi:

2

Pyth, 31 bajtów

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

Dzięki @Dennis i @Jakube za część roku przestępnego . Dane wejściowe to RRRR, MM, DD w osobnych wierszach.

+                          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]

Zestaw testowy .

lirtosiast
źródło
8

JavaScript ES6, 81 69 bajtów

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

Zakładając, że miesiące są oparte na 1, w przeciwnym razie mógłbym zaoszczędzić 2 bajty.

Edycja: Zapisano 12 bajtów, używając końcówki @ user81655.

Neil
źródło
3

C, 96 102 89 61 bajtów

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

Python 3, 152 148 150 bajtów

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)

Przyjmuje daty w formacie „MD RRRR”.

Steve Eckert
źródło
1
Powinieneś używać Pythona 2, chyba że potrzebujesz określonych funkcji z Pythona 3. Ponieważ wtedy nie potrzebujesz nawiasów na wydrukach, co pozwala zaoszczędzić jeden bajt poprzez zapisanie wydruku jakoprint n[m-1]+d
Denker
W pierwszym wierszu możesz napisać y% 4 == 0 i y% 100! = 0, myślę
Mega Man
2

Python 2, 100 82 bajtów

Port Pythona w odpowiedzi @ Neil :

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

Podobnie jak w poprzedniej odpowiedzi, dodanie 17 bajtów (łącznie 99 bajtów) da pełny program:

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

Poprzednia odpowiedź:

Jako anonimowa lambda:

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)

Można zamienić na nazwaną lambda za 2 bajty kary. Alternatywnie można uzyskać pełny program (przyjmujący dane wejściowe w formacie D,M,Y) dla 117 bajtów:

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())
Prochowiec
źródło
Kilka małych golfów ma 76 bajtów
kałamarnica
0

Python 3, 125 bajtów

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())))

Inne podejście do tego problemu. Kod korzysta z priorytetów wykonywania algebry logicznej Pythona, a ponieważ notjest to ostatnia operacja, konwersja na wartość logiczną jest automatyczna. Po zakończeniu sumowania wartość logiczna jest traktowana jako 1 lub 0. Format wejściowy to ciąg „RR MM DDDD”. System wprowadzania inspirowany podobnym systemem @ SteveEckert .

Kolejna postać jako funkcja, 91 bajtów

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

W tym przypadku wejściem są trzy liczby całkowite, miesiąc między 0-11. Działa to również w Pythonie 2.

SydB
źródło
0

Excel, 106 bajtów

=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

Pobiera dane w trzech komórkach A1= rok, B1= miesiąc, C1= dzień.


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

1 jeśli LeapYear, jeszcze 0

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

Wiele 30, WYBIERZ na dodatkowe dni plus dni w miesiącu


Ewolucja:

=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
źródło