Quando è il Ringraziamento?


38

sfondo

Alcune festività hanno date fisse e facili da ricordare, come il 31 ottobre, il 25 dicembre, ecc. Alcune, tuttavia, vogliono essere problematiche. Sono specificati come "il primo lunedì di settembre" o "il quarto giovedì di novembre". Come dovrei sapere quando è?

Tutto quello che so è che il Ringraziamento si sta avvicinando rapidamente, quindi ho bisogno di un programma che mi aiuti a capire quando lo è. Alcuni sostengono addirittura che è domani , quindi il tuo programma deve essere il più breve possibile per essere sicuro di poterlo digitare nuovamente in tempo.

La sfida

Creare un programma o una funzione che, dato un anno a quattro cifre (ad esempio 2015 o 1984), produca o restituisca la data del Ringraziamento degli Stati Uniti in quell'anno. Il Ringraziamento è definito come il quarto giovedì di novembre secondo la pagina di Wikipedia . (Suggerimento: quella pagina include anche alcune informazioni interessanti sull'andamento della data.)

Input : un numero decimale con un massimo di quattro cifre che rappresentano un anno nell'era comune (CE). Esempi: 987, 1984, 2101

Risultato : la data, incluso il mese e il giorno, in cui cade il Ringraziamento, o cadrebbe se esistesse, in quell'anno. Questo può essere in qualsiasi formato ragionevole; usa il tuo miglior giudizio. Usa il calendario gregoriano in tutti i casi, anche se non era in uso al momento.

(Nota: assicurati di gestire correttamente gli anni bisestili!)

Casi di test Ingresso 1:

2015

Uscita 1:

Nov 26

Ingresso 2:

1917

Uscita 2:

Nov 22

punteggio

Le iscrizioni verranno classificate in byte . Consiglio questo sito Web per tenere traccia del numero di byte, sebbene sia possibile utilizzare qualsiasi contatore desiderato.

bonus

