Data Sfida moltiplicante


19

(Ispirato dall'Enigmista della scorsa settimana su FiveThirtyEight.com. Post sandbox .)

Dato un anno tra il 2001 e il 2099, calcolare e restituire il numero di giorni durante quell'anno solare dove mm * dd = yy(dove yyè l' anno a 2 cifre ).

Il 2018, ad esempio, ha 5:

  • 18 gennaio (1 * 18 = 18)
  • 9 febbraio (2 * 9 = 18)
  • 6 marzo (3 * 6 = 18)
  • 3 giugno (6 * 3 = 18)
  • 2 settembre (9 * 2 = 18)

L'input può essere un anno numerico a 2 o 4 cifre.

L'output dovrebbe essere un numero intero. Lo spazio di trascinamento opzionale o il ritorno vanno bene.

Elenco completo di input / output:

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

Questa è una sfida di , vince il conteggio di byte più basso in ogni lingua.

Il pre-calcolo e la semplice ricerca delle risposte è normalmente escluso dalle nostre regole di scappatoia , ma lo autorizzo esplicitamente per questa sfida. Permette alcune interessanti strategie alternative, sebbene non sia probabile che un elenco di ricerca di 98 elementi da 99 sarà il più breve.


Se lo rende più facile nella tua lingua, la risposta sarà la stessa indipendentemente dal secolo; 1924 e 2124 hanno lo stesso numero di giorni del 2024.
BradC,

se il risultato di mm * dd è maggiore di 100 viene automaticamente filtrato?
DanielIndie,

@DanielIndie Corretto, non devono essere conteggiate date "avvolgenti". In altre parole, il 12 dicembre 2044 non conta, anche se 12 * 12 = 144.
BradC

Dato che dobbiamo gestire solo un numero limitato di input, li ho modificati tutti. Sentiti libero di eseguire il rollback o riformattare.
Shaggy,

1
@gwaugh Solo che puoi decidere quale accettare come input valido (quindi non devi spendere caratteri extra per la conversione tra i due).
BradC

Risposte:


14

Excel, 48 byte

Evviva! Finalmente qualcosa in Excel è davvero bravo.

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

Riceve input da A1 sotto forma di un numero intero compreso tra 1 e 99 che rappresenta l'anno e restituisce ovunque si immetta questa formula. È una formula di matrice, quindi usa Ctrl-Maiusc-Invio invece di Invio per inserirlo.

Questo sfrutta il fatto che COUNTignora gli errori, quindi qualsiasi errore causato dal mese che non divide l'anno (portando Excel a analizzare qualcosa di simile 2/12.5/25o che la data non è valida, come 2/29/58, viene semplicemente ignorato in silenzio.


1
Molto bella. Probabilmente vale la pena ricordare che richiede un anno a 2 cifre in A1. L'inserimento di un anno a 4 cifre ritorna semplicemente 0.
BradC,

Vero! Lo modificherò nella descrizione.
Sophia Lechner,

Inoltre, dovrei menzionare che è specifico della locale; dipende dall'avere una localizzazione che utilizza un ordine mm / gg / aa. In una locale con ordinazione gg / mm / aa, la risposta sarebbe ovviamente lo stesso numero di byte.
Sophia Lechner,

1
Super intelligente; Mi piace il modo in cui stai testando solo 12 candidati (uno al mese), invece di correre tutti i giorni dell'anno.
BradC,

Fissare l'anno a un byte di salvataggio senza un salto?
l4m2

6

Python 2 , 44 byte

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

Provalo online!

Una funzione anonima assegnata come oggetto metodo. Produce tutti i prodotti di (month, day)coppie (m, d)come codificato da k=32*m+dcon 0≤m≤12, 0≤d≤31, avvolgono. Elimina il 29-31 febbraio escludendoli dall'intervallo.


5

Java (JDK 10) , 65 byte

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

Provalo online!

Titoli di coda


Nessun anno bisestile 29*n, quindi non è necessario il controllo
l4m2

Grazie per il tuo contributo. Potrei rimuovere 27 byte in totale con un sacco di altre modifiche.
Olivier Grégoire,

