Data zwielokrotnienia wyzwania


19

(Zainspirowany przez Riddlera z zeszłego tygodnia na FiveThirtyEight.com. Wpis w piaskownicy .)

Biorąc pod uwagę rok między 2001 a 2099, oblicz i zwróć liczbę dni w tym roku kalendarzowym, gdzie mm * dd = yy(gdzie yyjest 2-cyfrowa rok).

Na przykład 2018 ma 5:

  • 18 stycznia (1 * 18 = 18)
  • 9 lutego (2 * 9 = 18)
  • 6 marca (3 * 6 = 18)
  • 3 czerwca (6 * 3 = 18)
  • 2 września (9 * 2 = 18)

Dane wejściowe mogą być dwu- lub czterocyfrowe rokiem numerycznym.

Wyjście powinno być liczbą całkowitą. Opcjonalne końcowe miejsce lub zwrot jest w porządku.

Pełna lista wejść / wyjść:

Input = Output
 2001 = 1     2021 = 3     2041 = 0     2061 = 0     2081 = 2
 2002 = 2     2022 = 3     2042 = 4     2062 = 0     2082 = 0
 2003 = 2     2023 = 1     2043 = 0     2063 = 3     2083 = 0
 2004 = 3     2024 = 7     2044 = 3     2064 = 2     2084 = 5
 2005 = 2     2025 = 2     2045 = 3     2065 = 1     2085 = 1
 2006 = 4     2026 = 2     2046 = 1     2066 = 3     2086 = 0
 2007 = 2     2027 = 3     2047 = 0     2067 = 0     2087 = 1
 2008 = 4     2028 = 4     2048 = 6     2068 = 1     2088 = 3
 2009 = 3     2029 = 1     2049 = 1     2069 = 1     2089 = 0
 2010 = 4     2030 = 6     2050 = 3     2070 = 3     2090 = 5
 2011 = 2     2031 = 1     2051 = 1     2071 = 0     2091 = 1
 2012 = 6     2032 = 3     2052 = 2     2072 = 6     2092 = 1
 2013 = 1     2033 = 2     2053 = 0     2073 = 0     2093 = 1
 2014 = 3     2034 = 1     2054 = 4     2074 = 0     2094 = 0
 2015 = 3     2035 = 2     2055 = 2     2075 = 2     2095 = 1
 2016 = 4     2036 = 6     2056 = 4     2076 = 1     2096 = 4
 2017 = 1     2037 = 0     2057 = 1     2077 = 2     2097 = 0
 2018 = 5     2038 = 1     2058 = 0     2078 = 2     2098 = 1
 2019 = 1     2039 = 1     2059 = 0     2079 = 0     2099 = 2
 2020 = 5     2040 = 5     2060 = 6     2080 = 4

To jest wyzwanie polegające na , wygrywa najniższa liczba bajtów w każdym języku.

Wstępne obliczanie i po prostu wyszukiwanie odpowiedzi jest zwykle wykluczone zgodnie z naszymi zasadami dotyczącymi luk , ale wyraźnie zezwalam na to wyzwanie. Pozwala na kilka interesujących alternatywnych strategii, chociaż prawdopodobnie nie będzie ona najkrótsza na liście 98 99 elementów.


Jeśli w twoim języku będzie to łatwiejsze, odpowiedź będzie taka sama bez względu na wiek; 1924 i 2124 mają taką samą liczbę dni jak 2024.
— BradC

jeśli wynik mm * dd jest większy niż 100, jest on automatycznie filtrowany?
— DanielIndie

@DanielIndie Prawidłowo, nie należy liczyć dat „zawinięcia”. Innymi słowy, 12 grudnia 2044 r.
— Się

Ponieważ potrzebujemy tylko ograniczonej liczby danych wejściowych, edytowałem je wszystkie. Zapraszam do przywracania lub formatowania.
— Kudłaty

1
@gwaugh Wystarczy, że zdecydujesz, które z nich przyjąć jako prawidłowe dane wejściowe (nie musisz więc wydawać dodatkowych znaków na konwersję między nimi).
— BradC

Odpowiedzi:


14

Excel, 48 bajtów

Brawo! Wreszcie coś, w czym Excel jest naprawdę dobry.

=COUNT(VALUE(ROW(1:12)&"/"&A1/ROW(1:12)&"/"&A1))

Pobiera dane z A1 w postaci liczb całkowitych 1-99 reprezentujących rok i wypisuje je tam, gdzie wprowadzasz tę formułę. Jest to formuła tablicowa, więc użyj Ctrl-Shift-Enter zamiast Enter, aby ją wprowadzić.

