Wann ist Erntedankfest?


38

Hintergrund

Einige Feiertage haben feste, leicht zu merkende Daten, wie der 31. Oktober, der 25. Dezember usw. Einige möchten jedoch problematisch sein. Sie sind angegeben als "der erste Montag im September" oder "der vierte Donnerstag im November". Woher soll ich das wissen?

Alles was ich weiß ist, dass Thanksgiving sich schnell nähert, also brauche ich ein Programm, um herauszufinden, wann es ist. Einige Leute sagen sogar, dass es morgen ist , daher muss Ihr Programm so kurz wie möglich sein, damit ich es rechtzeitig erneut eingeben kann.

Die Herausforderung

Erstellen Sie ein Programm oder eine Funktion, die bei einem bis zu vierstelligen Jahr (z. B. 2015 oder 1984) das Datum des Erntedankfestes der Vereinigten Staaten in diesem Jahr ausgibt oder zurückgibt. Thanksgiving ist laut Wikipedia der vierte Donnerstag im November . (Hinweis: Diese Seite enthält auch einige interessante Informationen zum Datumsmuster.)

Eingabe : Eine Dezimalzahl mit maximal vier Stellen, die ein Jahr in der Common Era (CE) darstellt. Beispiele: 987, 1984, 2101

Ausgabe : Das Datum, einschließlich Monat und Tag, an dem Thanksgiving in diesem Jahr fällt oder fallen würde, wenn es existiert. Dies kann in jedem vernünftigen Format erfolgen. Verwenden Sie Ihr bestes Urteilsvermögen. Verwenden Sie in jedem Fall den Gregorianischen Kalender, auch wenn er zu diesem Zeitpunkt nicht verwendet wurde.

(Hinweis: Achten Sie darauf, Schaltjahre richtig zu behandeln!)

Testfälle Eingang 1:

2015

Ausgang 1:

Nov 26

Eingang 2:

1917

Ausgang 2:

Nov 22

Wertung

Einsendungen werden in Bytes gewertet . Ich empfehle diese Website , um die Anzahl Ihrer Bytes im Auge zu behalten, obwohl Sie jeden beliebigen Zähler verwenden können.

Boni

-25% auf Ihre Punktzahl, wenn Sie BCE-Daten als negative Zahlen behandeln (z. B. -480 wäre das Schlachtjahr von Thermopylae).

Negative Testfälleingabe:

-480

Entsprechende Ausgabe:

Nov 25

Das ist , also gewinnt die niedrigste Punktzahl!

Bearbeiten: Ich markiere Thomas Kwas TI-BASIC-Einsendung als akzeptiert. Lassen Sie sich davon nicht abhalten, neue Einträge einzureichen!

Bestenlisten

Hier ist ein Stack-Snippet, um sowohl eine reguläre Rangliste als auch eine Übersicht der Gewinner nach Sprache zu generieren.

Um sicherzustellen, dass Ihre Antwort angezeigt wird, beginnen Sie Ihre Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:

# Language Name, N bytes

Wo Nist die Größe Ihres Beitrags? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:

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

Wenn Sie mehrere Zahlen in Ihre Kopfzeile aufnehmen möchten (z. B. weil Ihre Punktzahl die Summe von zwei Dateien ist oder wenn Sie die Strafen für Interpreter-Flags separat auflisten möchten), stellen Sie sicher, dass die tatsächliche Punktzahl die letzte Zahl in der Kopfzeile ist:

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

Sie können den Namen der Sprache auch als Link festlegen, der dann im Leaderboard-Snippet angezeigt wird:

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


25
Für alle, die sich fragen, wann Thanksgiving in diesem Jahr ansteht: Thanksgiving ist morgen.
TheNumberOne

6
Aber ich hatte am 10. Oktober Erntedankfest? Es tut mir leid, dass Ihre Frage zu spät ist.
JimmyJazzx

