Trova l'ultima domenica di ogni mese di un determinato anno


21

Soluzioni F # conosciute all'interno di 140 caratteri , e questo è un problema con il codice Rosetta .

Risultato richiesto su stdout o in una variabile stringa per l'anno di input 2014:

2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28

Come richiesto, per il 1900:

1900-01-28 1900-02-25 1900-03-25 1900-04-29 1900-05-27 1900-06-24 1900-07-29 1900-08-26 1900-09-30 1900-10-28 1900-11-25 1900-12-30

E 2000:

2000-01-30 2000-02-27 2000-03-26 2000-04-30 2000-05-28 2000-06-25 2000-07-30 2000-08-27 2000-09-24 2000-10-29 2000-11-26 2000-12-31

Posato perché le date sembrano mettere in evidenza imbarazzo nella maggior parte delle lingue. Spero di vederli più che consentire le librerie di date! Ma se esterno alla lingua di base, dichiarare nel nome del post (ad es. Coda + NodaTime di Jon Skeet).

chiarimenti:

  • Gamma di anni 1900 a 3015
  • calendario gregoriano
  • In caso contrario, qualunque cosa sia convenzionale per Regno Unito / Londra.
  • Un programma che utilizza un comando a riga di comando o stdin va bene, producendo il risultato su stdout
  • Anche una funzione che assume un valore per l'anno e restituisce una stringa va bene.

Scappatoie standard escluse . In attesa di soluzioni APL, J, K e di vedere alcune nuove librerie di date.


@ Sp3000 - 1752 potrebbe essere particolarmente imbarazzante :-)
ossifrage schizzinoso

@ MartinBüttner: utilizza le librerie di date, ha modificato la domanda per chiedere alle persone di dichiarare quelle che usano con la lingua.
Phil H,

1
È necessario specificare l'intervallo di anni che sono input validi e considerazioni sull'adozione gregoriana. (Vale a dire se l'intervallo di anni include uno qualsiasi prima del 1930, è necessario specificare che il calendario gregoriano deve essere utilizzato per l'intero intervallo, indipendentemente dalle impostazioni internazionali; o che l'output può variare in base alle impostazioni internazionali; oppure è necessario indicare una data di interruzione prima della quale il calendario giuliano dovrebbe essere usato e testare i casi per i tre anni intorno al passaggio all'euro).
Peter Taylor,

1
@squeamishossifrage: l'ho limitato a 1900 e Gregorian, perché preferirei evitare un progetto di ricerca per stabilire le specifiche ...
Phil H

1
@Adám: mi dispiace di averti aspettato così tanto tempo per una risposta :) Sì, davvero.
Phil H,

Risposte:


1

Dyalog APL con cal da dfns , 19 byte

Meglio tardi che mai!

Richiede l'anno, restituisce un elenco di date nel formato aaaaaaaaaaaaaaaaaaaaaa '' .

⎕{⍺⍵,2↑⊢⌿cal⍺⍵}¨⍳12

richiedere un input numerico e lasciare che sia l'argomento sinistro del