Wykorzystuje to fakt, że COUNTignoruje błędy, więc wszelkie błędy spowodowane przez miesiąc niepodzielący roku (prowadzące Excel do analizowania czegoś podobnego 2/12.5/25lub przez niepoprawną datę 2/29/58, są po prostu dyskretnie ignorowane.


1
Bardzo dobrze. Prawdopodobnie warto wspomnieć, że wymaga 2-cyfrowego roku A1. Wprowadzenie 4-cyfrowego roku po prostu powraca 0.
— BradC

Prawdziwe! Zmienię to w opisie.
— Sophia Lechner,

Powinienem również wspomnieć, że jest to specyficzne dla ustawień regionalnych; zależy to od ustawień regionalnych korzystających z uporządkowania w mm / dd / rr. W przypadku ustawień regionalnych z uporządkowaniem dd / mm / rr odpowiedź będzie oczywiście taka sama jak w bajtach.
— Sophia Lechner,

1
Super sprytny; Podoba mi się to, że testujesz tylko 12 kandydatów na randki (jednego na miesiąc), zamiast przeprowadzać je każdego dnia w roku.
— BradC

Naprawić rok na jeden skokowy bajt bez skoku?
— l4m2

6

Python 2 , 44 bajty

[k/32%13*(k%32)for k in range(96,509)].count

Wypróbuj online!

Anonimowa funkcja podana jako obiekt metody. Wytwarza wszystkie produkty (month, day)par (m, d)jak zakodowany k=32*m+dw 0≤m≤12, 0≤d≤31, owijając się. Eliminuje 29-31 lutego, wykluczając je z zasięgu.


5

Java (JDK 10) , 65 bajtów

y->{int m=13,c=0;for(;m-->1;)if(y%m<1&y/m<29+m%2*3)c++;return c;}

Wypróbuj online!

Kredyty


Nie pasuje rok przestępny 29*n, więc nie trzeba sprawdzać
— 14m2

Dzięki za wkład. Mogłem usunąć łącznie 27 bajtów z kilkoma innymi zmianami.
— Olivier Grégoire,

1
Zmiana (m==2?29:32)na 29+m%2*3nadal wydaje się dawać wszystkie OKwyniki. Kredyt dla @AsoneTuhid „s Ruby odpowiedź .
— Kevin Cruijssen

4

PowerShell , 94 bajty

param($a)for($x=Date 1/1/$a;$x-le(Date 12/9/$a);$x=$x.AddDays(1)){$z+=$x.Month*$x.Day-eq$a};$z

Wypróbuj online!

Pobiera dane wejściowe jako dwucyfrowy rok, a następnie konstruuje forpętlę od 1/1/yeardo 12/9/year(ponieważ 12/10 i kolejne nigdy się nie liczą, a to oszczędza bajt). Każdą iterację zwiększamy o $zile .Monthrazy .Dayjest równa naszemu rokowi wejściowemu. Poza pętlą $zpozostaje w potoku, a dane wyjściowe są niejawne.

Edytuj - to zależy od kultury. Powyższy kod działa dla en-us. Format daty może wymagać zmiany w przypadku innych kultur.


2
"kultura"? Miałeś na myśli „locale”? ...
— user202729

1
@ user202729 Potocznie tak, ale dokumentacja PowerShell nazywa to „kulturą”.
— AdmBorkBork

„Kultura” to słowo, którego MS zwykle używa do mówienia o lokalizacji, np. System.Globalization.CultureInfo w .NET.
— Sundar - Przywróć Monikę




3

JavaScript (ES6), 91 bajtów

Byłem ciekawy, jak kodowanie twarde porównałoby się do obliczeń iteracyjnych. Jest zdecydowanie dłuższy (patrz odpowiedź @ Shaggy ), ale nie strasznie dłużej.

Edycja : Jest to jednak znacznie dłużej niż bardziej bezpośrednia formuła (patrz odpowiedź @ l4m2 ).

Pobiera dane wejściowe jako liczbę całkowitą w [1..99] .

n=>(k=parseInt('8ijkskercdtbnqcejh6954r1eb2kc06oa3936gh2k0d83d984h'[n>>1],36),n&1?k>>3:k&7)

Wypróbuj online!

W jaki sposób?

Lata nieparzyste mają znacznie mniejsze szanse, że mm * dd = rr niż lata. Konkretniej, nieparzyste lata mają od 0 do 3 meczów, podczas gdy parzyste lata mają od 0 do 7 meczów. To pozwala nam kodować każdą parę lat za pomocą zaledwie 5 bitów, które można wygodnie przedstawić jako pojedynczy znak w bazie 36.




3

Narzędzia Bash + GNU , 57

  • 1 bajt zapisany dzięki @SophiaLechner
seq -f1/1/$1+%gday 0 365|date -f- +%m*%d-%y|bc|grep -c ^0

Zauważ, że seqpolecenie zawsze tworzy listę 366 dat - dla lat bez przestępstwa zostanie włączony 1 stycznia następnego roku. Jednak w zakresie dat 2001..2099, MM * DD nigdy nie będzie YY dla 1 stycznia następnego roku dla żadnego z tych lat, więc ten dodatkowy dzień nie wpłynie na wynik.

Wypróbuj online!


Bardzo fajnie - nawet nie wiedziałem date, że podczas matematyki zrobię taką randkę. seqnie potrzebuje spacji po -f, więc możesz zapisać tam bajt.
— Sophia Lechner,

3

T-SQL, 123 121 bajtów

Zgodnie z naszymi regułami IO dane wejściowe są pobierane za pomocą istniejącej tabeli t z polem całkowitym y , które zawiera 2-cyfrowy rok.

WITH c AS(SELECT 1m UNION ALL SELECT m+1FROM c WHERE m<12)
SELECT SUM(ISDATE(CONCAT(m,'/',y/m,'/',y)))FROM c,t WHERE y%m=0

Podział linii służy wyłącznie do odczytu. Zainspirowany głównie rozwiązaniem Excela Sophii .

  • Górny wiersz generuje tablicę liczb 12-elementowych c, która jest połączona z tabelą wprowadzania t .
  • Jeśli to minie, łączę ze sobą kandydata na datę CONCAT(), który dokonuje niejawnej varcharkonwersji typu danych. W przeciwnym razie musiałbym zrobić kilka instrukcji CASTlub CONVERToświadczeń.
  • Znaleziono idealną funkcję oceny ISDATE(), która zwraca 1 dla prawidłowych dat i 0 dla nieprawidłowych dat.
  • Zawiń to w SUMIE i gotowe.
  • EDYCJA : Przeniesiono sprawdzanie podziału liczb całkowitych ( y%m=0) do WHEREklauzuli, aby zaoszczędzić 2 bajty, dzięki @RazvanSocol.

Niestety, nie jest on dużo krótszy niż wersja tabeli odnośników (używając ciągu z wersji osdavison ):

Wyszukiwanie T-SQL, 129 bajtów

SELECT SUBSTRING('122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012',y,1)FROM t

EDYTOWAĆ : Pozostawiając mój oryginał powyżej, ale możemy zaoszczędzić kilka bajtów, używając kilku nowych funkcji:

  • STRING_SPLIT jest dostępny w MS SQL 2016 i nowszych wersjach.
  • CONCAT_WS jest dostępny w MS SQL 2017 i nowszych wersjach.
  • Jak wyżej, zastąpiony IIFprzezWHERE

MS-SQL 2017, 121 118 bajtów

SELECT SUM(ISDATE(CONCAT_WS('/',value,y/value,y)))
FROM t,STRING_SPLIT('1-2-3-4-5-6-7-8-9-10-11-12','-')
WHERE y%value=0

MS-SQL 2017, dodatkowa oszustwa edycja: 109 bajtów

SELECT SUM(ISDATE(CONCAT_WS('/',number,y/number,y)))
FROM t,spt_values WHERE number>0AND y%number=0AND'P'=TYPE

Wymaga bycia w masterbazie danych, która zawiera tabelę systemową, spt_valuesktóra (po przefiltrowaniu TYPE='P') daje zliczanie liczb od 0 do 2048.


Podobnie do innych odpowiedzi, kolejność, w której składam date ( m/d/y), zależy od ustawień lokalizacji instancji SQL. Inne lokalizacje mogą wymagać innej kolejności lub innego separatora, ale nie sądzę, żeby wpłynęło to na długość kodu.
— BradC

Wydaje mi się, że zdałeś sobie sprawę, że konwersja „2/29/64” na datę daje 1964-02-29 (nie 2064-02-29), ale biorąc pod uwagę, że lata 2000 i 2100 są wykluczone, to dobry sposób na skrócenie czasu kod.
— Razvan Socol

Użycie SPLIT_STRINGzamiast CTE sprowadza go do 120 bajtów. Użycie CONCAT_WSzamiast CONCATzapisuje inny znak, doprowadzając go do 119 bajtów.
— Razvan Socol

@RazvanSocol Tak, nie jestem pewien, gdzie jest przerwa między 2-cyfrowymi datami odwzorowanymi na 19xx a 20xx, ale obie dają tę samą odpowiedź. Spróbuję pozostałych dwóch sugestii, dzięki!
— BradC

1
Wymień IIFsię WHERE.
— Razvan Socol

3

Julia 0,6 , 49 44 42 bajtów

y->sum(y/i∈1:28+3(i%2⊻i÷8)for i=1:12)

Wypróbuj online!

-5 bajtów inspirowanych Rubinową odpowiedzią Asone Tuhid.
-2 bajty zastępujące licznik sumą

Wyjaśnienie:

Dla każdego miesiąca iod 1 do 12 oblicz y/ii sprawdź, czy jest to jeden z dni tego miesiąca. Miesięcy z 31 dni to 1, 3, 5, 7, 8, 10, 12 - tak oni dziwne poniżej 8, a nawet i powyżej 8. Więc albo i%2albo i÷8(co jest 0 dla i <8 i 1 dla I> = 8 tutaj) powinno wynosić 1, ale nie oba - więc XOR je. Jeśli wynik xor jest prawdą, możemy sprawdzić terminy 1:28+3tj 1:31, w przeciwnym razie możemy sprawdzić tylko dat 1:28.

1:28wystarcza na resztę miesięcy (ta poprawka zainspirowana Rubinową odpowiedzią Asone Tuhid ), ponieważ:

  • w lutym jedyną możliwością byłoby 2*29 = 58, ale 2058nie jest to rok przestępny, więc możemy założyć, że luty zawsze ma 28 dni.

  • pozostałe miesiące z 30 dniami to miesiąc 4 i więcej - dla których i*29(i i*30) byłoby powyżej 100, co można zignorować.

Na koniec odliczamy, ile razy y/inależy do tej listy dni (używając sumtutaj boolean ), i zwracamy to.


3

JavaScript, 91 85 82 81 77 bajtów

Pobiera dane wejściowe jako 2-cyfrowy ciąg (lub 1 lub 2 cyfrową liczbę całkowitą).

Wykorzystuje fakt, że new Dateprzejdzie do następnego miesiąca i będzie to kontynuował, jeśli przekażesz mu wartość dzienną przekraczającą liczbę dni w miesiącu, w którym ją przekazałeś, więc przy pierwszej iteracji próbuje zbudować data, yyyy-01-345która staje się yyyy-12-11lub yyyy-12-10w latach przestępnych. Po tym terminie nie musimy sprawdzać dat, ponieważ 12*11+otrzymujemy trzycyfrową liczbę.

y=>(g=d=>d&&([,M,D]=new Date(y,0,d).toJSON().split(/\D/),D*M==y)+g(--d))(345)

3 bajty zapisane dzięki Arnauldowi .


Sprawdź to

f=
y=>(g=d=>d&&([,M,D]=new Date(y,0,d).toJSON().split(/\D/),D*M==y)+g(--d))(345)
o.innerText=[...Array(99)].map((_,x)=>(2001+x++)+` = `+f(x)).join`\n`
pre{column-count:5;width:480px;}
<pre id=o></pre>



2

Excel, 83 bajty

{=SUM(IF(MONTH(DATE(A1,1,0)+ROW(1:366))*DAY(DATE(A1,1,0)+ROW(1:366))=A1-2000,1,0))}

Dane wejściowe są w komórce A1w formacie yyyy. Jest to formuła tablicowa i jest wprowadzana za pomocą Ctrl+ Shift+, Enteraby uzyskać nawiasy klamrowe {}. Jest to dość proste i bez sprytu.

W formule tablicowej DATE(A1,1,0)+ROW(1:366)daje nam tablicę 366 wartości dat. W latach bez przestępstwa będzie to obejmowało 1 stycznia następnego roku, ale nie stanowi to problemu, ponieważ 1*1=1i byłoby liczone jako fałszywie dodatnie, jeśli następny rok będzie, 2001ale ponieważ wymagany zakres roczny jest 2001 - 2099, nigdy nie powstanie jako kwestia.

Jeśli zwędziłeś ten kawałek na prosty ~, formuła jest o wiele łatwiejsza do naśladowania:

{=SUM(IF(MONTH(~)*DAY(~)=A1-2000,1,0))}

Próbowałem użyć COUNTIF()zamiast, SUM(IF())ale Excel nawet nie pozwolił mi wprowadzić go jako formuły tablicowej, a tym bardziej dać mi wynik. I tak znaleźć Arkusze Google rozwiązanie używając CountIf()ale ten sam sposób poza tym, że okazał się być 91 bajtów, głównie dlatego, że używa ArrayFormula()zamiast po prostu { }.

=CountIf(ArrayFormula(Month(Date(A1,1,0)+Row(1:366))*Day(Date(A1,1,0)+Row(1:366))),A1-2000)

Nie widziałem konsensusu, ale generalnie nie uwzględniłem zewnętrznych nawiasów klamrowych w mojej liczbie bajtów dla programu Excel. Czują się bardziej jak sposób, w jaki Excel formatuje wyświetlanie, niż część formuły. Opinie?
— Sophia Lechner,

@SophiaLechner Uwzględniłem je zamiast decydować, jak uwzględnić dodatkowe naciśnięcia klawiszy wymagane do wprowadzenia go jako formuły tablicowej. Jest meta pytanie o to i tylko odpowiedź mówi, że CTRL + ALT + ENTER, komenda będzie liczyć jako 1 naciśnięciem klawisza. Jeśli użyjesz tego samego co vim ( na meta ), to naciśnięcie klawisza będzie liczone jako 1 bajt. Jednak zwykle nie liczę ENTER na końcu wprowadzania formuły jako 1 bajt w innych odpowiedziach.
— Inżynier Toast

2

Retina 0.8.2 , 55 bajtów

..
$*
(?<=^(1{1,12}))(?=(?(?<=^11$)\1{0,27}|\1{0,30})$)

Wypróbuj online! Trwa dwucyfrowy rok; dodaj 1 bajt, aby obsługiwać 4-cyfrowe lata. Objaśnienie: Pierwszy etap po prostu przekształca się w jednoosobowy. Drugi etap rozpoczyna się od dopasowania od 1 do 12 znaków przed pozycją dopasowania, reprezentującą miesiąc, a następnie próbuje się spodziewać całej liczby powtórzeń tego miesiąca. Jednak lookahead zawiera warunek, który wybiera od 27 do 30 kolejnych powtórzeń w zależności od miesiąca. Liczba pasujących pozycji jest wówczas pożądanym wynikiem.


2

R , 22 122 bajty

x=scan();substr("122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012",x,x)

Wypróbuj online!

Zdecydowałem się na podejście oparte na tabeli odnośników. Rok wprowadzenia musi składać się z 2 cyfr.


1
Również w TIO możesz nacisnąć przycisk „link”, a to automatycznie sformatuje odpowiedź za ciebie. Podziękowania dla Dennisa za konfigurację!
— Giuseppe,

Można usunąć początkowe if, ponieważ wejście może być albo 2-cyfrowy lub 4-cyfrowy do wyboru (dzięki czemu można wybrać, aby zaakceptować tylko 2-cyfrowe wejście). Ale wygląda na to, że kod uważa, że ​​każdy miesiąc zawiera 31 dni, więc np. 62 (dla 2062) zwraca 1, gdzie powinien zwrócić 0.
— Sundar - Przywróć Monikę

2
Źle zrozumiałem. Biorąc to pod uwagę, jestem prawie pewien, że tabela odnośników musiałaby zostać uwzględniona w liczbie bajtów.
— ngm

@ngm Nie byłem również pewien, czy należy uwzględnić tabelę odnośników, ale dodam ją do liczby bajtów, aby zachować bezpieczeństwo.
— Robert S.

Nadal nie jestem pewien, jakie są wszystkie zasady!
— ngm


2

J , 29 bajtów

1#.(,x*i."+29+3*2~:x=.i.13)=]

Wypróbuj online!

Jak to działa

1#.(,x*i."+29+3*2~:x=.i.13)=]    Input: year (2-digit, 1..99)
                   x=.i.13       array of 0..12; assign to x
                2~:              1 1 0 1 .. 1
              3*                 3 3 0 3 .. 3
           29+                   32 32 29 32 .. 32
       i."+                      for each item of above, generate a row 0 .. n
    ,x*                          each row times 0 .. 12 and flatten
                           =]    1 for each item == input, 0 otherwise