5
@Downgoat Verwenden Sie den gewünschten Byte-Zähler. Das ist nur die, die ich persönlich benutze und empfehlen würde.
bkul

22
"Einige Feiertage haben feste, leicht zu merkende Daten, wie den 31. Oktober und den 25. Dezember." Diese Beispiele sind leicht zu merken, weil sie wirklich am selben Tag sind: 31. Oktober = = 25. Dezimal. ;-)
Adrian McCarthy,

7
Sollte es für eine Antwort, die den Bonus beinhaltet, ein Jahr 0 zwischen -1 und 1 geben oder nicht?
Feersum

Antworten:


40

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

Getestet mit meinem TI-84 + Taschenrechner

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

Danksagung ist der 29. November minus dem Wochentag des 1. September, wobei 1 Sonntag und 7 Samstag ist. Dies wird im Format ausgegeben MMDD.

Testfälle: 2015-> 1126, 1917-> 1122, -480-> 1125wurden verifiziert. TI-BASIC scheint den Gregorianischen Kalender für alle Daten zu verwenden.

TI-BASIC unterstützt keine negativen Jahre, aber dies bringt den Bonus, weil wir 10000 zur Eingabe hinzufügen. Da der Gregorianische Kalender einen Zeitraum von 400 Jahren hat, ändert sich der Wochentag nicht.


5
Heiliger Strohsack. xD Ich hätte nie gedacht, dass dies so funktioniert hätte, +1.
Addison Crump

Gute Idee, 10000 hinzuzufügen. Schön.
Am

Ich zähle 23 Buchstaben. Wie kann das 15 Bytes sein?
Stephan Schinkel