1
Il passaggio (m==2?29:32)a 29+m%2*3sembra ancora dare tutti i OKrisultati. Ringraziamo la risposta di Ruby di @AsoneTuhid .
Kevin Cruijssen,

4

PowerShell , 94 byte

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

Provalo online!

Accetta input come un anno a due cifre, quindi costruisce a for loop da 1/1/yeara 12/9/year(perché il 12/10 e oltre non contano mai e questo salva un byte). Ogni iterazione, incrementiamo $ziff i .Monthtempi .Daysono uguali al nostro anno di input. Al di fuori del ciclo, $zviene lasciato sulla pipeline e l'output è implicito.

Modifica: dipende dalla cultura. Il codice sopra funziona peren-us . Potrebbe essere necessario cambiare il formato della data per altre culture.


2
"cultura"? Intendevi "locale"? ...
user202729

1
@ user202729 Colloquialmente, sì, ma la documentazione di PowerShell la chiama "cultura".
AdmBorkBork,

"Cultura" è la parola che la SM generalmente usa per parlare di locale, ad es. System.Globalization.CultureInfo in .NET.
Sundar - Ripristina Monica il




3

JavaScript (ES6), 91 byte

Ero curioso di sapere come l'hardcoding sarebbe paragonabile a un calcolo iterativo. È decisamente più lungo (vedi la risposta di @ Shaggy ), ma non terribilmente più a lungo.

Modifica : è, tuttavia, molto più lungo di una formula più diretta (vedi risposta @ l4m2 ).

Accetta l'input come numero intero in [1..99] .

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

Provalo online!

Come?

Gli anni dispari hanno significativamente meno possibilità di avere mm * gg = aa rispetto agli anni pari. Più concretamente, gli anni dispari hanno da 0 a 3 partite, mentre gli anni pari hanno da 0 a 7 partite. Questo ci consente di codificare ogni coppia di anni con soli 5 bit, che possono essere comodamente rappresentati come un singolo carattere nella base 36.




3

Utilità Bash + GNU , 57

  • 1 byte salvato grazie a @SophiaLechner
seq -f1/1/$1+%gday 0 365|date -f- +%m*%d-%y|bc|grep -c ^0

Si noti che il seq comando produce sempre un elenco di 366 date - per gli anni non bisestili verrà incluso il 1 ° gennaio dell'anno successivo. Tuttavia, nell'intervallo di date 2001..2099, MM * GG non sarà mai AA per il 1 ° gennaio dell'anno successivo per nessuno di questi anni, quindi questo giorno in più non influirà sul risultato.

Provalo online!


Molto bello - non sapevo nemmeno dateche uscirò con la matematica in quel modo durante l'analisi. seqnon è necessario uno spazio dopo il -f, quindi è possibile salvare un byte lì.
Sophia Lechner,

3

T-SQL, 123 121 byte

Secondo le nostre regole IO , l'input viene preso tramite la tabella t preesistente con un campo intero y , che contiene un anno a 2 cifre.

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

L'interruzione di riga è solo per leggibilità. Ispirato in gran parte da soluzione Excel di Sophia .

  • La riga superiore genera una tabella numerica di 12 elementi c che è unita alla tabella di input t .
  • Se ciò CONCAT()accade, mischio insieme un candidato per data , il che comporta varcharconversioni del tipo di dati implicite . Altrimenti dovrei fare un sacco diCAST o CONVERTdichiarazioni.
  • Ho trovato la funzione di valutazione perfetta ISDATE() , che restituisce 1 per date valide e 0 per date non valide.
  • Avvolgilo in una SOMMA e ho finito.
  • EDIT : spostato il segno di controllo della divisione di numeri interi ( y%m=0) inWHERE clausola per salvare 2 byte, grazie a @RazvanSocol.

Sfortunatamente, non è molto più breve della versione della tabella di ricerca (usando la stringa dalla versione di osdavison ):

Ricerca T-SQL, 129 byte

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