{... funzione anonima (di seguito) applicata a ciascuno di

⍳12 i numeri da 1 a 12 (i mesi)

La funzione anonima sopra è la seguente:

⍺⍵, anteporre gli argomenti sinistro e destro (ad es. anno e mese) a

2↑ i primi due personaggi di

⊢⌿ la riga più in basso di

cal il calendario per

⍺⍵ argomento sinistro e argomento destro (anno e mese)

TryAPL online:

  1. Ritorna a questa pagina dopo aver fatto clic qui per importare cale le sue dipendenze.

  2. Fare clic qui per eseguire i casi di test.


Molto buona. Avevo sperato in una libreria APL che capisse cosa significano le date, ma cal è ragionevole!
Phil H,

@PhilH data e giorni ?
Adám,

1
@PhilH C'è anche lo spazio dei nomi Date di MiServer.
Adám,

1
@PhilH e Dyalog le primitive diadiche di APL + - < = e funzionano con oggetti data .Net .
Adám,

7

Rubino, 91 + 6 = 97

#!ruby -prdate
$_=(Date.new(y=$_.to_i)...Date.new(y+1)).select(&:sunday?).chunk(&:mon).map{|k,v|v[-1]}*' '

Funziona abbastanza bene. select(&:sunday?)è carino e, sorprendentemente, *' 'esegue tutta la formattazione da solo.


Bei trucchi! Puoi salvare altri tre caratteri usando chunkinvece di group_by.
Cristian Lupascu,

Quindi posso, gentile.
histocrat,

6

Bash 4.x + ncal, 57

Se i separatori di nuova riga sono OK anziché gli spazi, è possibile rimuovere l' -nopzione e lo spazio finale echodall'istruzione. E immagino che funzionerà ancora senza lo shebang, quindi ho rimosso anche quello:

for i in {01..12};{ echo "$1-$i-`ncal $i $1|tail -c-3`";}

Script originale (73 byte):

#!/bin/bash
for i in {01..12};{ echo -n "$1-$i-`ncal $i $1|tail -c-3` ";}

Uso:

$ bash sundays.sh 2014
2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-31
2014-09-28
2014-10-26
2014-11-30
2014-12-28
$

Nota: le versioni Bash precedenti alla 4.0 ometteranno gli zeri iniziali dei mesi. Questo può essere risolto con l'aggiunta di 5 caratteri cambiando {01..12}in `seq -w 1 12)`. Inoltre, tail -c-3potrebbe causare problemi su alcuni sistemi in cui l'output di ncalinclude spazi finali, ma non ne sono a conoscenza.


1
La differenza è davvero correlata a Darwin, non solo alla versione di Bash? È stato aggiunto in Bash 4.0 (anche se in seguito c'erano alcuni bug). Ad ogni modo, 1 personaggio può ancora essere risparmiato usando `…`invece di una buona abitudine $(…).
arte

Ah, potrebbe essere. Darwin dice che sta usando la versione 3.2.53; Debian sta usando 4.1.5.
ossifrage schizzinoso

@manatwork PS Ho appena notato il tuo commento sulle zecche posteriori. Buona cattura, grazie!
ossifrage schifoso

Non penso che sia necessario conteggiarli #!/bin/bashai fini del golf.
Trauma digitale il

@DigitalTrauma Va bene. Sembra che posso usare anche le interruzioni di riga anziché gli spazi. Fino a 57 byte ora :-)
ossifrage schizzinoso

6

IBM DFSORT, 11 3 righe di 71, 72 o 80 caratteri

 OPTION COPY 
 OUTFIL REPEAT=12,OVERLAY=(5:SEQNUM,2,ZD,5,2,1,8,Y4T,LASTDAYM,TOJUL=Y4T*
 ,9,7,Y4T,ADDDAYS,+1,TOJUL=Y4T,1:16,7,Y4T,PREVDSUN,TOGREG=Y4T(-),12X) 

Le due risposte con formato di uscita colonnare hanno superato la prova del tempo. Questo mi dà un "loop", una specie di, in quello su OUTFIL REPEAT = copia il record corrente più volte.

Tecnica diversa per arrivare al valore, che sembra più lungo ma più breve in quanto non riesco a trovare un modo incondizionato per gestire il 12 ° disco nell'anno successivo, e renderlo condizionato significa includere IFTHEN=(WHEN=, due volte, e altre cose. Guadagnare sulle altalene (il primo del mese è il modo più semplice per farlo) perdere pesantemente sulle rotatorie (particolari requisiti di sintassi).

Questo utilizza una funzione integrata (tutte le funzioni in DFSORT sono integrate) per trovare l'ultimo giorno del mese. Quindi aggiunge un giorno (funzione) per arrivare al primo del mese successivo e utilizza la funzione PREVDSUN per ottenere la domenica precedente (che sarà sempre l'ultima domenica del mese precedente, come prima).

Quando si trasforma l'anno (immissione) in una data valida, viene utilizzato un numero progressivo a due cifre per il mese e quel valore viene copiato anche per il giorno, poiché il punto di partenza non ha importanza per il tempo in cui siamo validi dopo l'ultimo giorno del mese inizialmente: 5,2è più breve di C'01'.