1
@StephanSchinkel TI-BASIC verwendet Token, die im Speicher des Taschenrechners gespeichert sind. Ich glaube, alle Zeichen hier sind 1 Byte, mit Ausnahme der Token, dayofWK(und Ansbestehen jeweils aus 2 und 1 Byte.
FryAmTheEggman

Sie haben es auf einem Taschenrechner getestet? Wow.

23

PHP, 65 48 42 41 36 (+2 für -F) = 38 Bytes

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

Übernimmt die Eingabe als erstes Befehlszeilenargument. Läuft mit Warnungen, die von unseren Regeln akzeptiert werden. Druckt NovDD, wo DDist der Tag des Erntedankfestes.

Kein Online-Link, da ideone keine Kommandozeilen-Argumente unterstützt und ich keinen Online-Interpreter kenne, der dies tut.

Vielen Dank an Alexander O'Mara, der mir einen neuen Trick beigebracht hat, und an Primo für eine deutliche Reduzierung


2
Das ist lustiger als Mathematica.
Lirtosiast

2
@Tryth Noch kürzere: "4thuXI". Sie können den Raum zwischen dem Jahr sogar fallen lassen "4thuXI2015".
Alexander O'Mara

1
Mit der Befehlszeilenoption -Fkann die Eingabe auf gekürzt werden "4thuXI$argn".
Primo

3
Warten Sie, das funktioniert tatsächlich? Das ist ... das ist nur ... ich weiß nicht einmal ...
ETHproductions

1
Funktioniert bei mir . Während ich dabei bin, Mdbraucht keine Anführungszeichen, mit E_NOTICEdeaktiviert.
Primo

18

Mathematica, 59 38 Bytes

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

+1 Clever. Dort wird auch WolframAlpha["Thanksgiving " <> #] &das Datum als Zeichenfolge eingegeben.
DavidC

WolframAlpha gibt den US-Erntedankfesttag ab 1863 (als Lincoln ihn am LETZTEN Donnerstag im November bekannt gab) zurück. Die USA beobachten Thanksgiving seit 1789.
DavidC

@DavidCarraher Das OP gibt jedoch an, dass das Programm für mindestens 0 - 9999 CE
LegionMammal978 25.11.15

17

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

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

Da das Datum "in einem vernünftigen Format sein kann", wird diese Funktion verwendet DD.MM. Ich habe eine TeaScript-Antwort mit einer anderen Technik geschrieben, aber diese Formel war kürzer.

Erläuterung

Da die Monate auf Null basieren, wird new Date(a,10)ein DateObjekt zurückgegeben, das den 1. November des angegebenen Jahres darstellt.

Da getDay()eine Zahl zurückgegeben wird, die den Wochentag von darstellt 0..6, möchten wir eine Karte von erstellen

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  

dann 22 hinzufügen. Es stellt sich heraus, dass (11 - new Date(a,10).getDay()) % 7das den Trick tun wird. Wie @Thomas Kwa betonte, entspricht dies 28-new Date(a,8).getDay()28 minus dem Wochentag des 1. September.


Gute Lösung, ich finde es toll, wie kurz es ist und dass es immer noch verständlicher ist als die meisten Einträge.
Marko Grešak

16

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

Japt ist eine verkürzte Version von Ja vaScri pt .

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

Hahaha, ich fand einen wirklich betrügerischen Trick: Der Interpreter ignoriert beim Dekomprimieren alle Klammern in Strings (die zum Einfügen von Code verwendet werden), sodass wir den gesamten Quellcode komprimieren können, um ein Byte zu speichern>: D

Die beiden ?s sollten die nicht druckbaren Unicode-Zeichen U + 0098 bzw. U + 0085 sein. Probieren Sie es online!

Nach der Dekomprimierung ergibt der Code Folgendes:

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

Welches ergibt:

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

Welches gibt die richtige Ausgabe.

Verwendet die Technik von intrepidcoder und gibt im Format aus dd.mm. Stützt richtig negative Jahre. Vorschläge willkommen!

Bearbeiten: Ab dem 2. Dezember können Sie jetzt diesen 11-Byte- Code (mit 8,25 Punkten ) verwenden:

28.11-ÐU8 e

(Ich wünschte, ich hätte dies früher implementiert!)


Sehr schön gemacht.
bkul

Dies ist jetzt länger als Vanille-JavaScript. Thomas Kwa hat eine viel kürzere Formel .
intrepidcoder

@intrepidcoder Danke, behoben.
ETHproductions

12

Vitsy , 44 Bytes

Ich rechne mit reiner Mathematik !

Golf gespielt:

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

Ungolfed (verschob den Methodenaufruf in die erste Zeile, um ihn lesbar zu machen):

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

V Speichern Sie die Eingabe als endgültige Variable.
 e2 * 28 zum Stapel schieben.
    V Schieben Sie den Eingang auf den Stapel.
     2- Subtrahiere zwei.
       V4 / D1M - Get floor (Eingang / 4).
              + Addiere es zur Gesamtsumme.
               Vaa * Dv / D1M - Boden abrufen (Eingabe / 100) und 100 als Temp. Speichern
                                    Variable in den Prozess.
                          - Subtrahieren Sie es von der Summe.
                           Vv4 * / D1M - Get floor (Eingabe / 400).
                                    + Addiere es zur Gesamtsumme.
                                     7M Modulo mal sieben.
                                       - Subtrahieren Sie das Ergebnis von 28.
                                        baa * / + Add .11
                                              N Ausgabe als Nummer.

Es gibt wahrscheinlich einen besseren Algorithmus dafür (und das ist wahrscheinlich schrecklich golfen), aber für diejenigen, die sich fragen, kommt mein Algorithmus von hier .

Probieren Sie es online!

Bekomme ich Bonuspunkte für die Berechnung und genau 42 Bytes? Träume ruiniert.

Vielen Dank an @ Hosch250 für den Hinweis, dass ich es falsch gemacht habe. : D behoben.


2
Nein, aber du bekommst eine +1 von mir;)
Conor O'Brien

Es heißt, dass Thanksgiving im Jahr 2016 28. November ist. Es ist wirklich 24. November
Hosch250

@ Hosch250 Du hast Recht - jetzt behoben.
Addison Crump

10

Python 38 * 0,75 = 28,5 Bytes

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

Dies funktioniert mit negativen Jahren in der in der Frage angegebenen Weise, obwohl mir aufgefallen ist, dass der Gregorianische Kalender kein Jahr 0 enthält, sodass dieses Verhalten ein wenig verdächtig ist.


1
Sie können fallen lassen f=.
Feersum

1
Wie funktioniert das bei negativen Daten? Gilt Modulo in Python für Negative? : O
Addison Crump

Es sollte kürzer sein String Wiederholungen zu verwenden,"Nov "+`...`
xnor

@VoteToClose Python modulo gibt eine Antwort mit demselben Vorzeichen wie das zweite Argument. So -40%7==2aber-40%-7==-5
Quintopia

@quintopia Warte, warte, ich bin ein Idiot. Okay. Das macht Sinn.
Addison Crump

10

JavaScript (ES6), 43.5

Die tatsächliche Byteanzahl beträgt 58. Der Bonus von -25% gilt => 58 * 0,75 = 43,5

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

So geradlinig und albern es auch sein mag, ohne knifflige Umgehungen oder Berechnungen.

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

Beachten Sie, dass die Eingabe von Jahr 0-100 1900-2000 Jahre ergibt. Es sieht jedoch so aus, als gäbe 0-100 Jahre das gleiche Datum wie 1900-2000, wenn man sich die anderen Antworten ansieht.


Ersetzen a+18durch 22, weil es nur in "else" aufgerufen wird und "else" nur auftritt, wenn a weder größer noch kleiner als 4 ist, dh genau 4.


Ersetzen a<4?26-a:a>4?a+21:22durcha<=4?26-a:a+21


2
Entschuldigen Sie, wenn ich falsch liege, aber nicht a<4?x:a>4?y:a+18gleichwertig mit a<4?x:a>4?y:22?
ETHproductions

Übrigens, es sagt mir das falsche Jahr für Eingaben von 0 bis 99. Ich bin mir nicht sicher, ob dies wichtig ist.
ETHproductions

@Eth LOL natürlich hast du recht, hätte nicht gedacht, dass das immer 4 + 18 ist: D
nicael

@Eth hm, 0 bis 99 ist in der Tat falsch, lassen Sie mich versuchen, das zu beheben.
Nicael

@Eth Es sieht so aus, als gäbe 0-100 das gleiche Datum wie 1900-2000, gemessen an den anderen Antworten.
Nicael

8

TeaScript, 35 33 24 Bytes - 25% = 18

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

Dies ist die gleiche Methode wie bei meiner JavaScript-Antwort , bei der die clevere Formel von Thomas Kwa verwendet wird.

Alternative Version mit Erläuterung

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.

Es ist 35 Zeichen, aber 36 Bytes wegen ¡:)
Nicael