EDIT : Lasciando il mio originale sopra, ma possiamo salvare alcuni byte usando un paio di nuove funzioni:

  • STRING_SPLIT è disponibile in MS SQL 2016 e versioni successive.
  • CONCAT_WS è disponibile in MS SQL 2017 e versioni successive.
  • Come sopra, sostituito IIFconWHERE

MS-SQL 2017, 121 118 byte

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, edizione extra economica: 109 byte

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

Richiede di essere nel masterdatabase, che contiene una tabella di sistema spt_valuesche (se filtrata da TYPE='P'), consente di contare i numeri da 0 a 2048.


Simile ad altre risposte, l'ordine in cui assemblo la data ( m/d/y) dipende dalle impostazioni della località dell'istanza SQL. Altre località potrebbero richiedere un ordine diverso o un separatore diverso, ma non credo che influenzerebbe la lunghezza del codice.
BradC,

Immagino che tu abbia capito che la conversione del "29/02/64" in una data dà il 1964-02-29 (non il 2064-02-29), ma considerando che gli anni 2000 e 2100 sono esclusi, è un bel modo per ottenere una riduzione codice.
Razvan Socol,

L'utilizzo al SPLIT_STRINGposto di un CTE lo porta a 120 byte. Usando CONCAT_WSinvece di CONCATsalvare un altro personaggio, portandolo a 119 byte.
Razvan Socol,

@RazvanSocol Sì, non sono sicuro di dove si trovi l'interruzione tra le date a 2 cifre associate a 19xx vs 20xx, ma entrambe danno la stessa risposta. Proverò gli altri due suggerimenti, grazie!
BradC,

1
Sostituisci IIFcon WHERE.
Razvan Socol,

3

Julia 0.6 , 49 44 42 byte

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

Provalo online!

-5 byte ispirati alla risposta di Ruby di Asone Tuhid.
-2 byte sostituendo conteggio con somma

Spiegazione:

Per ogni mese ida 1 a 12, calcola y/ie controlla se è uno dei giorni di quel mese. I mesi con 31 giorni sono 1, 3, 5, 7, 8, 10, 12 - quindi sono dispari sotto 8 e persino a e sopra 8. Quindi o i%2o i÷8(che è 0 per i <8 e 1 per i> = 8 qui) dovrebbe essere 1, ma non entrambi - quindi li XOR. Se il risultato XOR è vero, controlliamo date 1:28+3cioè 1:31, altrimenti controlliamo solo le date 1:28.

1:28è sufficiente per il resto dei mesi (questo miglioramento ispirato alla risposta di Ruby di Asone Tuhid ) perché:

  • per febbraio, l'unica possibilità sarebbe stata 2*29 = 58, ma 2058non è un anno bisestile, quindi possiamo supporre che febbraio abbia sempre 28 giorni.

  • gli altri mesi con 30 giorni sono il mese 4 e oltre - per i quali i*29(e i*30) sarebbero superiori a 100, che possono essere ignorati.

Infine, contiamo il numero di volte che y/iappartiene a questo elenco di giorni (utilizzando sumqui il valore booleano ) e lo restituiamo.


3

JavaScript, 91 85 82 81 77 byte

Accetta l'input come una stringa di 2 cifre (o un numero intero di 1 o 2 cifre).

Sfrutta il fatto che new Datepasserà al passaggio al mese successivo e continuerà a farlo, se gli passi un valore di giorno che supera il numero di giorni nel mese che passi ad esso, quindi, nella prima iterazione, prova a costruire il data yyyy-01-345che diventa yyyy-12-11, o yyyy-12-10negli anni bisestili. Non è necessario controllare le date successive poiché si 12*11+ottiene un numero di 3 cifre.

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

3 byte salvati grazie ad Arnauld .


Provalo

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 byte

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

L'input è nella cella A1nel formato yyyy. Questa è una formula di matrice ed è inserita con Ctrl+ Shift+ Enterper ottenere le parentesi graffe {}. È abbastanza semplice e senza intelligenza.