Ecco il dettaglio:

OPZIONE COPIA: copia il file di input nell'output

OUTFIL: per consentire più file di output, con selezione e formattazione diverse, produrre report formattati. Usato preferibilmente al più corto a INRECcausa dell'uso di REPEAT=.

REPEAT = 12: produce 12 copie di ciascun record. In questo esempio, può esserci un solo record di input (a differenza della versione precedente) a causa di SEQNUM.

5: - inizia dalla colonna 5 del record.

SEQNUM, 2, ZD - numero progressivo, l'impostazione predefinita inizia con una, due cifre, "decimale suddiviso in zone" (per i segni senza segno, che saranno, uguale al carattere).

1,8 - copia i byte 1 per la lunghezza 8 nella posizione corrente (9). Questo perché Y4T deve vedere che 8, altrimenti verrà utilizzato un formato data diverso.

Y4T - data in formato ccyymmdd (a causa dell'8 immediatamente davanti ad esso).

LASTDAYM - Ultimo giorno del mese (anche possibile di settimana, trimestre e anno).

TOJUL = - output della conversione della data per le funzioni della data (TOJUL è un carattere in meno di TOGREG)

9,7 - ora che è lungo 7, Y4T sarà CCYYDDD.

ADDDAYS - aggiunge un numero di giorni, adattandosi automaticamente se si passa al mese / anno successivo (potrebbe anche essere ADDMONS e ADDYEARS)

PREVDSUN - arriva la data giuliana, si trova la domenica precedente, TOGREG per ottenere il formato di output corretto, con il separatore "-" (potrebbe essere qualcosa che ti piace come separatore)

12X - spazi vuoti per chiarire il casino che ci ha permesso di farlo in un modo così breve

L'output di cui sopra, per il 2014, è:

2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-31
2014-09-28
2014-10-26
2014-11-23
2014-12-28

È necessario qualcosa per dire al SORT cosa fare. Non esiste alcun valore predefinito. OPTION COPYè il più corto, SORT FIELDS=COPYè equivalente ma più lungo.

Il lavoro stesso è stato svolto questa volta OUTFIL(per consentire l'uso di REPEAT). Il codice di lavoro è probabilmente uno di 160 (2 * 80), 144 (2 * 72), 140 (72 + 69) o 138 (70 + 68) (esclusi gli spazi vuoti iniziali, la continuazione forzata e gli spazi vuoti finali).

Dato che il ricevitore dovrebbe sapere cosa stanno facendo, penso di poter dire che il codice DFSORT elenca l'ultima domenica di ogni mese per qualsiasi anno dal 1900 (funzionerà dall'anno 0001, ma sto evitando la ricerca come bene) fino a 9999 (sebbene DFSORT supporti anni fino a 9999, la soluzione precedente non funzionerebbe nell'anno 9999 poiché la dodicesima data va nell'anno successivo) può essere twittata.

Perché il codice è così lungo, se ci sono funzioni incorporate particolarmente adatte?

Le definizioni dei campi sono effimere. Un campo è definito solo come una posizione particolare all'interno dei dati (che è un record) per il suo uso immediato. Per dirla in altro modo, i campi non sono definiti come tali, ma sono definiti per ogni utilizzo e solo per l'uso. Le funzioni di data devono sapere quali (di molti) formati di data sono utilizzati per l'origine e l'output deve essere in un formato di data, quindi deve essere specificato.

Ora che abbiamo un appuntamento giuliano ... TBC?


 OPTION COPY 
 INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8*
 ,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4,14:C'3',22:C'4',30:C'5',38:C'6',*
 46:C'7',54:C'8',62:C'9',69:C'10',77:C'11',85:C'12',127:X,89,8,Y4T,PREV*
 DSUN,TOGREG=Y4T(-),116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-),105:X,73,8,Y4*
 T,PREVDSUN,TOGREG=Y4T(-),94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-),83:X,57,*
 8,Y4T,PREVDSUN,TOGREG=Y4T(-),72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-),61:X*
 ,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-),50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-),*
 39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-),28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T*
 (-),17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-),1:1,8,Y4T,PREVDSUN,TOGREG=Y4T*
 (-),11:X,18,120,6X) 