1#.                              sum

Próbowałem ciężko dostać 2 razy rozwiązanie Jelly :)

Dygresja

Jeśli ktoś naprawdę chce zakodować 99-cyfrowe dane, oto trochę informacji:

Podziel 99-cyfrową część na 2 cyfry. Następnie pierwsza cyfra to <4druga <8, co oznacza, że ​​pięć bitów może zakodować dwie liczby. Następnie całe dane mogą być kodowane w 250 bitach lub 32 bajtach.


2

Python 3 , 158 162 215 241 bajtów

Usunięto 4 Dzięki Stephen za grę w golfa w warunkach warunkowych.

Usunięto 53 podziękowania dla Stephena za wskazanie białej przestrzeni

Usunięto 26 dzięki linkowi udostępnionemu przez Caira

Jestem w tym całkiem nowy. Nie mogłem wymyślić, jak to zrobić bez opisania dni w miesiącu.

r=range
def n(Y):
 a,b,c=31,30,0
 for x in r(12):
  for y in r([a,(28if Y%4else 29),a,b,a,b,a,a,b,a,b,a][x]):
   if(x+1)*(y+1)==int(str(Y)[2:]):c+=1
 return c

Wypróbuj online!


5
Witamy na stronie i miły pierwszy post! Istnieje kilka sposobów na
— grę w