Quando ci si trova in una formula di matrice, DATE(A1,1,0)+ROW(1:366)ci fornisce una matrice di 366 valori di data. Negli anni non bisestili, questo includerà il 1 ° gennaio dell'anno successivo, ma questo non è un problema perché 1*1=1e sarebbe considerato falso positivo solo se l'anno successivo lo è 2001, ma poiché l'intervallo di anni richiesto è 2001 - 2099, non si presenterà mai come problema.

Se hai abbreviato quel bit semplicemente ~, la formula è molto più facile da seguire:

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

Ho provato a utilizzare COUNTIF()invece di, SUM(IF())ma Excel non mi ha nemmeno permesso di inserirlo come formula di matrice, tanto meno mi dà un risultato. Ho fatto trovare una Fogli Google soluzione che utilizza CountIf()ma lo stesso metodo altrimenti che si rivelò essere di 91 byte, in gran parte perché utilizza ArrayFormula()invece di { }.

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

Non ho visto un consenso, ma in genere non ho incluso le parentesi graffe esterne nei miei conteggi di byte per Excel. Sembrano più un modo in cui Excel sta formattando il suo display che parte della formula. Opinioni?
Sophia Lechner,

@SophiaLechner li ho inclusi invece di decidere come includere i tasti aggiuntivi richiesti per inserirlo come formula di matrice. C'è una meta domanda riguardo che e l'unica risposta che dice il CTRL + ALT + INVIO comando conterebbe come 1 battitura. Se usi lo stesso di vim ( per meta ), la sequenza di tasti conta come 1 byte. Tuttavia, di solito non conto INVIO alla fine dell'inserimento di una formula come 1 byte in altre risposte.
Ingegnere Toast,

2

Retina 0.8.2 , 55 byte

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

Provalo online! Richiede un anno a due cifre; aggiungere 1 byte per supportare anni a 4 cifre. Spiegazione: Il primo stadio si converte semplicemente in unario. La seconda fase inizia abbinando da 1 a 12 caratteri prima della posizione della partita, che rappresenta il mese, quindi tenta di guardare avanti per un numero intero di ripetizioni di quel mese. Tuttavia, il lookahead contiene un condizionale, che sceglie tra 27 o 30 ripetizioni aggiuntive a seconda del mese. Il conteggio delle posizioni delle partite è quindi il risultato desiderato.


2

R , 22 122 byte

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

Provalo online!

Ho deciso di seguire un approccio con tabella di ricerca. L'anno di immissione deve essere di 2 cifre.


1
Anche su TIO puoi premere il pulsante "link" e formatterà automaticamente la risposta per te. Grazie a Dennis per averlo configurato!
Giuseppe,

Puoi rimuovere l'iniziale if, poiché l'input può essere a 2 o 4 cifre, a tua scelta (quindi puoi scegliere di accettare solo input a 2 cifre). Ma sembra che il codice consideri che ogni mese contiene 31 giorni, quindi per esempio, 62 (per il 2062) restituisce 1 dove dovrebbe restituire 0.
Sundar - Ripristina Monica il

2
Ho frainteso. Detto questo, sono abbastanza sicuro che la tabella di ricerca dovrebbe essere inclusa nel conteggio dei byte.
ngm

@ngm Inoltre non ero sicuro che la tabella di ricerca dovesse essere inclusa, ma la aggiungerò al conteggio dei byte solo per sicurezza.
Robert S.

Non sono ancora sicuro di quali siano tutte le regole!
ngm


2

J , 29 byte

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

Provalo online!

Come funziona

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

Ho provato a superare la soluzione di gelatina 2 volte :)

Nota a margine

Se qualcuno vuole davvero codificare i dati a 99 cifre, ecco alcune informazioni:

Dividi le 99 cifre in blocchi di 2 cifre. Quindi la prima cifra è <4e la seconda <8, il che significa che cinque bit possono codificare due numeri. Quindi è possibile codificare tutti i dati in 250 bit o 32 byte.


2

Python 3 , 158 162 215 241 byte

Rimosso 4 Grazie a Stephen per aver giocato a golf i condizionali.

Rimosso 53 grazie a Stephen per aver indicato lo spazio bianco