Ne ha bisogno JCL

//LASTSUNG EXEC PGM=SORT 
//SYSOUT   DD SYSOUT=* 
//SORTOUT  DD SYSOUT=* 
//SYSIN    DD * 

E un file di input (un'altra riga di JCL e tre elementi di dati instream):

//SORTIN DD *
2014 
1900 
2000 

produce:

2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28
1900-01-28 1900-02-25 1900-03-25 1900-04-29 1900-05-27 1900-06-24 1900-07-29 1900-08-26 1900-09-30 1900-10-28 1900-11-25 1900-12-30
2000-01-30 2000-02-27 2000-03-26 2000-04-30 2000-05-28 2000-06-25 2000-07-30 2000-08-27 2000-09-24 2000-10-29 2000-11-26 2000-12-31

Funzionerà effettivamente fino all'anno 9999.

DFSORT è il prodotto di ordinamento Mainframe di IBM. I dati possono essere manipolati, ma poiché l'ordinamento è fondamentale e gli ordinamenti sono spesso di grandi dimensioni e di lunga durata, le schede di controllo DFSORT non hanno costrutti di loop, quindi non possiamo mettere un SORT in un loop. Rende le cose un po 'complicate per attività come il golf.

Perché pubblicare la risposta, è perché DFSORT ha una PREVDdayfunzione. Quindi la scorsa domenica di un mese è facile. È la domenica precedente (PREVDSUN) al primo giorno del mese successivo.

È stato anche divertente farlo all'interno di un "operando" (OVERLAY), un po 'come fare tutto all'interno sprintfo simile.

Qui è ungolfed:

 OPTION COPY 

 INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8, 
         1,8,1,8,1,8,1,8, 
         1,8,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4, 
         14:C'3',22:C'4',30:C'5',38:C'6',46:C'7',54:C'8',
         62:C'9',69:C'10',77:C'11',85:C'12', 
        127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
        116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
        105:X,73,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         83:X,57,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         61:X,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
          1:1,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         11:X,18,120,6X) 

Sebbene non sia del tutto un abuso, non sarebbe normale tentare di stipare tutto questo in un OVERLAY, e ci sono alcune cose apparentemente non necessarie che sono necessarie per consentire a tutto di andare in un OVERLAY. C'è un po 'di spazio per giocare a golf, ma dal momento che eliminerebbe solo una linea al massimo, non sono tentato.

L'INREC viene elaborato per ciascun record.

OVERLAY consente di modificare il contenuto di un record esistente. Se il record viene esteso oltre la sua lunghezza nel processo, questo non è un problema.

1,4 è l'anno in arrivo. Ha un letterale di 0201 aggiunto ad esso, e quindi i successivi 1,8 lo ripetono 11 volte per dare un lungo mandrino di 96 byte,

Al dodicesimo anno del record corrente esteso viene aggiunto 1 e il suo mese è stato portato a 1 (gennaio).

I restanti 10 mesi vengono cambiati da 3 a 11.

Poi ci sono 12, in ordine inverso (a causa di OVERLAY) di questo tipo di cose:

127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-),

Il n: è un numero di colonna nel record. La X inserisce uno spazio. 89,8 prende i dati da quella colonna / lunghezza, Y4T li considera come una data CCYYMMDD, PREVDSUM elabora la domenica precedente, TOGREG = Y4T (-) li emette come una data CCYY-MM-DD gregoriana.

Poiché si ottiene spazzatura se l'origine e il target di una parte particolare di un OVERLAY si sovrappongono in modo distruttivo, gli ultimi si 11:X,18,120,6X)riorganizzano e mascherano un po 'di casino.

Manuali e documenti sono disponibili all'indirizzo: http://www-01.ibm.com/support/docview.wss?uid=isg3T7000080 e include la Guida alla programmazione dell'applicazione DFSORT di oltre 900 pagine.

Come per tutti i prodotti IBM, tutti i manuali sono disponibili gratuitamente (tranne una quantità estremamente piccola di quelli molto costosi che solo un numero molto piccolo di persone al mondo pretenderebbe di capire).