@cairdcoinheringaahing Dzięki za poradę link był bardzo przydatny!
— akozi

1
158 bajtów - trochę grałeś w golfa, ale przeważnie miałeś dużą długą linię spacji na trzeciej linii, nie wiem, jak się tam dostało
— Stephen

@Stephen Dzięki :) Dodałem twój jako dwie zmiany. Jeden do białych pól, a drugi do gry w golfa.
— akozi

(28if Y%4else 29)można skrócić do [29,28][Y%4>0]. Można także skrócić długą listę [a,...]+2*[a,b,a,b,a]. a,b,cmożna dodać do listy parametrów, aby zapisać linię. int(str(Y)[2:])można skrócić do Y%100. Wreszcie, zmienne przeciwne można przeważnie skrócić do lens wyrażeń listowych, co pozwala również nna wykonanie lambda. To daje 118 .
— Czarna sowa Kai

2

Naprzód (gforth) , 60 59 bajtów

: f 0 13 1 do over i /mod swap 32 i 2 = 3 * + 0 d< - loop ;

Wypróbuj online!

Ta wersja korzysta z faktu, że nie może być więcej niż 1 pasujący dzień na miesiąc, a rok musi być podzielny przez miesiąc, aby się zgadzał.

Wyjaśnienie

Iteruje po miesiącach, sprawdza, czy rok jest podzielny przez miesiąc i czy iloraz wynosi <31 (28 lutego) Miesiące po marcu nie mogą się zgadzać dla dni większych niż 25, więc możemy po prostu założyć wszystkie miesiące (inne niż luty) mają 31 dni na przeznaczenie układanki.