Rimosso 26 grazie al link fornito da caird

Sono abbastanza nuovo in questo. Non riuscivo a pensare a come farlo senza che i giorni in un mese fossero descritti.

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

Provalo online!


5
Benvenuti nel sito e bel primo post! Ci sono alcuni modi in cui puoi giocare a golf, come rimuovere alcuni spazi bianchi, quindi assicurati di dare un'occhiata a questi suggerimenti per giocare a golf in Python
caird coinheringaahing

@cairdcoinheringaahing Grazie per il consiglio il link è stato molto utile!
akozi,

1
158 byte - ho giocato a golf un po 'di distanza, ma soprattutto hai avuto una lunga serie di spazi sulla terza linea, non so come siano arrivati ​​lì
Stephen,

@Stephen Grazie :) Ho aggiunto le tue come due modifiche. Uno per lo spazio bianco e l'altro come il golf.
akozi il

(28if Y%4else 29)può essere abbreviato in [29,28][Y%4>0]. Inoltre, l'elenco lungo può essere abbreviato in [a,...]+2*[a,b,a,b,a]. a,b,cpuò essere aggiunto nell'elenco dei parametri per salvare una riga. int(str(Y)[2:])può essere abbreviato in Y%100. Infine, le variabili contatore possono principalmente essere abbreviate in lens di comprensione dell'elenco, ciò consente anche di creare nun lambda. Questo fa 118 .
Black Owl Kai

2

Forth (gforth) , 60 59 byte

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

Provalo online!

Questa versione sfrutta il fatto che non ci può essere più di 1 giorno corrispondente al mese e che l'anno deve essere divisibile per mese affinché coincida.

Spiegazione

Scorre tra i mesi, controlla se l'anno è divisibile per mese e se il quoziente è <31 (28 per febbraio) I mesi dopo marzo non possono corrispondere per giorni superiori a 25, quindi possiamo solo ipotizzare tutti i mesi (diversi da febbraio) avere 31 giorni ai fini del puzzle.

Spiegazione del codice

: 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 ha il concetto di numeri a doppia lunghezza, che sono memorizzati nello stack come due numeri a lunghezza singola (della forma xy, dove il valore del doppio = y * 2^(l) + xdove l è la dimensione in bit di un singolo nella quarta implementazione con cui stai lavorando).

In questo caso, ho confrontato il quoziente e il resto con 32 (o 29) 0. Se il resto fosse maggiore di 0 (anno non divisibile per mese), il primo doppio sarebbe automaticamente maggiore di 32 (o 29) 0 e il risultato sarebbe falso. Se il resto è 0, si risolve in modo efficace per un controllo regolare del quoziente <= 32 (o 29)

Forth (gforth) , 61 byte

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

Provalo online!

Ho salvato alcuni byte rendendomi conto che solo febbraio conta in termini di avere il numero corretto di giorni nel mese

Spiegazione

I confronti di Forth (almeno gforth) restituiscono -1 per true e 0 per 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 byte

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

Provalo online!


@Shaggy Grazie! (rimanente della versione precedente in cui d
eseguo il

Se cambi &&a &è la stessa risposta della risposta Java di OlivierGrégoire, sebbene abbia risposto 19 minuti prima.
Kevin Cruijssen,

@KevinCruijssen Casuale coincidenza. Anche se la mia versione è un po 'peggio (uso non necessario del ternario).
user202729

1

JavaScript (Node.js) , 108 byte

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>


Ricerca di forza bruta, bello!
BradC,

Benvenuti in PPCG!
Shaggy,


1

Python 3, 132 byte

Questo è davvero un programma abbastanza lungo, ma ho pensato che potesse essere interessante.

Tutti i valori sono compresi tra 0 e 7, quindi codifico ogni numero con 3 bit in una lunga stringa binaria. Ho provato a incollare una stringa binaria non elaborata nel mio programma Python ma non sono riuscito a farlo funzionare, quindi ho optato per base64 nel file.

Ho usato la seguente stringa come tabella di ricerca (fine 7 usata per il riempimento): 01223242434261334151533172234161321260115040331061312042410060032130113060021220420051013051110140127

Il programma prende questa stringa e la decodifica come numero, quindi usa lo spostamento dei bit per estrarre il risultato.

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

66 byte + 37 byte file = 103 byte

Questo legge un file binario chiamato eed evita di usare base64.

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

Ecco un hexdump del file letto (senza riempimento):

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 byte

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

Possiamo notare che non importa quanti giorni ad aprile (e mesi successivi), dal 100/4 <28. Inoltre, non è necessario verificare se l'anno è un salto o meno. Dobbiamo solo specificare che ci sono 28 giorni a febbraio (non 29 perché quella convalida verrà eseguita solo per il 2058 che non è un salto), altrimenti potrebbe essere solo 31 per ogni mese.

Altri approcci

Oracle SQL (12c versione 2 e successive), 151 byte

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 versione 2 e successive), 137 byte

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