@nicael Nicht von dieser Seite , es ist nicht;)
ETHproductions

Hm, 36 mit mothereff.in/… .
Nicael

@Downgoat verwendet normalerweise dieses Format , in dem alle Zeichen bis zu U + 00FF 1 Byte lang sind.
ETHproductions

5

Jython, 141.155 Bytes

Verwendet die Java Calendar- und Scanner-Klassen mit Python-Syntax.

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)

Bearbeiten: Kleinere Syntaxprobleme, 14 Bytes hinzugefügt.

Siehe auch meine Brainfuck- Version.


5

Python, 83 81 78 Bytes

from datetime import*
lambda a:'Nov '+`((10-datetime(a,11,1).weekday())%7)+22`
  • -2 Bytes: Name zum Import hinzugefügt (danke @ Κριτικσι Λίθος)
  • -1 Bytes: geändert in * import ** (danke @FryAmTheEggman)
  • -2 bytes: geändert in repr um den Tag umzuwandeln (danke @willem)

1
Nur ein Vorschlag zur Reduzierung der Byteanzahl: Verwenden Sie import datetime as dund dann können Sie dfür jedes Mal, wenn Sie datetimein Ihrem Programm verwenden.
Kritixi Lithos

2
Sie könnten auch Pandas probieren. import pandas;print'Nov '+`((10-pandas.datetime(input(),11,1).weekday())%7)+22`
Willem