Tutte le carte di controllo DFSORT devono iniziare con uno spazio vuoto. La colonna 72 viene utilizzata solo per la continuazione (qualsiasi operazione non vuota lo farà, ma * è convenzionale). La colonna 72 è seguita da un'area del numero di sequenza che viene ignorata, rendendo ogni record 80 byte.

Un'altra coppia di soluzioni a venire, forse.


5

Bash, 63 byte

for i in {01..12};{  date -v30d -v${i}m  -v2014y  -vsun +%Y-%m-%d;}

Produzione:

2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-24
2014-09-28
2014-10-26 
2014-11-30
2014-12-28

for i in {1..12};{ date -v30d -v${i}m -v$1y -v0w +%Y-%m-%d;}- 60 byte
Trauma digitale il

-vparam to dateè specifico della data BSD. Quindi funziona su OSX, ma non sulla maggior parte di Linux, forse dovrebbe essere indicato nella risposta.
Digital Trauma,

@DigitalTrauma, funziona su Mac e sul mio Linux.
michael501,

4

Python 2 - 189 byte

y=input()
for m in range(12):
 d=[31-(1322>>m&1),28+(y%400<1or 1>y%4<y%100)][m==1];Y=y-(m<2);Z=Y%100;C=Y/100
 while(d+13*((m-2)%12+4)/5+Z+Z/4+C/4-2*C)%7-1:d-=1
 print"%d-%02d-%d"%(y,m+1,d),

Immettere la data tramite STDIN.

Ancora più golf che si può fare. Il programma va un po 'fuori bordo, solo per divertimento:

  • Nessuna importazione, in particolare non utilizzando alcuna funzione di data integrata
  • Utilizza la congruenza di Zeller per calcolare i giorni della settimana

Appunti

  • 1322 è una tabella di ricerca magica per determinare se un mese non di febbraio ha 30 o 31 giorni
  • Non zfillè necessario per anni a causa della gamma di input, né giorni in quanto saranno sempre più di 20

Python 2 - 106 byte

La soluzione non divertente:

from calendar import*
y=input();m=1
while m<13:w,n=monthrange(y,m);print"%d-%02d-%d"%(y,m,n-(n+w)%7),;m+=1

calendar.monthrangerestituisce due numeri: il giorno della settimana in cui inizia il mese ( w) e il numero di giorni del mese ( n). La soluzione è un po 'controintuitiva a causa di una cattura: il giorno della settimana restituito inizia a 0 per lunedì , non domenica! Tuttavia, ciò è compensato dal fatto che nè basato su 1.