Entrambe le soluzioni avrebbero potuto essere più brevi di 8 byte se sostituiamo (select level l from dual connect by level<=12)conxmltable('1to 12'columns l int path'.') ma Oracle genera un'eccezione a causa del bug (testato sulle versioni 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

L'unico caso in entrambe le soluzioni in cui l'anno è importante è il 2058, che è senza salti, quindi è stato usato letteralmente '-1' per specificare l'anno senza salti.

Oracle SQL, 128 byte

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 byte

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

Aggiornare

Oracle SQL, 110 byte

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 byte

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 byte

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 byte

(la replacefunzione diventa disponibile)

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 byte

Utilizzando input pipe e php -nR:

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

Provalo online!

PHP , 76 byte

Utilizzando l'input arg della riga di comando 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;

Provalo online!

Approccio iterativo. Poiché l'unico anno bisestile da considerare è 2 * 29 = 58 e il 2058 non è un anno bisestile, non è necessario considerare l'anno bisestile nei giorni di febbraio. E poiché il wraparound non è un problema - da aprile in poi, ogni giorno superiore a 25 supererà i 100, diciamo solo che il resto dei mesi ha solo 25 giorni.

L'input è un anno a 2 cifre tramite riga di comando (-10 byte come programma, grazie al suggerimento di @Titus).

O:

PHP , 101 byte

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

Provalo online!

Ancora iterativo ma usando le funzioni timestamp di PHP. Accetta l'anno come numero di quattro cifre. Grazie a @Titus per il suggerimento di utilizzare strtotime()invece di mktime().


La prima versione fallisce per anni a 4 cifre, la seconda fallisce per due cifre. Ma bello pensare. Prova $m<5?$m-2?31:28:25per il primo e $d=strtotime("$y-1")per il secondo
Tito

Uhm ... Perché hai inserito il valore ytra virgolette?
Tito

@Titus perché PHP7 ora tratta le cifre precedute da 0 come ottali, quindi 08 e 09 in realtà non sono validi. tio.run/##K8go@G9jXwAkU5Mz8hUMFWxtFQwsrP//BwA Usando la funzione date () puoi ottenere solo un anno a 2 cifre, con zero.
640 KB

Bummer! ovviamente.
Tito

1
@Titus, seconda versione aggiornata usando strtotime()invece di mktime()e reimplementato come programma, -7 byte. Inoltre, ho esaminato la maggior parte degli invii, compresi quelli più votati, che accetteranno l'anno solo come 2 o 4 cifre, quindi lo prenderò per significare che dipende dal mittente. Grazie ancora per i suggerimenti!
640 KB

0

PHP, 74 70 byte

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

accetta solo anni a due cifre.

Ho adottato le considerazioni di Gwaugh e le ho giocate a golf; il mio primo approccio era più lungo dei suoi (92 byte):

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 consente di utilizzare anni a 4 cifre.


Esegui come pipe -nRo provali online .


È possibile salvare 4 byte rimuovendo il% 100 e solo prendendo in ingresso a 2 cifre, che è OK: codegolf.stackexchange.com/questions/162137/...
640KB
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.