@ ΚριτικσιΛίθος aber dann wäre datetime.datetime nur d.datetime, nicht wahr?
TanMath

2
from datetime import*ist noch ein bisschen kürzer, da du das nicht d.mehr
brauchst

5

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

Angenommen, das Jahr befindet sich in Zelle A1 im Datumsformat. Gibt die Ganzzahl des Tages im November zurück, an dem Thanksgiving stattfindet.

Dies gilt nur für normale Schaltjahre. Es berücksichtigt nicht die Tatsache, dass die Jahre 2100, 2200, 2300 keine Schaltjahre sind.

Dies soll erst ab 1621 funktionieren, dh seit Thanksgiving. (Obwohl es auf jeden Fall bis 0 n. Chr. Funktionieren wird).

=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"))))))

Hübsch gedruckt:

=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! Anstatt nach dem 1. Januar zu rechnen und dann viele Schaltjahrberechnungen durchzuführen, um mit dem 29. Februar fertig zu werden, hätte ich die Berechnungen nach dem 1. November durchführen sollen Die Implementierung hängt jedoch vom Standard-Datumsformat Ihrer Excel-Installation ab. Diese Version ist für TT / MM / JJJJ vorgesehen:

 =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")))))

Und jetzt, da ich das Pfaffing durchgeführt habe, um eine knappe Berechnung in Smalltalk zu erhalten, führt das Zurückportieren nach Excel zu:

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

(mit dem Jahr noch in A1, aber als ganze Zahl). Dies funktioniert sogar für die Jahre 2100, 2200 und 2300 für alle Daten ab 7700BC / E mit dem Datumswiederholungstrick von Thomas Kwa.


1
Wenn ich das mit Daten vor 1900 versuche, funktioniert es in meiner Excel-Kopie nicht.
Angelo Fuchs

Die lange Version funktioniert nicht so gut.
Angelo Fuchs

Verwenden Sie für alte Daten die Excel-Arbeitsmappe für Daten vor 1900. < exceluser.com/downloads/examples/post_900_123/index.html >
Euan M,

Bei Fragen, ob dies auch funktioniert, darf man nicht nur das Datum im November ausgeben. Sie benötigen ein "Nov" oder "11" in irgendeiner Form.
Lirtosiast

@Thomas Kwa Die Datumseingabe ist das Jahr im Datumsformat. Die Berechnung berechnet dann den Wochentag, auf den der 1. November fällt, und berechnet dann, welcher Tag der vierte Donnerstag im November ist.
Euan M

4

PowerShell, 67 64 84 72 58 45 Bytes

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

Wir nehmen unsere Eingabe-Ganzzahl als $aund geben sofort Noveine neue Zeile aus. Dann stellen wir $aNullen und den 1. September voran, 00$a/9/1bevor wir eine neue generieren dateund bestimmen, was DayOfWeekdas ist. Wenn der 1. September an einem Sonntag ( .DayOfWeekgleich 0) ist, ist Thanksgiving am 28.. Wenn der 1. September an einem Montag ist ( .DayOfWeekgleich 1), ist Thanksgiving am 27.. Und so weiter. Daher subtrahieren wir diesen Wochentag von, 28um unsere Antwort auszugeben.

Das Voranstellen mit zweistelligen Nullen berücksichtigt ein- und zweistellige Jahre, ohne das Parsen für drei- oder vierstellige Jahre zu unterbrechen. Funktioniert nicht für negative Zahlen, da .NET datetimenicht weniger als Jahre unterstützt 0.

Vielen Dank an TessellatingHeckler und Toby Speight für die Unterstützung.


"{0:D3}/Nov/$_" -f $akürzer ist als "$($a.ToString("000"))/Nov/$_"und das gleiche Ergebnis, und ich denke , Sie nutzen könnten 11stattNov
n0rd