Objaśnienie kodu

: f                   \ start new word definition
  0                   \ set up counter
  13 1 do             \ start a counted loop from 1 to 12
    over i /mod       \ get the quotient and remainder of dividing year by month
    swap              \ default order is remainder-quotient, but we want to swap them
    32 i 2= 3 * +     \ we want to compare to 32 days unless month is Feb
    0 d<=             \ treat the 4 numbers on the stack as 2 double-length numbers
                      \ and compare [1]
    -                 \ subtract result from counter (-1 is true in Forth)
  loop                \ end loop
;                     \ end word definition    

[1] - Forth ma pojęcie liczb o podwójnej długości, które są przechowywane na stosie jako dwie liczby o pojedynczej długości (w postaci xy, gdzie wartość podwójnej = y * 2^(l) + x gdzie l jest rozmiarem w bitach pojedynczego w czwarta implementacja, nad którą pracujesz).

W tym przypadku porównałem iloraz i resztę do 32 (lub 29) 0. Jeśli reszta była większa niż 0 (rok niepodzielny przez miesiąc), pierwsze podwójne byłoby automatycznie większe niż 32 (lub 29) 0, a wynik byłoby fałszywe. Jeśli reszta to 0, oznacza to skuteczne regularne sprawdzanie ilorazu <= 32 (lub 29)