1
Una risposta $from calendar import monthrange as gt$V12AGH>QhN%"%d-%02d-%d"(QhN-H%+GH7
Pyth

3

JavaScript (ES6) 155 145

Modifica Problemi di fuso orario risolti Potrebbe essere più breve se reso ricorsivo. Può essere.

F=y=>{
  for(n=i=o=[];!o[11];)
    d=new Date(Date.UTC(y,0,++i)),m=d.getMonth(),
    d.getDay()||(m!=n&&o.push(p.toISOString().slice(0,10)),p=d,n=m);
  return o.join(' ')
}

È possibile utilizzare new Date(y,0,++i,9). Inoltre, ciò fallisce per gli anni bisestili del 2100 e oltre poiché JS non ha informazioni su quegli anni bisestili e quindi non ha Feb 29affatto negli anni bisestili per il 2100 e oltre.
Ottimizzatore

@Optimizer non è JS: 2100,2200,2300 non sono anni bisestili. Il 2014 è un anno bisestile e JS lo sa. Per quanto riguarda l'utilizzo dell'ora 9, non posso verificare, ma penso che non funzioni se ad esempio sei a Melbourne ...
edc65,

Ah .. Non ho mai saputo che cadiamo 3 giorni per 400 anni. Circa il 9 - ho cambiato il mio fuso orario da -1000 (Hawaii) a 1100 (Melbourne) e new Date(2014,0,26,9)stato di Domenica dando corretta ISOstringa così come getDay()come 0.
Ottimizzatore il

3

JavaScript, ES6, 222 219 199 byte

Non ho visto nessuna risposta JavaScript nel wiki di rosetta.

Eccoci qui:

S=Y=>{for(l=[],p=new Date(Y,i=0);i<365+!(Y%4);)if(!(d=new Date(Y,0,++i,9)).getDay()){p.getMonth()-d.getMonth()&&l.push(p);p=new Date(d)}return[...l,p].map(x=>x.toISOString().split("T")[0]).join(" ")}

Questo crea una funzione Sche restituisce una stringa con l'output desiderato. la funzione si occupa anche degli anni bisestili.

Grazie a ES6, questo funziona solo con un ultimo Firefox.

Grazie a apsillers per la punta che è stata ridotta a 200 byte

Trova la versione non golf di seguito come frammento di stack che puoi eseguire qui stesso:

S=Y=>{
  for(l=[],p=new Date(Y,i=0);i<365+!(Y%4);)
    if(!(d=new Date(Y,0,++i,9)).getDay()){
      p.getMonth()-d.getMonth()&&l.push(p);
      p=new Date(d)
    }
  return[...l,p].map(x=>x.toISOString().split("T")[0]).join(" ")
}

alert(S(parseInt(prompt())))


Puoi usare + prompt () invece di parseInt e radere via alcuni byte
Jacob,

@Jacob Quel prompt non viene aggiunto al conteggio dei byte.
Ottimizzatore

OIC. Avrei dovuto leggere la domanda ...
Jacob,

@apsillers Grazie mille! Risolto il problema e ridotto molto in base al tuo suggerimento.
Ottimizzatore

L' 2100uscita di input 2100-01-31 2100-02-28 2100-03-28 2100-04-25 2100-05-30 2100-06-27 2100-07-25 2100-08-29 2100-09-26 2100-10-31 2100-11-28 2100-12-26 2101-01-02è errata.
Qwertiy,

3

Rebol - 120 116 80 79 76

d: do join"1-1-"input print collect[for m 2 13 1[d/2: m keep d - d/weekday]]


Ungolfed + alcune annotazioni:

d: do join "1-1-" input         ;; golfy way to create Rebol date! datatype 1-Jan-(year)

print collect [
    for m 2 13 1 [              ;; loop thru months 2 to 13!
        d/2: m                  ;; move to (1st of) next month
        keep d - d/weekday      ;; collect/keep last sunday of month
    ]
]

Esempio di calcolo della domenica nella console di Rebol:

>> ; get last sunday of Jan 2014

>> d: 1-1-2014
== 1-Jan-2014

>> d/month: d/month + 1
== 2

>> d
== 1-Feb-2014

>> d/weekday
== 6

>> d - d/weekday
== 26-Jan-2014

>> ; above is last sunday of Jan 2014
>> ; and when pass end of year (ie. month 13!)

>> d/month: 13
== 13

>> d
== 1-Jan-2015

Potenziale 87: d: 1-1-1 d / anno: input print collect [ripeti m 12 [d / mese: m + 1 mantieni d - d / giorno della settimana]]
rgchris

@rgchris Grazie Chris. È stato in grado di radere altri 7 caratteri.
Draegtun,

Bello!! È brutto, ma non pensare mai a FOR come una scorciatoia.
rgchris,

2

CJam, 122 102 byte

30li:X400%){[1387Yb30f+~28I!I4%!I100%e&|g+\]W%{\_2$>7*-\7%7\m1$+}/}fI;]12/W=12,{101+s1>}%]z{X+W%'-*S}/

Questo non utilizza alcuna forma di libreria di date. Può anche essere ancora molto giocato a golf, credo.

Provalo qui.


3
Sono così incredibilmente entusiasta che una risposta CJam non è la risposta migliore in una sfida di code-golf per una volta. Posso morire felice .. Oggi è una buona giornata (fino a quando non è sceso a 6 byte, ovviamente)
Brandon,

@Brandon: quello era il tipo di motivo per cui pensavo fosse interessante. Spero davvero di vedere qualche meravigliosa biblioteca che lo rende facile, ma finora deluso.
Phil H,

1

R, 128 caratteri

P=paste;f=format;a=strptime(P(1:366,scan()),"%j %Y");cat(sort(sapply(split(a,f(a,"%B")),function(x)P(tail(x[f(x,"%u")==7],1)))))

Con interruzioni di riga:

P=paste
f=format
a=strptime(P(1:366,scan()),"%j %Y")
cat(sort(sapply(split(a,f(a,"%B")),function(x)P(tail(x[f(x,"%u")==7],1)))))

1

C # 255

Ungolfed

static void Main(string[] a)
    {
        int y = Int32.Parse(Console.ReadLine());
        DateTime d = new DateTime(y, 1, 1);
        while (d.Year == y)
        {
            if (d.DayOfWeek == DayOfWeek.Sunday && d.Day>(DateTime.DaysInMonth(y,d.Month)-7))
                Console.WriteLine(d.ToShortDateString());
            d = d.AddDays(1);
        }
        Console.ReadKey();
    }

Modifica: modificato per stampare solo l' ultima domenica :)


Non è il formato di output richiesto. + Questo è il codice golf
edc65

1

q, 67

{({{1<>x mod 7}-[;1]/x}')14h$1_til[13]+13h$"D"$(($)x),".01.01"}

Non ci sono librerie di date utilizzabili per questo in q?
Phil H,

1

"Oh, no, di nuovo lui!"

Java - 259 246 byte

void g(int y){for(int i=;i<12;i++){GregorianCalendar c=new GregorianCalendar(y,i,0);c.set(c.DAY_OF_WEEK,c.SUNDAY);c.set(c.DAY_OF_WEEK_IN_MONTH,-1);System.out.print(y+"-"+String.format("%02d",(c.get(c.MONTH)+1))+"-"+(c.get(c.DAY_OF_MONTH))+" ");}}

Versione non golfata:

void g(int y){
    for (int i = 0; i < 12;i++) {
        GregorianCalendar c = new GregorianCalendar(y, i, 0);
        c.set(c.DAY_OF_WEEK, c.SUNDAY);
        c.set(c.DAY_OF_WEEK_IN_MONTH, -1);
        System.out.print(y+"-"+String.format("%02d",(c.get(c.MONTH)+1))+"-"+(c.get(c.DAY_OF_MONTH))+" ");
    }
}

Uso:

import java.util.GregorianCalendar;
import java.util.Scanner;

public class LastSundayInYear {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Year?");
        int year = scanner.nextInt();
        LastSundayInYear sunday = new LastSundayInYear();
        sunday.g(year); 
    }

    void g(int y){
        for (int i = -1; ++i < 12;) {
            GregorianCalendar c = new GregorianCalendar(y, i, 0);
            c.set(c.DAY_OF_WEEK, c.SUNDAY);
            c.set(c.DAY_OF_WEEK_IN_MONTH, -1);
            System.out.print(y+"-"+String.format("%02d",(c.get(c.MONTH)+1))+"-"+(c.get(c.DAY_OF_MONTH))+" ");
        }
    }
}

Produzione:

2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28

Ancora un'altra risposta "mettiamo una risposta Java solo per calci". Oh bene. Ma, almeno, dato che ti sei preso la briga di raggiungere questo punto della mia risposta, cercherò di annoiarti ancora un po 'e di spiegare il mio ragionamento.

Il metodo griceve l'anno desiderato e, per ogni mese, crea un GregorianCalendaroggetto (i mesi vanno da 0 a 11). Quindi, il primo c.setimposta il giorno della settimana come una domenica e il secondo dichiara che vogliamo l' ultima settimana del mese, come mostrato nella documentazione ufficiale . Le System.out.printlnstampe fuori la data di quella Domenica (se stessimo facendo questo diritto, l'anno si sarebbe stampata come c.get(c.YEAR), ma utilizzando yancora una volta rade 13 caratteri), il mese deve essere formattato per aggiungere uno zero da gennaio a settembre (e la il valore viene incrementato perché, beh, i mesi qui sono rappresentati 0-11) e viene stampato il giorno dell'ultima domenica. E questa procedura si ripete per gli altri undici mesi.


0

C #, 212 , 237

string x(int y){var s="";var t="";var d=new DateTime(y,1,1);for(;;){if(d.Year!=y){return s;}t=(d.DayOfWeek==DayOfWeek.Sunday)?t=string.Format("{0}-{1}-{2} ",d.Year,d.Month,d.Day):t;s=(d.AddDays(1).Month!=d.Month)?s+=t:s;d=d.AddDays(1);}}

Con interruzioni di riga

string x(int y)
    {
        var s = "";
        var t = "";
        var d = new DateTime(y,1,1);
        for (;;)
        {
            if (d.Year != y) {
                return s;
            }
            t = (d.DayOfWeek == DayOfWeek.Sunday) ? t = string.Format("{0}-{1}-{2} ", d.Year, d.Month, d.Day) : t;
            s=(d.AddDays(1).Month!=d.Month)?s+=t:s;
            d=d.AddDays(1);
        }
    }

Uscita per il 2014

"2015-1-25 2015-2-22 2015-3-29 2015-4-26 2015-5-31 2015-6-28 2015-7-26 2015-8-30 2015-9-27 2015-10-25 2015-11-29 2015-12-27"

Non è il formato di output richiesto
edc65

Lì, riparato. Meglio?
Darren Breen,

0

C # 171

Funzione che restituisce una stringa.

string S(int y){var r="";for(int m=1;m<13;++m){var d=new System.DateTime(y,1,1).AddMonths(m).AddDays(-1);r+=y+string.Format("-{0:00}-{1} ",m,d.Day-d.DayOfWeek);}return r;}

Ungolfed

string S(int y)
{
    var r="";
    for (int m=1;m<13;++m)
    {
        var d = new System.DateTime(y, 1, 1).AddMonths(m).AddDays(-1);
        r += y + string.Format("-{0:00}-{1} ", m, d.Day - d.DayOfWeek);
    }
    return r;
}

0

C # 194

usando Linq:

string d(int y){return string.Join(" ",Enumerable.Range(1,12).Select(m=>new DateTime(y,m,DateTime.DaysInMonth(y,m))).Select(d=>d.AddDays(-(int)d.DayOfWeek)).Select(d=>d.ToString("yyy-MM-dd")));}

Ungolfed

string d(int y)
{
    return string.Join(" ",Enumerable.Range(1,12)
        .Select(m => new DateTime(y, m, DateTime.DaysInMonth(y, m)))
        .Select(d => d.AddDays(-(int)d.DayOfWeek))
        .Select(d => d.ToString("yyy-MM-dd")));
}

Produzione

2013-01-27 2013-02-24 2013-03-31 2013-04-28 2013-05-26 2013-06-30 2013-07-28 2013-08-25 2013-09-29 2013-10-27 2013-11-24 2013-12-29

0

Mathematica - 171

Avvolto in una funzione anonima, restituisce la stringa

StringJoin[Last@#~DateString~{"Year","-","Month","-","Day"," "}&/@GatherBy[Select[DateRange[DateObject[{#}],DateObject[{#+1}]],DayName@#==Sunday&],DateValue[#,"Month"]&]]&

Primo golf matematico. Sento che potrebbe essere sostanzialmente ridotto.


0

VB-192

Function z(y)
For i = 1 To 11
a = 0
s = IIf(i <> 11, DateSerial(y, i + 1, 1), DateSerial(y + 1, 1, 1))
While Weekday(s - a) <> 1
a = a + 1
Wend
r = r + Str(s - a) + " "
Next
z = r
End Function

Potrebbe essere peggio ^^

La mia seconda e ultima voce (non credo di poterla ridurre)

142

Function z(y)
Dim m(12)
For i = 1 To 366
s = DateSerial(y, 1, 1) + i
If Weekday(s) = 1 Then m(Month(s)) = s
Next
z = Join(m, " ")
End Function

0

Rubino 76

Utilizza un parametro da riga di comando ruby sundays.rb 1900. Utilizza la libreria Data.

require'date';puts (1..12).map{|m|d=Date.new($*[0].to_i,m,-1);d-d.wday}*" "
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.