@ n0rd Ah, ausgezeichnet! Ja - das Novwar ein Überbleibsel aus der Zeit, als ich versuchte, zweistellige Jahreszahlen richtig zu erkennen, also tausche ich das auch aus. Vielen Dank!
AdmBorkBork

@TessellatingHeckler Dieser Ansatz funktioniert, aber Sie müssen zwei Nullen voranstellen, um einstellige Jahre zu berücksichtigen. Andernfalls befinden Sie sich wieder im 20XX, dem ich begegnet bin. Danke für die Hilfe - ich habe die Antwort aktualisiert.
AdmBorkBork

1
@TessellatingHeckler Auf meinem System zumindest die Eingabe mit einem einstelligen Jahren in date "11/1/$a"Ergebnisse in Thursday, November 1, 2007 12:00:00 AM. Dies liegt daran, dass wir die Calendar.TwoDigitYearMax- Eigenschaft nicht bearbeiten. Wenn es also analysiert wird , müssen wir doppelt null auffüllen, um das zu umgehen.
AdmBorkBork

Richtig richtig. Doppelte Polsterung ist es.
TessellatingHeckler

3

Golfscript, 25 × 0,75 = 18,75 Bytes

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

Hierbei wird die Sakamoto-Formel für den Wochentag verwendet. Da es Leute gibt, die dies tun, erfolgt die Ausgabe in Form von dd-mm. Mein vorheriger Beitrag ist unten zu finden:

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

3

TSQL, 478 296 Bytes

Nur für Funsies. Normalerweise hätten Sie eine Datumsmaßtabelle, um dies zu vereinfachen, select * from dimDate where [Year] = @Year and [Holiday] = 'Thanksgiving'aber wenn dies nicht der Fall ist ...

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

Ist das wirklich der kürzeste Weg?
Lirtosiast

Ich nehme an, dass ich mit den Regeln des Code-Golf nicht vertraut bin, aber die Antwort erstellt ein DB-Objekt, das Eingaben akzeptiert und Ausgaben zurückgibt, die mit dem OP übereinstimmen. Es gibt einige offensichtliche Kürzungen, die auftreten können, wenn Eingaben in Inline-Code akzeptiert werden können, aber dies war mein Gedanke für den Funktionsobjekttyp. Ich bin mir sicher, dass es in beiden Fällen noch weiter gehen könnte. @ ThomasKwa, hast du Vorschläge?
Peter Vandivier

Nun, es scheint mir, dass Sie die reine mathematische Formel verwenden könnten, die in dieser Antwort erwähnt wird, und sich nicht mit all den Dattelobjekten zu beschäftigen.
Lirtosiast

Das ist keine rein mathematische Lösung, aber das Lesen dieser Antwort brachte mich auf jeden Fall auf die Idee, 200 Zeichen zu spielen. Vielen Dank!!
Peter Vandivier

(Ich meinte (28 - ( x - 2 + floor(x / 4) - floor(x / 100) + floor(x / 400) ) % 7) Ja, das Lesen anderer Antworten ist oft hilfreich.
Lirtosiast

3

Pyth, 30 28 * 75% = 21 Bytes

Ich bin zu 100% davon überzeugt, dass dies verkürzt werden könnte, aber hey, es ist mein erstes Pyth-Programm! \O/

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

Testsuite

Gibt das Datum im dd.mmFormat aus.

Bitte schlagen Sie Golfmöglichkeiten vor, wenn Sie können! Ich würde gerne mehr über Pyth erfahren.


2

Excel, 64 48

Jahr in A1

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

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

Da Excel lokalisierungsbasiert ist und ich dies testen möchte. Bitte erklären Sie, was die Funktionen bewirken, damit ich die richtige in meiner Sprache auswählen kann.
Angelo Fuchs

1
Dies funktioniert auch nicht für Daten vor 1900 (zumindest in meiner Excel-Version)
Angelo Fuchs

Außerdem haben Sie 13Bytes TEXTvon gespeichert =TEXT(DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22),"d mmm")- die Ausgabe ist eine Ganzzahl ohne Formatierung.
User3819867