Dalej (gforth) , 61 bajtów

: f 0 13 1 do i 2 = 3 * 32 + 1 do over i j * = - loop loop ; 

Wypróbuj online!

Zaoszczędzono kilka bajtów, zdając sobie sprawę, że tylko luty ma znaczenie pod względem posiadania prawidłowej liczby dni w miesiącu

Wyjaśnienie

Czwarte (przynajmniej gforth) porównania zwracają -1 dla true i 0 dla false

0                     \ place 0 on top of the stack to use as a counter
13 1 do               \ begin the outer loop from 1 to 12
  i 2 = 3 *           \ if i is 2 place -3 on top of the stack, otherwise 0
  32 + 1 do           \ begin the inner loop from 1 to 31 (or 28)
    over              \ copy the year from stack position 2 and place it on top of the stack
    i j * = -         \ multiply month and day compare to year, subtract result from counter 
  loop                \ end the inner loop
loop                  \ end the outer loop

1

Java (JDK 10) , 79 72 70 bajtów

y->{int a=0,m=13;for(;m-->1;)a+=y%m<1&&y/m<(m==2?29:32)?1:0;return a;}

Wypróbuj online!


@Shaggy Thanks! (pozostałość po poprzedniej wersji, w której przeglądam wszystkie d
— pliki

Jeśli zmienisz &&na &to ta sama odpowiedź, co odpowiedź Javy Oliviera Grégoire'a, chociaż odpowiedział 19 minut wcześniej.
— Kevin Cruijssen

@KevinCruijssen Przypadkowy zbieg okoliczności. Chociaż moja wersja jest nieco gorsza (niepotrzebne użycie potrójnego).
— user202729,

1

JavaScript (Node.js) , 108 bajtów

a=>'0122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012'[a]

f=a=>'0122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012'[a]
o.innerText=[...Array(99)].map((_,x)=>(2001+x++)+` = `+f(x)).join`\n`
pre{column-count:5;width:480px;}
<pre id=o></pre>


Wyszukiwanie z użyciem siły brutalnej, miło!
— BradC

Witamy w PPCG!
— Kudłaty


1

Python 3, 132 bajty

To naprawdę dość długi program, ale pomyślałem, że może być interesujący.

Wszystkie wartości mieszczą się w zakresie od 0 do 7, więc koduję każdą liczbę 3 bitami w długim ciągu binarnym. Próbowałem wkleić nieprzetworzony ciąg binarny do mojego programu python, ale nie mogłem go uruchomić, więc zdecydowałem się na base64 w pliku.

Użyłem następującego ciągu jako tabeli odnośników (końcówka 7 została użyta do wypełnienia): 01223242434261334151533172234161321260115040331061312042410060032130113060021220420051013051110140127

Program pobiera ten ciąg i dekoduje go jako liczbę, a następnie używa przesunięcia bitowego w celu wyodrębnienia wyniku.

import base64
lambda n:int.from_bytes(base64.b64decode(b'pNRRxYtw01s9Jw4tFYE0QNkYsoRQgYBosEsYBFIRAUgsUkgwFQM='),'big')>>(6306-3*n)&7

66 bajtów + plik 37 bajtów = 103 bajty

Czyta to plik binarny o nazwie ei unika korzystania z base64.

lambda n:int.from_bytes(open('e','rb').read(),'big')>>(6306-3*n)&7

Oto zrzut heksowy odczytanego pliku (bez wypełniania):

00000000  a4 d4 51 c5 8b 70 d3 5b  3d 27 0e 2d 15 81 34 40  |..Q..p.[='.-..4@|
00000010  d9 18 b2 84 50 81 80 68  b0 4b 18 04 52 11 01 48  |....P..h.K..R..H|
00000020  2c 52 48 30 0a                                    |,RH0.|


1

Oracle SQL, 115 bajtów

select count(decode(sign(decode(l,2,29,32)-y/l),1,1))from t,
xmltable('1to 12'columns l int path'.')where mod(y,l)=0

Możemy zauważyć, że tak naprawdę nie ma znaczenia, ile dni w kwietniu (i późniejszych miesiącach), ponieważ 100/4 <28. Również nie trzeba sprawdzać, czy rok jest przestępny, czy nie. Musimy tylko określić, że w lutym jest 28 dni (nie 29, ponieważ ta walidacja zostanie wykonana tylko dla 2058, co nie jest skokiem), w przeciwnym razie może to być tylko 31 na dowolny miesiąc.

Inne podejścia

Oracle SQL (12c wydanie 2 i nowsze), 151 bajtów

select count(to_date(y/l||'-'||l||'-1' default '' on conversion error,'dd-mm-y'))from t,
(select level l from dual connect by level<=12)where mod(y,l)=0

Oracle SQL (12c wydanie 2 i nowsze), 137 bajtów

select sum(validate_conversion(y/l||'-'||l||'-1'as date,'dd-mm-y'))from t,
(select level l from dual connect by level<=12)where mod(y,l)=0

Zarówno rozwiązanie mogło 8 bajtów krótszy, jeśli wymienimy (select level l from dual connect by level<=12)się xmltable('1to 12'columns l int path'.')jednak Oracle zgłasza wyjątek z powodu błędu (testowane na wersji 12.2.0.1.0, 18.3.0.0.0).

SQL> select count(to_date(y/l||'-'||l||'-1' default '' on conversion error,'dd-mm-y'))from t,
  2  xmltable('1to 12'columns l int path'.')where mod(y,l)=0
  3  /
select count(to_date(y/l||'-'||l||'-1' default '' on conversion error,'dd-mm-y'))from t,
*
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected DATE got DATE


SQL> select sum(validate_conversion(y/l||'-'||l||'-1'as date,'dd-mm-y'))from t,
  2  xmltable('1to 12'columns l int path'.')where mod(y,l)=0
  3  /
select sum(validate_conversion(y/l||'-'||l||'-1'as date,'dd-mm-y'))from t,
*
ERROR at line 1:
ORA-43909: invalid input data type

Jedynym przypadkiem w obu rozwiązaniach, gdy rok ma znaczenie, jest rok 2058, który nie jest skokowy, dlatego dosłowne „-1” zostało użyte do określenia roku nieskokowego.

Oracle SQL, 128 bajtów

select count(d)from t,(select date'1-1-1'+level-1 d from dual connect by level<365)
where to_char(d(+),'mm')*to_char(d(+),'dd')=y

Oracle SQL, 126 bajtów

select substr('122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012',y,1)from t

Aktualizacja

Oracle SQL, 110 bajtów

select-sum(least(sign(y/l-decode(l,2,29,32)),0))from t,
xmltable('1to 12'columns l int path'.')where mod(y,l)=0

Oracle SQL, 108 bajtów

select sum(decode(sign(decode(l,2,29,32)-y/l)*mod(y+1,l),1,1))from t,
xmltable('1to 12'columns l int path'.')

Spark SQL, 137 bajtów

select count(cast(regexp_replace(concat_ws('-','2001',l,y/l),'.0$','')as date))
from(select explode(array(1,2,3,4,5,6,7,8,9,10,11,12))l),t

Spark 2.3+ SQL, 126 bajtów

( replacefunkcja staje się dostępna)

select count(cast(replace(concat_ws('-','2001',l,y/l),'.0')as date))
from(select explode(array(1,2,3,4,5,6,7,8,9,10,11,12))l),t

1

PHP , 73 bajty

Korzystanie z wprowadzania potoku i php -nR:

for(;++$m<13;$d=1)while($d<25+($m-2?$m>4?:7:4))$c+=$argn==$m*$d++;echo$c;

Wypróbuj online!

PHP , 76 bajtów

Za pomocą wprowadzania arg wiersza poleceń php dm.php 18:

for(;++$m<13;$d=1)while($d<25+($m-2?$m>4?:7:4))$c+=$argv[1]==$m*$d++;echo$c;

Wypróbuj online!

Podejście iteracyjne. Ponieważ jedynym rokiem przestępnym jest 2 * 29 = 58, a rok 2058 nie jest rokiem przestępnym, nie trzeba brać pod uwagę roku przestępnego w dniach lutowych. A ponieważ owijanie nie stanowi problemu - od kwietnia każdy dzień większy niż 25 przekroczy 100, po prostu mówimy, że reszta miesięcy ma tylko 25 dni.

Dane wejściowe to 2-cyfrowy rok za pomocą wiersza poleceń (-10 bajtów jako program, dzięki za sugestię z @Titus).

LUB:

PHP , 101 bajtów

$y=$argv[1];for($d=strtotime("$y-1");date(Y,$d)==$y;$d+=86400)eval(date("$\x+=j*n=='y';",$d));echo$x;

Wypróbuj online!

Wciąż iteracyjny, ale przy użyciu funkcji znaczników czasu PHP. Akceptuje rok jako czterocyfrowy numer. Dziękujemy za @Titus za sugestię użycia strtotime()zamiast mktime().


Pierwsza wersja zawiedzie przez 4-cyfrowe lata, druga zawiedzie przez dwie cyfry. Ale miłe myślenie. Spróbuj $m<5?$m-2?31:28:25pierwszego i $d=strtotime("$y-1")drugiego
— Tytusa

Uhm ... Dlaczego wprowadziłeś yewaluację w cudzysłów?
— Tytus

@Titus, ponieważ PHP7 traktuje teraz cyfry poprzedzone 0 jako ósemkowe, więc 08 i 09 w rzeczywistości nie są poprawne. tio.run/##K8go@G9jXwAkU5Mz8hUMFWxtFQwsrP//BwA Za pomocą funkcji date () można uzyskać tylko 2-cyfrowy, zerowany rok.
— 640 KB

Porażka! oczywiście.
— Tytus

1
@Titus, zaktualizowano drugą wersję, używając strtotime()zamiast mktime()i ponownie zaimplementowano jako program, -7 bajtów. Spojrzałem również na większość zgłoszeń, w tym te, które uzyskały najwyższy głos, będą przyjmować rok jako 2 lub 4 cyfry, więc przyjmę, że to zależy od autora. Jeszcze raz dziękuję za sugestie!
— 640 KB

0

PHP, 74 70 bajtów

while(++$m<13)for($d=$m<5?$m-2?31:28:25;$d;)$n+=$d--*$m==$argn;echo$n;

akceptuje tylko dwucyfrowe lata.

I przyjął gwaugh's rozważania i grałem je; moje pierwsze podejście było dłuższe niż jego (92 bajty):

for($y=$argn%100;++$m<13;)for($d=$m-2?30+($m+$m/8)%2:29-($y%4>0);$d;)$n+=$d--*$m==$y;echo$n;

%100 pozwala na użycie 4-cyfrowych lat.


Uruchom jako potok z -nRlub wypróbuj je online .


Możesz zapisać 4 bajty, usuwając% 100 i przyjmując tylko 2 cyfry, co jest OK: codegolf.stackexchange.com/questions/162137/…
— 640KB
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.