-25% al tuo punteggio se gestisci le date BCE come numeri negativi (ad esempio, -480 sarebbe l'anno della battaglia delle Termopili).

Input del caso di test negativo:

-480

Uscita corrispondente:

Nov 25

Questo è , quindi vince il punteggio più basso!

Modifica: sto contrassegnando l'invio TI-BASIC di Thomas Kwa come accettato. Non lasciarti scoraggiare dal presentare nuove voci!

Classifiche

Ecco uno snippet di stack per generare sia una classifica regolare che una panoramica dei vincitori per lingua.

Per assicurarti che la tua risposta venga visualizzata, ti preghiamo di iniziare la risposta con un titolo, usando il seguente modello Markdown:

# Language Name, N bytes

dov'è Nla dimensione del tuo invio. Se si migliora il punteggio, è possibile mantenere i vecchi punteggi nel titolo, colpendoli. Per esempio:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Se si desidera includere più numeri nell'intestazione (ad es. Perché il punteggio è la somma di due file o si desidera elencare separatamente le penalità del flag dell'interprete), assicurarsi che il punteggio effettivo sia l' ultimo numero nell'intestazione:

# Perl, 43 + 2 (-p flag) = 45 bytes

Puoi anche rendere il nome della lingua un collegamento che verrà quindi visualizzato nello snippet della classifica:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes


25
Per chiunque si stia chiedendo quando arriverà il Ringraziamento quest'anno: il Ringraziamento sarà domani.
TheNumberOne il

6
Ma ho avuto il ringraziamento il 10 ottobre? Mi dispiace dire che la tua domanda è in ritardo.
JimmyJazzx,

5
@Downgoat Usa il contatore di byte che desideri. Questo è solo quello che uso personalmente e lo consiglierei.
bkul

22
"Alcune festività hanno date fisse e facili da ricordare, come il 31 ottobre, il 25 dic" Questi esempi sono facili da ricordare perché sono davvero lo stesso giorno: ottale 31 == decimale 25. ;-)
Adrian McCarthy

7
Per una risposta che fa il bonus, dovrebbe esserci un anno 0 tra -1 e 1 o no?
febbraio

Risposte:


40

TI-BASIC, 15 byte * 0,75 = 11,25

Testato sul mio calcolatore TI-84 +

1129-dayOfWk(Ans+ᴇ4,9,1

Il Ringraziamento è il 29 novembre, meno il giorno della settimana del 1 ° settembre, dove 1 è domenica e 7 è sabato. Questo produce nel formato MMDD.

Casi di test: 2015-> 1126, 1917-> 1122, -480-> 1125sono stati verificati. TI-BASIC sembra usare il calendario gregoriano per tutte le date.

TI-BASIC non supporta gli anni negativi, ma questo ottiene il bonus perché aggiungiamo 10000 all'input. Poiché il calendario gregoriano ha un periodo di 400 anni, questo non cambia il giorno della settimana.


5
Merda santa. xD Non avrei mai pensato che avrebbe funzionato così, +1.
Addison Crump,

Buona idea per aggiungere 10000. Bello.
agtoever,

Conto 23 lettere. Come possono essere 15 byte?
Stephan Schinkel,

1
@StephanSchinkel TI-BASIC utilizza token che sono memorizzati nella memoria dei calcolatori, credo che tutti i caratteri qui siano 1 byte tranne i token dayofWK(e Ansche sono 2 e 1 byte ciascuno.
FryAmTheEggman,

L'hai provato su una calcolatrice? Wow.

23

PHP, 65 48 42 41 36 (+2 per -F) = 38 byte

<?date(Md,strtotime("4thuXI$argn"));

Accetta l'input come primo argomento della riga di comando. Funziona con avvisi, che sono accettabili dalle nostre regole. Stampe NovDD, dov'è DDil giorno del Ringraziamento.

Nessun collegamento online perché ideone non supporta gli argomenti della riga di comando e non conosco un interprete online che lo faccia.

Grazie ad Alexander O'Mara per avermi insegnato un nuovo trucco e primo per una riduzione significativa


2
Questo è più divertente di Mathematica.
lirtosiast

2
@Tryth ancora più breve: "4thuXI". Puoi anche eliminare lo spazio tra l'anno "4thuXI2015".
Alexander O'Mara,

1
Utilizzando l'opzione della riga di comando -F, è possibile accorciare l'input "4thuXI$argn".
primo

3
Aspetta, funziona davvero? Questo è ... questo è solo ... Io nemmeno ...
ETHproductions

1
Funziona per me . Mentre ci sono, Mdnon ha bisogno di virgolette, con E_NOTICEdisabilitato.
primo

18

Mathematica, 59 38 byte

DayRange[{#,11},{#,12},Thursday][[4]]&

+1 intelligente. C'è anche WolframAlpha["Thanksgiving " <> #] &dove la data è inserita come una stringa.
DavidC,

WolframAlpha restituisce le date del Giorno del Ringraziamento degli Stati Uniti dal 1863 (quando Lincoln dichiarò che era l'ultimo giovedì di novembre) in poi. Gli Stati Uniti osservano il Ringraziamento dal 1789.
DavidC

@DavidCarraher Tuttavia, l'OP afferma che il programma deve funzionare per almeno 0 - 9999 CE
LegionMammal978

17

JavaScript (ES6), 42 40 31 byte - 25% = 23,25

a=>28.11-new Date(a,8).getDay()

Poiché la data "può essere in qualsiasi formato ragionevole", questa funzione utilizza DD.MM. Ho scritto una risposta TeaScript con una tecnica diversa, ma questa formula era più breve.

Spiegazione

Poiché i mesi sono basati su zero, new Date(a,10)restituisce un Dateoggetto che rappresenta il 1 ° novembre dell'anno specificato.

Dato che getDay()restituisce un numero che rappresenta il giorno della settimana da 0..6cui vogliamo mappare

Su Mo Tu We Th Fr Sa 
0  1  2  3  4  5  6  
to to to to to to to
4  3  2  1  0  6  5  

quindi aggiungi 22. Si scopre che (11 - new Date(a,10).getDay()) % 7farà il trucco. Come ha sottolineato @Thomas Kwa , questo è lo stesso 28-new Date(a,8).getDay()che è 28 meno il giorno della settimana del 1 settembre.


Bella soluzione, adoro quanto sia breve e che sia ancora più comprensibile della maggior parte delle voci.
Marko Grešak,

16

Japt , 43 37 36 35 29 byte - 25% = 21,75

Japt è una versione abbreviata di Ja vaScri pt .

`{28.11-?w D?e(U,8).getDay()}

Hahaha, ho trovato un trucco davvero economico: l'interprete ignora tutte le parentesi all'interno delle stringhe (utilizzate per inserire il codice) mentre le decomprime, quindi possiamo comprimere l'intero codice sorgente per salvare un byte>: D

I due ?s dovrebbero essere gli Unicode non stampabili U + 0098 e U + 0085, rispettivamente. Provalo online!

Dopo la decompressione, il codice valuta questo:

"{28.11-new Date(U,8).getDay()}"

Che valuta a:

""+(28.11-new Date(U,8).getDay())+""

Che dà l'output corretto.

Utilizza la tecnica di intrepidcoder , producendo in formato dd.mm. Supporta correttamente gli anni negativi. Suggerimenti benvenuti!

Modifica: a partire dal 2 dicembre, ora puoi utilizzare questo codice a 11 byte (segnando 8,25 punti ):

28.11-ÐU8 e

(Vorrei tanto averlo implementato prima!)


Molto ben fatto.
bkul,

Questo è ora più lungo di JavaScript vaniglia. Thomas Kwa ha una formula molto più breve .
intrepidcoder il

@intrepidcoder Grazie, risolto.
ETHproductions

12

Vitsy , 44 byte

Sto calcolando con pura matematica !

golfed:

Ve2 * V2-V41m + Vaa * Dv1m-VV4 * 1m + 7M-baa * / + N
/ D1M-

Ungolfed (ha spostato la chiamata del metodo sulla prima riga per renderla leggibile):

Ve2 * V2-V4 / D1M- + Vaa * Dv / D1M - VV4 * / D1M- + 7M-baa * / + N

V Salvare l'input come variabile finale.
 e2 * Spingi 28 nello stack.
    V Inserire l'ingresso nello stack.
     2- Sottrai due.
       V4 / D1M- Ottieni piano (input / 4).
              + Aggiungilo al totale.
               Vaa * Dv / D1M- Ottieni piano (input / 100) e risparmia 100 come temp
                                    variabile nel processo.
                          - Sottrai dal totale.
                           Vv4 * / D1M- Ottieni piano (input / 400).
                                    + Aggiungilo al totale.
                                     Modulo 7M per sette.
                                       - Sottrai il risultato da 28.
                                        baa * / + Aggiungi .11
                                              N Uscita come numero.

Probabilmente esiste un algoritmo migliore per questo (e questo è probabilmente orribile da golf), ma per quelli che si chiedono, il mio algoritmo viene da qui .

Provalo online!

Ricevo punti bonus per calcolarlo e avere esattamente 42 byte? Sogni rovinati.

Grazie a @ Hosch250 per aver sottolineato che stavo sbagliando. : D Risolto.


2
No. ma ricevi un +1 da me;)
Conor O'Brien,

Dice che il Ringraziamento nel 2016 è il 28 novembre. È davvero il 24 novembre.
Hosch250,

@ Hosch250 Hai ragione - risolto ora.
Addison Crump,

10

Python, 38 * 0,75 = 28,5 byte

lambda x:28.11-(x-2+x/4-x/100+x/400)%7

Questo funziona con anni negativi nel modo specificato nella domanda, anche se mi viene in mente che non c'è anno 0 nel calendario gregoriano, quindi questo comportamento è un po 'sospetto.


1
Puoi lasciar perdere f=.
febbraio

1
Come funziona con date negative? Modulo in Python si applica ai negativi? : O
Addison Crump,

Dovrebbe essere più breve usare ripetizioni di stringa,"Nov "+`...`
xnor

@VoteToClose Python modulo fornisce una risposta con lo stesso segno del secondo argomento. Quindi -40%7==2ma-40%-7==-5
quintopia,

@quintopia Aspetta, aspetta, sono un idiota. Va bene. Ciò ha senso.
Addison Crump,

10

JavaScript (ES6), 43.5

Il conteggio dei byte effettivi è 58. Si applica il bonus del -25% => 58 * 0,75 = 43,5

s=>new Date(s,10,(a=new Date(s,10).getDay())<5?26-a:a+21)

Modo abbastanza dritto e sciocco come potrebbe essere, senza soluzioni complicate o calcoli.

De-golf (ES5) + demo:

function t(s) {
    a = new Date(s, 10).getDay();
    alert(new Date(s,10,a<=4?26-a:a+21))
}

t(prompt())

Si noti che l'inserimento dell'anno 0-100 produce l'anno 1900-2000. Tuttavia, sembra che 0-100 anni diano la stessa data del 1900-2000, a giudicare dalle altre risposte.


Sostituendo a+18con 22, perché viene chiamato solo in "else", e "else" si verifica solo se a non è né maggiore né minore di 4, ovvero esattamente 4.


Sostituzione a<4?26-a:a>4?a+21:22cona<=4?26-a:a+21


2
Scusami se sbaglio, ma non è a<4?x:a>4?y:a+18equivalente a a<4?x:a>4?y:22?
ETHproductions

A proposito, mi dice l'anno sbagliato per qualsiasi input da 0 a 99. Non sono sicuro che sia importante, però.
ETHproductions

@Eth LOL ovviamente hai ragione, non pensavo che fosse sempre 4 + 18: D
nicael

@Eth hm, da 0 a 99 è davvero sbagliato, lasciami provare a risolverlo.
nicael

@Eth Sembra che 0-100 diano la stessa data che 1900-2000, a giudicare dalle altre risposte.
nicael

8

TeaScript, 35 33 24 byte - 25% = 18

28.11-new D(x,8).getDay¡

Questo è lo stesso metodo della mia risposta JavaScript , che utilizza la formula intelligente di Thomas Kwa .

Versione alternativa con spiegazione

r(22,28)F(#/h/t(new D(x,10,l)))+'-11'

r(22,28)    // Range from 22 to 28
        F(    // filter, keeps elements for which the function returns true. 
          #    // Expands to function(l,i,a,b)
           /h/    // RegExp literal, Thursday is the only day with an 'h'.
              t(    // test, true if date string contains an 'h'.
                new D(x,10,l) // Create date object
                             ))+'-11' // Append '-11' for the month.

Sono 35 caratteri, ma 36 byte a causa di ¡:)
nicael

@nicael Non da questo sito , non lo è;)
ETHproductions

Hm, ottenendo 36 con mothereff.in/… .
nicael

@Downgoat di solito utilizza questo formato , in cui tutti i caratteri fino a U + 00FF sono 1 byte.
ETHproductions

5

Jython, 141 155 byte

Utilizza le classi Calendario e Scanner Java con sintassi Python.

import java.util.Scanner as s;import java.util.Calendar as c
d=c.getInstance();k=s(System.in);d.set(c.YEAR,k.nextInt());d.set(c.DAY_OF_WEEK,c.THURSDAY)

Modificare: problemi di sintassi minori, aggiunti 14 byte.

Vedi anche la mia versione di Brainfuck .


5

Python, 83 81 78 byte

from datetime import*
lambda a:'Nov '+`((10-datetime(a,11,1).weekday())%7)+22`
  • -2 byte: aggiunto un nome da importare (grazie @ Κριτικσι Λίθος)
  • -1 byte: modificato in * import ** (grazie @FryAmTheEggman)
  • -2 byte: modificato in repr per convertire il giorno (grazie @willem)

1
Solo un suggerimento per ridurre il conteggio dei byte: usa import datetime as de poi puoi usarlo dper ogni volta che usi datetimenel tuo programma.
Kritixi Lithos,

2
Potresti anche provare i panda. import pandas;print'Nov '+`((10-pandas.datetime(input(),11,1).weekday())%7)+22`
Willem,

@ ΚριτικσιΛίθος ma poi datetime.datetime sarebbe solo d.datetime, no?
TanMath,

2
from datetime import*è anche un po 'più breve, poiché non ti servirà d.più
FryAmTheEggman

5

Excel, 367 154 53 - 25% = 39,75 byte

Suppone che l'anno si tenga nella cella A1, nel formato data. Restituisce il numero intero del giorno di novembre in cui si tiene il Ringraziamento.

Questo spiega solo i normali anni bisestili. Non tiene conto del fatto che gli anni 2100, 2200, 2300 non sono anni bisestili.

Questo è progettato per funzionare solo dal 1621 in poi, cioè da quando il Ringraziamento ha iniziato a essere celebrato. (Anche se sicuramente funzionerà fino allo 0 d.C.).

=IF(MOD(YEAR(A1),4)=0,IF(WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,1127-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),1134-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))),IF(WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,1127-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),1134-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))))

Pretty-stampati:

=IF(MOD(YEAR(A1),4)=0,
    IF(WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,
       1127-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),
       1134-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))),
    IF(WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,
       1127-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),
       1134-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))))

Gah! Invece di calcolare in base al 1 ° gennaio, quindi fare molti calcoli per l'anno bisestile per far fronte al 29 febbraio, avrei dovuto basare i calcoli al 1 ° novembre. Questo ora tratta correttamente con gli anni 2100, 2200 e 2300 , ma rende l'implementazione dipendente dal formato data predefinito dell'installazione di Excel. Questa versione è progettata per gg / mm / aaaa:

 =IF(WEEKDAY(DATEVALUE(("01/11/"&TEXT(C1,"yyyy"))))<6,  
     1127-WEEKDAY(DATEVALUE(("01/11/"&TEXT(C1,"yyyy")))),
     1134-WEEKDAY(DATEVALUE(("01/11/"&TEXT(C1,"yyyy")))))

E ora che ho fatto il pfaffing per ottenere un calcolo conciso in Smalltalk, il backport in Excel porta a:

=DATE(A1,11,MOD(12-WEEKDAY(DATE(9600+A1,11,1)),7)+22)

(con l'anno ancora in A1, ma come un numero intero). Funziona anche per gli anni 2100, 2200 e 2300, per tutte le date dal 7700 aC / E in poi, usando il trucco di ripetizione della data di Thomas Kwa.


1
Quando provo questo con date precedenti al 1900 non funziona nella mia copia di Excel.
Angelo Fuchs,

Anche la versione lunga non funziona.
Angelo Fuchs,

Per le date precedenti, utilizzare la cartella di lavoro Date pre-1900 dell'utente di Excel. < exceluser.com/downloads/examples/post_900_123/index.html >
Euan M

Domande sul fatto che questo funzioni a parte, non penso che tu sia autorizzato a produrre solo la data di novembre; hai bisogno di "Nov" o "11" in qualche modo.
Lirtosiast

@Thomas Kwa L'inserimento della data è l'anno, nel formato della data. Il calcolo quindi determina il giorno della settimana in cui cade il 1 ° novembre, quindi calcola in quale data è il quarto giovedì di novembre.
Euan M,

4

PowerShell, 67 64 84 72 58 45 byte

param($a)'Nov';28-(date "00$a/9/1").DayOfWeek

Prendiamo il nostro intero di input come $a, e immediatamente output Nove una nuova riga. Quindi lo prendiamo $ae lo anteponiamo con zero e il 1 settembre con 00$a/9/1prima di generare un nuovo datee determinare di cosa si DayOfWeektratta. Se il 1 ° settembre è di domenica ( .DayOfWeekuguale a 0), il Ringraziamento è il 28. Se il 1 ° settembre è di lunedì ( .DayOfWeekuguale a 1), il Ringraziamento è il 27. E così via. Pertanto, sottraggiamo quel giorno della settimana da28 dall'output della nostra risposta.

Preparazione con conti a doppio zero per anni a una o due cifre senza interrompere l'analisi per anni a tre o quattro cifre. Non funziona con numeri negativi, poiché .NET datetimenon supporta anni in meno di 0.

Grazie a TessellatingHeckler e Toby Speight per l'assistenza in merito.


"{0:D3}/Nov/$_" -f $aè più breve di "$($a.ToString("000"))/Nov/$_"e produce lo stesso risultato e penso che potresti usare 11invece diNov
n0

@ n0rd Ah, eccellente! Sì, Novera un residuo di quando stavo cercando di far riconoscere correttamente gli anni a due cifre, quindi lo sostituirò anche io. Grazie!
AdmBorkBork,

@TessellatingHeckler Questo approccio funziona, ma devi anteporre due zeri per tenere conto degli anni a una cifra, altrimenti tornerai alla 20XX in cui mi sono imbattuto. Grazie per l'assistenza - ho aggiornato la risposta.
AdmBorkBork,

1
@TessellatingHeckler Sul mio sistema, almeno, inserendo anni a una cifra in date "11/1/$a"risultati Thursday, November 1, 2007 12:00:00 AM. Questo perché non stiamo modificando la proprietà Calendar.TwoDigitYearMax , quindi quando analizza , siamo bloccati con il doppio zero per ovviare a questo.
AdmBorkBork,

Giusto giusto. È una doppia imbottitura.
TessellatingHeckler,

3

Golfscript, 25 * 0,75 = 18,75 byte

~.4/.25/.4/2---+7%28\--11

Questo utilizza la formula di Sakamoto per il giorno della settimana. Dal momento che ci sono persone che lo fanno, l'output è sotto forma di dd-mm. La mia presentazione precedente può essere trovata di seguito:

~.4/.25/.4/2---+7%"Nov "28@-

3

TSQL, 478 296 byte

Solo per divertimenti. In genere, avresti una tabella dimensionale della data per renderlo sempliceselect * from dimDate where [Year] = @Year and [Holiday] = 'Thanksgiving' ma in assenza di ...

create function a(@y varchar(4))returns date as begin declare @d date,@i int=0 set @d=convert(date,@y+'-11-01')declare @t table(d date,c int identity)while @i<28 begin if datepart(weekday,@d)=5 insert @t(d) select @d select @d=dateadd(d,1,@d),@i+=1 end select @d=d from @t where c=4 return @d end

Ungolfed:

if exists(select * from sys.objects where name='a' and [type]='FN') drop function a
go

create function a(@y varchar(4))returns date
-- select dbo.a('2015')
as
begin
    declare @d date,@i int=0;

    set @d=convert(date,@y+'-11-01'); -- cannot golf out dashes for dates <year 1000

    declare @t table(d date,c int identity)

    while @i<28 
    begin -- populate "November" array
        if datepart(weekday,@d)=5 insert @t(d) select @d -- assumes @@datefirst = 7
        select @d=dateadd(d,1,@d),@i+=1
    end;

    select @d=d from @t where c=4 

    return @d

end

È davvero il modo più breve?
lirtosiast,

Suppongo che potrei non avere familiarità con le regole del codice golf, ma la risposta crea un oggetto DB che accetta input e restituisce output in modo che corrisponda all'OP. C'è un accorciamento evidente che potrebbe verificarsi se l'input può essere accettato nel codice inline, ma questo era il mio pensiero per il tipo di oggetto funzione. Sono sicuro che potrebbe essere ulteriormente golfato in entrambi i casi. @ThomasKwa, hai suggerimenti?
Peter Vandivier,

Bene, mi sembra che potresti usare la formula di matematica pura che menziona questa risposta e non preoccuparti di tutto ciò che è datato.
lirtosiast,

not strictly a pure-math solution, but reading that answer definitely gave me some ideas to golf out 200 characters. Thanks!!
Peter Vandivier

(I meant (28 - ( x - 2 + floor(x / 4) - floor(x / 100) + floor(x / 400) ) % 7) Yeah, reading other answers tends to help a lot.
lirtosiast

3

Pyth, 30 28 * 75% = 21 bytes

I'm 100% positive that this could be made shorter, but hey, it's my first Pyth program! \o/

-28.11%+-+-Q2/Q4/Q100/Q400 7

Test suite

Outputs the date in dd.mm format.

Please suggest ways to golf this if you can! I'd like to learn more about Pyth.


2

Excel, 64 48

Year in A1

=DATE(A1,11,CHOOSE(WEEKDAY(DATE(A1,11,1)),26,25,24,23,22,28,27))

=DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22)

As Excel is localization based and I would like to test this. Please explain what the functions do, so I can select the proper one in my language.
Angelo Fuchs

1
Also, this doesn't work for dates prior to 1900 (at least in my copy of Excel)
Angelo Fuchs

Also, you saved 13 bytes on TEXT from =TEXT(DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22),"d mmm") - the output is an integer without formatting.
user3819867

@user3819867, that's how excel stores its dates. formatting is left up to the user
SeanC

@AngeloFuchs, DATE returns a date value, using year, month, day as parameters. MOD returns the remainder part of a division (modulus). WEEKDAY returns the day of week of a date (1=Sunday, 2=Monday, etc).
SeanC

2

Befunge, 41 Bytes

47*&:::4"d"*/\"d"/-\4/++5+7%-" voN",,,,.@

Run on this interpreter.

Explanation: A common year is 365 = 1 mod 7 days, so the year plus every 4th year, minus every 100th (d in ascii) year, plus every 400th years accounts for any leap days (including the present year). The result of :::4"d"*/\"d"/-\4/++ can then be thought of as March 5th, the first day after February to fall on the same day as the first day of the year in common years. After that we calibrate to the pattern with 5+7%- subtracting a number of days of the week from the 28th(the 47*stored earlier) of November. Then print.

A version correcting for B.C. years is currently longer than the bonus provides for, at 59 -25% = 44.25 bytes:

47*&v
!`0:<+*"(F"_v#
" voN",,,,.@>:::4"d"*/\"d"/-\4/++5+7%-

2

Matlab, 78 bytes

x=find(all(bsxfun(@eq,datestr(datenum(input(''),11,1:30),'ddd'),'Thu')'));x(4)

2

Ruby, 60 58 57 * 0.75 = 42.75 bytes

->y{puts"Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"}

58 bytes

->y{puts "Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"}

60 bytes

->y{puts "Nov #{[5,4,3,2,1,7,6][Time.new(y,11,1).wday]+21}"}

Ungolfed:

-> y {
  puts "Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"
}

Usage:

->y{puts"Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"}

=> Nov 26

0

VBA, 124 bytes * 75% = 93 bytes

Function e(y)
For i = 1 To 7
x = DateSerial(y, 11, 21) + i
If Weekday(x) = 5 Then e = Format(x, "mmm dd")
Next
End Function

I'm not sure if spaces count, it's somewhere between 102 and 124, feel free to edit.
If integers are a valid output I'm more than happy to remove the Format part.


Spaces count; if they're unnecessary to the program you can remove them though.
lirtosiast

0

PHP 5.3+, 59 bytes

This uses PHP builtin function strtotime to parse the date.

<?=gmdate('M d',strtotime("Next Thursday $_GET[Y]-11-19"));

This expects the value to be passed over GET parameter Y OR over php-cli Y=<year>.

It tries to find the next thursday after 19th November.
So far, with the tests I've made, it works fine.

Be aware that 2-digit years may be interpreted differently.

I use gmdate to avoid timezone issues, but it works equally well using date (at least, where I live).


1
An answer is not an appropriate place to discuss the validity of an input method. I've created this option in the default I/O meta post (so the community can vote on it) and moved your conversation to chat. (CC @Mego)
Dennis

0

T-SQL 215 bytes 248 * 0.75 = 186 bytes

create function t(@y int)returns table return select x=convert(char(6),x,107)from(select x=cast(dateadd(dd,d,dateadd(yy,@y-2015+7600,'20151101'))as date)from(select d=21+n from(values(0),(1),(2),(3),(4),(5),(6))b(n))c)t where datepart(weekday,x)=5

Ungolfed

set nocount on;
if object_id('dbo.t') is not null drop function dbo.t
go

create function t(@y int)returns table return
    select x=convert(char(6),x,107)
    from (
        select
        x=cast(dateadd(dd,d,dateadd(yy,@y-2015+7600,'20151101'))as date)
        from (
            select d=21+n 
            from (values (0),(1),(2),(3),(4),(5),(6))b(n)
        )c
    )t
    where datepart(weekday,x)=5
go

which with this test scaffold

select 
  [ 2015 = Nov. 26]=(select x from dbo.t( 2015))
 ,[ 1917 = Nov. 22]=(select x from dbo.t( 1917))
 ,[ 1752 = Nov. 23]=(select x from dbo.t( 1752))
 ,[ 1582 = Nov. 25]=(select x from dbo.t( 1582))
 ,[ 1400 = Nov. 27]=(select x from dbo.t( 1400))
 ,[ -480 = Nov. 25]=(select x from dbo.t( -480))
 ,[-5480 = Nov. 28]=(select x from dbo.t(-5480))
;
go

yields as desired

2015 = Nov. 26  1917 = Nov. 22  1752 = Nov. 23  1582 = Nov. 25  1400 = Nov. 27  -480 = Nov. 25 -5480 = Nov. 28
--------------- --------------- --------------- --------------- --------------- --------------- ---------------
Nov 26          Nov 22          Nov 23          Nov 25          Nov 27          Nov 25          Nov 28

0

Pike, 87 91 107 77 76 bytes - 25% = 57

string t(int y){return"Nov "+((11-Calendar.Day(y,11,1)->week_day())%7+22);}

leaving the old one in for comparison because i find it more clever in terms of taking advantage of the Calendar module, but the above is way shorter.

string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();}

This doesn't seem to take input.
Peter Taylor

yeah, i got confused by that, some solutions have a function definition and some just use a variable that is not defined anywhere, so i am not sure what i am supposed to use for the bytecount.
eMBee

I think that the answers which you see as using "a variable that is not defined anywhere" are actually using a very short function declaration syntax. There are one or two answers which use esolangs which have special treatment for stdin and so favour writing full programs. I don't know Pike, but if you can remove whitespace and abbreviate the function name to get string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();} then I count that as 107 bytes.
Peter Taylor

i thought i had seen a few that weren't function declarations, but they appear to have been fixed, only the smalltalk example doesn't fit. if that is valid i could shave another 17 bytes of this one...
eMBee

The Smalltalk version is written as a program - specifically a Workspace expression. We were told we are given an input, rather than soliciting input.
Euan M

0

Smalltalk - Squeak and Pharo, 69 57 54 49 35 34 33 32 - 25% = 24 bytes

"Nov nn": 69B 49B (-25% = 36.75B)
11nn (anInt): 57 54 32B (-25% = 24B)

"Year supplied as an integer value, y  
 Result provided as an integer value, 11nn
 Methods Date>>y:m:d: and >>w created as duplicates 
 of year:month:day and weekdayIndex"
(12-(Date y:y m:11d:1)w)\\7+1122

Previous versions

11nn output

"Year supplied as an integer value, y  
 Result provided as an integer value, 11nn"
(12-(Date year:y month:11 day:1) weekdayIndex)\\7+1122

"Year supplied as an integer value, y  
 Result provided as an integer value, d, prefixed by 11"
d:=(12-(Date year:y month:11 day:1) weekdayIndex)\\7+1122

Nov nn output

"Year supplied as an integer value, y  Result provided as a string, 'Nov nn'"
'Nov ', (12-(Date year:y month:11 day:1) weekdayIndex\\7+22) asString

nn output

"Year supplied as an integer value, y  Result provided as an integer value, d"
d:=(12-(Date year:y month:11 day:1) weekdayIndex)\\7+22

n.b. This is provided as a program - specifically a Workspace expression - rather than as a method.

It assumes the input is a given (as per the phrasing "given an up-to-four-digit year".
Including the declaring and giving of the input would add another 11 characters:

|y|y:=2015.(12-(Date y:y m:11 d:1)w)\\7+1122

Thanks to eMBee, for showing how to remove yet one more char - the whitespace immediately before the 'w'.

Actually, that inspired me to try removing the whitespace before 'd:' :
|y|y:=2015.(12-(Date y:y m:11d:1)w)\\7+1122
Which worked!


As per the OP's clarification, the day number version is not valid.
Mego

I agree - but given there are quite a few day-number-only versions in the list, I put it there for an apples-to-apples comparison
Euan M

0

GNU coreutils, 35 bytes

seq -f$1-11-2%g 2 8|date -f-|grep h

Simply searches the week 22-28 November for a Thursday. Run it in a C or POSIX locale, as I depend on Thursday being the only day abbreviation to contain a 'h'.


Here's a cleverer answer, albeit a byte longer:

echo Nov $((28-`date -d$1-5-5 +%w`))

We retrieve the day-of-week number of a date in a fairly arbitrary week between March and September (so day and month are one digit each, and we're not affected by a possible leap day). We pick the day so that it's a Sunday (%w==0) when Thanksgiving is on the 28th. We can then subtract that value from 28 to obtain the appropriate Thursday.


2
This works unless Sean Connery runs it.
bkul

0

TSQL, 53 52 bytes

DECLARE @ CHAR(4)=2000

PRINT DATEADD(d,59,DATEDIFF(d,1,DATEADD(m,9,@))/7*7)

Fiddle

Calculating monday before or on september 2nd and adding 59 days

(better than calculating monday before or on october 4th and adding 31 days because october is the 10th month thus saving 1 byte)


-1

Perl, 92 bytes

use Time::Local;(localtime(timelocal 0,0,0,$_,10,$ARGV[0]))[6]==4?print "Nov $_":0for 22..28

EDIT : Fixed output format, fixed bug e.g. 2012 result, used shorter "for" format. Thanks to msh210.


This is shorter and does the same thing: use Time::Local;(localtime(timelocal 0,0,0,$_,10,$ARGV[0]))[6]==4?print:0for 22..29. But both scripts suffer from the same flaws: (1) they don't print a representation of the month as required; (2) they have the wrong output for e.g. 2012.
msh210
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.