@ user3819867, so speichert Excel seine Daten. Die Formatierung bleibt dem Benutzer
überlassen

@AngeloFuchs, DATE gibt einen Datumswert mit den Parametern Jahr, Monat und Tag zurück. MOD gibt den restlichen Teil einer Division (Modul) zurück. WOCHENTAG gibt den Wochentag eines Datums zurück (1 = Sonntag, 2 = Montag usw.).
SeanC

2

Befunge, 41 Bytes

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

Führen Sie diesen Interpreter aus .

Erläuterung: Ein gemeinsames Jahr ist 365 = 1 mod 7 Tage, also das Jahr plus all 4 - ten Jahr, minus all 100 th ( din ascii) Jahr plus alle 400 - ten Jahren Konten für alle Schalttag (einschließlich dem laufenden Jahr). Das Ergebnis :::4"d"*/\"d"/-\4/++kann dann als 5. März gedacht werden th , den ersten Tag nach dem Februar am gleichen Tag wie der erste Tag des Jahres gemeinsam Jahre fällt. Danach haben wir uns auf das Muster mit kalibrieren 5+7%-Subtrahieren eine Anzahl von Tagen der Woche vom 28. - ten (die 47*gespeicherten früher) im November. Dann drucken.

Eine Version, die BC-Jahre korrigiert, ist derzeit mit 59 -25% = 44,25 Byte länger als der vorgesehene Bonus:

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}"
}

Verwendung:

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

Ich bin mir nicht sicher, ob Leerzeichen zählen, es liegt irgendwo zwischen 102 und 124, zögern Sie nicht, sie zu bearbeiten.
Wenn Ganzzahlen eine gültige Ausgabe sind, bin ich mehr als glücklich, den FormatTeil zu entfernen .


Leerzeichen zählen; Wenn sie für das Programm nicht erforderlich sind, können Sie sie jedoch entfernen.
Lirtosiast

0

PHP 5.3+, 59 Bytes

Dies verwendet die in PHP eingebaute Funktion strtotime, um das Datum zu analysieren.

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

Dies erwartet, dass der Wert über den GET-Parameter Y ODER über übergeben wird php-cli Y=<year>.

Es wird versucht, den nächsten Donnerstag nach dem 19. November zu finden.
Bei den Tests, die ich bisher durchgeführt habe, funktioniert es einwandfrei.

Beachten Sie, dass zweistellige Jahreszahlen möglicherweise unterschiedlich interpretiert werden.

Ich benutze es gmdate, um Zeitzonenprobleme zu vermeiden, aber es funktioniert genauso gut mit date(zumindest, wo ich wohne).


1
Eine Antwort ist kein geeigneter Ort, um die Gültigkeit einer Eingabemethode zu diskutieren. Ich habe diese Option im Standard-E / A-Metapost erstellt (damit die Community darüber abstimmen kann) und Ihre Konversation in den Chat verschoben . (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

was mit diesem Testgerüst

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

ergibt wie gewünscht

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);}

Lassen Sie die alte zum Vergleich, weil ich finde es klüger in Bezug auf die Nutzung des Kalendermoduls, aber das oben ist viel kürzer.

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

Dies scheint keine Eingabe zu erfordern.
Peter Taylor

Ja, das hat mich verwirrt. Einige Lösungen haben eine Funktionsdefinition und andere verwenden nur eine Variable, die nirgendwo definiert ist. Ich bin mir also nicht sicher, was ich für das bytecount verwenden soll.
eMBee

Ich denke, dass die Antworten, die Sie als " eine Variable, die nirgendwo definiert ist " verwenden, tatsächlich eine sehr kurze Syntax für die Funktionsdeklaration verwenden. Es gibt ein oder zwei Antworten, bei denen esolangs verwendet werden, die eine spezielle Behandlung für stdin haben und daher das Schreiben vollständiger Programme bevorzugen. Ich kenne Pike nicht, aber wenn Sie Leerzeichen entfernen und den Funktionsnamen abkürzen können, string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();}dann zähle ich das als 107 Bytes.
Peter Taylor

Ich dachte, ich hätte ein paar gesehen, die keine Funktionsdeklarationen waren, aber sie scheinen repariert worden zu sein, nur das Smalltalk-Beispiel passt nicht. Wenn das gültig ist, könnte ich weitere 17 Bytes von diesem rasieren ...
eMBee

Die Smalltalk-Version ist programmspezifisch als Workspace-Ausdruck geschrieben. Uns wurde gesagt, dass wir einen Input bekommen, anstatt Input zu erbitten.
Euan M

0

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

"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

Vorherige Versionen

11nn Ausgang

"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 Ausgabe

"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 Ausgabe

"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

nb Dies wird nicht als Methode, sondern als Programm - speziell als Workspace-Ausdruck - bereitgestellt.

Es wird davon ausgegangen, dass die Eingabe gegeben ist (gemäß der Formulierung "gegeben mit einem bis zu vierstelligen Jahr".
Wenn die Eingabe deklariert und gegeben wird, werden weitere 11 Zeichen hinzugefügt:

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

Vielen Dank an eMBee, dass Sie gezeigt haben, wie Sie noch ein Zeichen entfernen können - das Leerzeichen unmittelbar vor dem 'w'.

Eigentlich hat mich das dazu inspiriert, das Leerzeichen vor 'd:' zu entfernen:
|y|y:=2015.(12-(Date y:y m:11d:1)w)\\7+1122
Was hat funktioniert!



Ich stimme zu - aber da die Liste einige Versionen nur für Tageszahlen enthält, habe ich sie für einen Vergleich von Äpfeln zu Äpfeln dort abgelegt
Euan M

0

GNU-Coreutils, 35 Bytes

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

Durchsucht einfach die Woche vom 22. bis 28. November nach einem Donnerstag. Führen Sie es in einem C- oder POSIX-Gebietsschema aus, da ich davon abhänge, dass Donnerstag die einzige Abkürzung für einen Tag ist, die ein 'h' enthält.


Hier ist eine klügere Antwort, wenn auch ein Byte länger:

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

Wir ermitteln die Wochentagsnummer eines Datums in einer ziemlich willkürlichen Woche zwischen März und September (Tag und Monat sind also jeweils eine Ziffer und wir sind nicht von einem möglichen Schalttag betroffen). Wir wählen den Tag so, dass es ein Sonntag ( %w==0) ist, an dem Thanksgiving am 28. ist. Wir können diesen Wert dann von 28 subtrahieren, um den entsprechenden Donnerstag zu erhalten.


2
Dies funktioniert nur, wenn Sean Connery es ausführt.
bkul

0

TSQL, 53 52 Bytes

DECLARE @ CHAR(4)=2000

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

Geige

Berechnen Sie den Montag vor oder am 2. September und addieren Sie 59 Tage

(besser als montags vor oder am 4. oktober berechnen und 31 tage hinzufügen, da der 10. oktober der monat ist und somit 1 byte gespart wird)


-1

Perl, 92 Bytes

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

BEARBEITEN: Festes Ausgabeformat, Fehler behoben, zB 2012 Ergebnis, verwendet kürzeres "für" Format. Danke an msh210.


Dies ist kürzer und macht das Gleiche: use Time::Local;(localtime(timelocal 0,0,0,$_,10,$ARGV[0]))[6]==4?print:0for 22..29. Beide Skripte weisen jedoch die gleichen Mängel auf: (1) Sie geben nicht die erforderliche Darstellung des Monats aus. (2) Sie haben die falsche Ausgabe für zB 2012.
msh210
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.