kiedy jest święto Dziękczynienia?

38

tło

Niektóre święta mają ustalone, łatwe do zapamiętania daty, takie jak 31 października, 25 grudnia itp. Niektóre jednak chcą być kłopotliwe. Są one określane jako „pierwszy poniedziałek września” lub „czwarty czwartek listopada”. Skąd mam wiedzieć, kiedy to jest?

Wiem tylko, że Święto Dziękczynienia zbliża się bardzo szybko, dlatego potrzebuję programu, który pomoże mi ustalić, kiedy to nastąpi. Niektórzy nawet twierdzą, że jest jutro , więc twój program musi być jak najkrótszy, aby upewnić się, że mogę go ponownie wpisać na czas.

Wyzwanie

Utwórz program lub funkcję, która, biorąc pod uwagę maksymalnie czterocyfrowy rok (np. 2015 lub 1984), wyświetla lub zwraca datę Święta Dziękczynienia Stanów Zjednoczonych w tym roku. Święto Dziękczynienia jest zdefiniowane jako czwarty czwartek listopada według strony Wikipedii . (Wskazówka: ta strona zawiera także kilka interesujących informacji na temat wzorca daty).

Wprowadzanie : liczba dziesiętna z maksymalnie czterema cyframi reprezentującymi rok w erze wspólnej (CE). Przykłady: 987, 1984, 2101

Wyjście : data, w tym miesiąc i dzień, w którym przypada Święto Dziękczynienia, lub spadłoby, gdyby istniało, w tym roku. Może to być dowolny rozsądny format; użyj najlepszej oceny. Korzystaj z kalendarza gregoriańskiego we wszystkich przypadkach, nawet jeśli w tym czasie nie był używany.

(Uwaga: pamiętaj, aby poprawnie obchodzić lata przestępne!)

Przypadki testowe Wejście 1:

2015

Wyjście 1:

Nov 26

Wejście 2:

1917

Wyjście 2:

Nov 22

Punktacja

Zgłoszenia będą oceniane w bajtach . Polecam tę stronę do śledzenia liczby bajtów, chociaż możesz użyć dowolnego licznika, który ci się podoba.

Bonusy

-25% do twojego wyniku, jeśli traktujesz daty BCE jako liczby ujemne (np. -480 byłby rokiem bitwy pod Termopilami).

Wprowadzanie negatywnych przypadków testowych:

-480

Odpowiednia wydajność:

Nov 25

To jest , więc wygrywa najniższy wynik!

Edycja: Oznaczam zgłoszenie TI-BASIC Thomasa Kwa jako zaakceptowane. Nie zniechęcaj Cię do przesyłania nowych wpisów!

Liderów

Oto fragment kodu, który pozwala wygenerować zarówno zwykłą tabelę wyników, jak i przegląd zwycięzców według języka.

Aby upewnić się, że twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:

# Language Name, N bytes

gdzie Njest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

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

Jeśli chcesz umieścić w nagłówku wiele liczb (np. Ponieważ twój wynik jest sumą dwóch plików lub chcesz osobno wymienić kary za flagi tłumacza), upewnij się, że rzeczywisty wynik jest ostatnią liczbą w nagłówku:

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

Możesz także ustawić nazwę języka jako link, który pojawi się we fragmencie tabeli wyników:

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

bkul
źródło
25
Dla każdego, kto zastanawia się, kiedy w tym roku nadejdzie Święto Dziękczynienia: Święto Dziękczynienia będzie jutro.
TheNumberOne
6
Ale miałam Święto Dziękczynienia 10 października? Przykro mi powiedzieć, że twoje pytanie jest spóźnione.
JimmyJazzx
5
@Downgoat Użyj dowolnego licznika bajtów, jaki chcesz. Tego właśnie używam osobiście i poleciłbym.
bkul,
22
„Niektóre święta mają ustalone, łatwe do zapamiętania daty, takie jak 31 października, 25 grudnia” Te przykłady są łatwe do zapamiętania, ponieważ są naprawdę tego samego dnia: 31 października == 25 miejsc po przecinku ;-)
Adrian McCarthy
7
W przypadku odpowiedzi, która daje premię, czy powinien być rok 0 między -1 a 1, czy nie?
feersum

Odpowiedzi:

40

TI-BASIC, 15 bajtów * 0,75 = 11,25

Testowany na moim kalkulatorze TI-84 +

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

Święto Dziękczynienia przypada na 29 listopada minus dzień tygodnia 1 września, gdzie 1 to niedziela, a 7 to sobota. Dane wyjściowe są w formacie MMDD.

Przypadki testowe: 2015-> 1126, 1917-> 1122, -480-> 1125zostały zweryfikowane. Wydaje się, że TI-BASIC używa kalendarza gregoriańskiego dla wszystkich dat.

TI-BASIC nie obsługuje lat ujemnych, ale dostaje to bonus, ponieważ dodajemy 10000 do nakładów. Ponieważ kalendarz gregoriański ma okres 400 lat, nie zmienia to dnia tygodnia.

lirtosiast
źródło
5
O kurczę. xD Nigdy bym nie pomyślał, że to tak by działało, +1.
Addison Crump
Dobry pomysł, aby dodać 10000. Fajnie.
agtoever
Naliczyłem 23 litery. Jak to może być 15 bajtów?
Stephan Schinkel,
1
@StephanSchinkel TI-BASIC wykorzystuje tokeny, które są przechowywane w pamięci kalkulatory, wierzę, wszystkie postacie są tu 1 bajt wyjątkiem żetonów dayofWK(i Ansktóre są 2 i 1 bajtów każdy.
FryAmTheEggman,
Przetestowałeś to na kalkulatorze? łał.
23

PHP, 65 48 42 41 36 (+2 dla -F) = 38 bajtów

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

Pobiera dane wejściowe jako pierwszy argument wiersza poleceń. Działa z ostrzeżeniami, które są akceptowane przez nasze zasady. Odbitki NovDD, gdzie DDjest dzień Dziękczynienia.

Brak linku online, ponieważ ideone nie obsługuje argumentów wiersza poleceń i nie znam takiego interpretera.

Dzięki Alexander O'Mara za nauczenie mnie nowej sztuczki i primo za znaczną redukcję

Mego
źródło
2
To jest zabawniejsze niż Mathematica.
lirtosiast
2
@Tryth jeszcze krócej: "4thuXI". Możesz nawet upuścić przestrzeń między rokami "4thuXI2015".
Alexander O'Mara,
1
Za pomocą opcji wiersza poleceń -Fmożna skrócić dane wejściowe "4thuXI$argn".
primo,
3
Czekaj, to faktycznie działa? To jest ... to po prostu ... ja nawet ...
ETHprodukcje
1
Pracuje dla mnie . Chociaż jestem przy tym, Mdnie potrzebuje cytatów, z E_NOTICEwyłączonym.
primo
18

Mathematica, 59 38 bajtów

DayRange[{#,11},{#,12},Thursday][[4]]&
LegionMammal978
źródło
+1 Sprytny. Tam również WolframAlpha["Thanksgiving " <> #] &data jest wprowadzana jako ciąg.
DavidC,
WolframAlpha zwraca Dzień Dziękczynienia w Stanach Zjednoczonych od 1863 roku (kiedy Lincoln ogłosił, że będzie to OSTATNI Czwartek w listopadzie). USA
obchodzi
@DavidCarraher Jednak OP stwierdza, że ​​program musi działać przez co najmniej 0 - 9999 CE
LegionMammal978
17

JavaScript (ES6), 42 40 31 bajtów - 25% = 23,25

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

Ponieważ data „może mieć dowolny rozsądny format”, funkcja ta używa DD.MM. Napisałem odpowiedź na TeaScript inną techniką, ale ta formuła była krótsza.

Wyjaśnienie

Ponieważ miesiące liczone są od zera, new Date(a,10)zwraca Dateobiekt reprezentujący 1 listopada określonego roku.

Ponieważ getDay()zwraca liczbę reprezentującą dzień tygodnia, od 0..6którego chcemy mapować

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  

następnie dodaj 22. Okazuje się, że (11 - new Date(a,10).getDay()) % 7to załatwi sprawę. Jak zauważył Thomas Kwa , jest to to samo, 28-new Date(a,8).getDay()co 28 minus dzień tygodnia 1 września.

intrepidcoder
źródło
Ładne rozwiązanie, uwielbiam to, jak krótkie i że jest jeszcze bardziej zrozumiałe niż większość wpisów.
Marko Grešak
16

Japt , 43 37 36 35 29 bajtów - 25% = 21,75

Japt to skrócona wersja Ja vaScri pt .

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

Hahaha, znalazłem naprawdę podstępną sztuczkę: interpreter ignoruje nawiasy wewnątrz ciągów (używanych do wstawiania kodu) podczas ich dekompresji, dzięki czemu możemy skompresować cały kod źródłowy, aby zapisać bajt>: D

Te dwa ?znaki powinny być, odpowiednio, niedrukowalnymi kodami U + 0098 i U + 0085 w Unicode. Wypróbuj online!

Po dekompresji kod ocenia to:

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

Co ocenia:

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

Co daje odpowiednią wydajność.

Używa techniki intrepidcodera , wyświetlając dane w formacie dd.mm. Właściwie obsługuje lata ujemne. Sugestie mile widziane!

Edycja: Od 2 grudnia możesz teraz używać tego 11-bajtowego kodu (zdobywając 8,25 punktu ):

28.11-ÐU8 e

(Szkoda, że ​​nie wdrożyłem tego wcześniej!)

ETHprodukcje
źródło
Bardzo ładnie wykonane.
bkul,
To jest teraz dłuższe niż waniliowy JavaScript. Thomas Kwa ma znacznie krótszą formułę .
intrepidcoder
@intrepidcoder Dzięki, naprawiono.
ETHprodukcje
12

Vitsy , 44 bajty

Obliczam z czystą matematyką !

Gra w golfa:

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

Ungolfed (przeniesiono wywołanie metody do pierwszego wiersza, aby było czytelne):

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

V Zapisz dane wejściowe jako zmienną końcową.
 e2 * Naciśnij 28 na stos.
    V Wciśnij wejście na stos.
     2- Odejmij dwa.
       V4 / D1M - Uzyskaj podłogę (wejście / 4).
              + Dodaj to do sumy.
               Vaa * Dv / D1M - Uzyskaj podłogę (wejście / 100) i zapisz 100 jako temp
                                    zmienna w procesie.
                          - Odejmij to od sumy.
                           Vv4 * / D1M- Uzyskaj podłogę (wejście / 400).
                                    + Dodaj to do sumy.
                                     7M Modulo o siedem.
                                       - Odejmij wynik od 28.
                                        baa * / + Dodaj .11
                                              N Wyjście jako liczba.

Prawdopodobnie jest na to lepszy algorytm (i to prawdopodobnie strasznie gra w golfa), ale dla tych, którzy zastanawiają się, mój algorytm pochodzi stąd .

Wypróbuj online!

Czy dostaję punkty bonusowe za ich obliczenie i posiadanie dokładnie 42 bajtów? Zniszczone marzenia.

Dzięki @ Hosch250 za wskazanie, że robiłem to źle. : D Naprawiono.

Addison Crump
źródło
2
Nie, ale dostaniesz ode mnie +1;)
Conor O'Brien
Mówi, że Święto Dziękczynienia w 2016 jest 28 listopada. To naprawdę 24 listopada.
Hosch250
@ Hosch250 Masz rację - teraz naprawione.
Addison Crump
10

Python, 38 * 0,75 = 28,5 bajtów

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

Działa to z ujemnymi latami w sposób określony w pytaniu, chociaż zwróciłem uwagę, że w kalendarzu gregoriańskim nie ma roku 0, więc takie zachowanie jest nieco podejrzane.

Luke
źródło
1
Możesz upuścić f=.
feersum
1
Jak to działa w przypadku dat ujemnych? Czy modulo w Pythonie ma zastosowanie do negatywów? : O
Addison Crump
Używanie powtórzeń ciągu powinno być krótsze,"Nov "+`...`
xnor
@VoteToClose Modulo Python daje odpowiedź z tym samym znakiem, co drugi argument. Zatem -40%7==2ale-40%-7==-5
quintopia
@ Quintopia Poczekaj, poczekaj, jestem idiotą. W porządku. To ma sens.
Addison Crump
10

JavaScript (ES6), 43.5

Rzeczywista liczba bajtów wynosi 58. Obowiązuje premia w wysokości -25% => 58 * 0,75 = 43,5

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

Całkiem prosto i głupio, jak to możliwe, bez żadnych skomplikowanych obejść ani obliczeń.

De-golf (ES5) + wersja demo:

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

t(prompt())

Uwaga: wprowadzenie roku 0-100 daje 1900-2000 lat. Chociaż wygląda na to, że 0-100 lat podaje tę samą datę co 1900-2000, sądząc po innych odpowiedziach.


Wymiana a+18z 22, ponieważ jest wywoływana tylko w „inny” i „inny” występuje tylko wtedy, gdy nie jest ani większa, ani mniejsza niż 4, to znaczy dokładnie 4.


Zastępuje a<4?26-a:a>4?a+21:22sięa<=4?26-a:a+21

Nicość
źródło
2
Wybacz mi, jeśli się mylę, ale czy nie jest to a<4?x:a>4?y:a+18równoważne a<4?x:a>4?y:22?
ETHprodukcje
BTW, mówi mi zły rok dla dowolnego wejścia od 0 do 99. Nie jestem pewien, czy to ma znaczenie.
ETHprodukcje
@Eth LOL oczywiście masz rację, nie sądziłem, że to zawsze 4 + 18: D
nicael
@Eth hm, od 0 do 99 jest rzeczywiście błędne, pozwól mi spróbować to naprawić.
Nicola
@Eth Wygląda na to, że 0-100 podaje tę samą datę, co 1900-2000, sądząc na podstawie innych odpowiedzi.
Nicola
8

TeaScript, 35 33 24 bajty - 25% = 18

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

Jest to ta sama metoda, co moja odpowiedź JavaScript , która wykorzystuje sprytną formułę Thomasa Kwa .

Wersja alternatywna z objaśnieniem

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.
intrepidcoder
źródło
Ma 35 znaków, ale 36 bajtów z powodu ¡:)
nicael
@nicael Nie przez tę stronę , to nie;)
ETHproductions
Hm, dostając 36 z mothereff.in/... .
Nicola
@Downgoat zwykle używa tego formatu , w którym wszystkie znaki do U + 00FF mają 1 bajt.
ETHprodukcje
5

Jython, 141 155 bajtów

Korzysta z klas kalendarza i skanera Java ze składnią 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)

Edycja: drobne problemy ze składnią, dodano 14 bajtów.

Zobacz także moją wersję Brainfuck .

Społeczność
źródło
5

Python, 83 81 78 bajtów

from datetime import*
lambda a:'Nov '+`((10-datetime(a,11,1).weekday())%7)+22`
  • -2 bajty: dodano nazwę do zaimportowania (dzięki @ Κριτικσι Λίθος)
  • -1 bajtów: zmieniono na * import ** (dzięki @FryAmTheEggman)
  • -2 bajty: zmieniono na repr, aby przekonwertować dzień (dzięki @willem)
Pręt
źródło
1
Tylko sugestia, aby zmniejszyć liczbę bajtów: użyj, import datetime as da następnie możesz użyć dza każdym razem, gdy używasz datetimew swoim programie.
Kritixi Lithos
2
Możesz także spróbować pand. import pandas;print'Nov '+`((10-pandas.datetime(input(),11,1).weekday())%7)+22`
Willem,
@ ΚριτικσιΛίθος, ale wtedy datetime.datetime będzie tylko d.datetime, prawda?
TanMath,
2
from datetime import*jest nawet nieco krótszy, ponieważ nie będziesz już d.więcej
potrzebował
5

Excel, 367 154 53 - 25% = 39,75 bajtów

Zakłada, że ​​rok jest przechowywany w komórce A1 w formacie daty. Zwraca liczbę całkowitą dnia w listopadzie, w którym odbywa się Święto Dziękczynienia.

To tylko normalne lata przestępne. Nie uwzględnia to faktu, że lata 2100, 2200, 2300 nie są latami przestępnymi.

Jest to przeznaczone tylko do pracy w 1621 roku - tj. Od początku Święta Dziękczynienia. (Chociaż z pewnością będzie działać aż do 0 AD).

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

Dość wydrukowane:

=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! Zamiast wykonywać obliczenia na podstawie 1 stycznia, a następnie wykonywać wiele obliczeń roku przestępnego, aby poradzić sobie z 29 lutego, powinienem był oprzeć obliczenia na 1 listopada. Nb To dotyczy teraz poprawnie lat 2100, 2200 i 2300 , ale uzależnia implementację od domyślnego formatu daty instalacji programu Excel. Ta wersja jest przeznaczona dla dd / mm / rrrr:

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

A teraz, kiedy zrobiłem pfaffing, aby uzyskać zwięzłe obliczenia w Smalltalk, przeniesienie go do Excela powoduje:

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

(z rokiem wciąż w A1, ale jako liczba całkowita). Działa to nawet w latach 2100, 2200 i 2300, dla wszystkich dat od 7700BC / E, przy użyciu sztuczki polegającej na powtarzaniu dat przez Thomasa Kwa.

Euan M.
źródło
1
Kiedy próbuję tego z datami sprzed 1900 roku, nie działa to w mojej kopii programu Excel.
Angelo Fuchs,
Długa wersja również nie działa.
Angelo Fuchs
W przypadku starych dat użyj skoroszytu użytkownika Excela sprzed 1900 roku. < exceluser.com/downloads/examples/post_900_123/index.html >
Euan M
Pytania o to, czy to działa na bok, nie sądzę, że wolno ci podawać tylko datę w listopadzie; potrzebujesz „Nov” lub „11” w jakiejś formie.
lirtosiast
@Thomas Kwa Wprowadzoną datą jest rok w formacie daty. Obliczenia są następnie obliczane w dniu tygodnia, w którym przypada 1 listopada, a następnie oblicza datę czwartego czwartku listopada.
Euan M
4

PowerShell, 67 64 84 72 58 45 bajtów

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

Bierzemy naszą całkowitą liczbę wejściową jako $a, i natychmiast wypisujemy Novi nową linię. Następnie bierzemy $ai poprzedzamy go zerami i 1 września 00$a/9/1przed wygenerowaniem nowego datei ustaleniem, co DayOfWeekto jest. Jeśli 1 września przypada w niedzielę ( .DayOfWeekrówna się 0), Święto Dziękczynienia przypada na 28. Jeśli 1 września przypada w poniedziałek ( .DayOfWeekrówny 1), Święto Dziękczynienia przypada na 27. I tak dalej. Dlatego odejmujemy ten dzień tygodnia od, 28aby uzyskać odpowiedź.

Przygotowywanie kont z podwójnymi zerami dla lat jedno- i dwucyfrowych bez przerywania parsowania przez trzy- lub czterocyfrowe lata. Nie działa dla liczb ujemnych, ponieważ .NET datetimenie obsługuje lat mniej niż 0.

Dzięki TessellatingHeckler i Toby Speight za pomoc w tym zakresie.

AdmBorkBork
źródło
"{0:D3}/Nov/$_" -f $ajest krótszy niż "$($a.ToString("000"))/Nov/$_"i daje ten sam wynik, i myślę, że możesz użyć 11zamiastNov
n0rd
@ n0rd Ah, doskonale! Tak - Novbyła to pozostałość po tym, jak starałem się, aby poprawnie rozpoznała dwucyfrowe lata, więc też to zmienię. Dzięki!
AdmBorkBork
@TessellatingHeckler To podejście działa, ale musisz wstawić dwa zera, aby uwzględnić cyfrę przez lata, w przeciwnym razie wracasz do 20XX, na którą wpadłem. Dzięki za pomoc - zaktualizowałem odpowiedź.
AdmBorkBork,
1
@TessellatingHeckler W moim systemie, przynajmniej jednocyfrowe lata w date "11/1/$a"wynikach Thursday, November 1, 2007 12:00:00 AM. Wynika to z faktu, że nie edytujemy właściwości Calendar.TwoDigitYearMax , więc kiedy się analizuje , utkniemy w miejscu podwójnego zerowania, aby obejść ten problem .
AdmBorkBork,
Racja, racja. To podwójne wypełnienie.
TessellatingHeckler
3

Skrypt golfowy, 25 * 0,75 = 18,75 bajtów

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

To używa formuły Sakamoto na dzień tygodnia. Ponieważ są ludzie, którzy to robią, dane wyjściowe mają postać dd-mm. Moje poprzednie zgłoszenie można znaleźć poniżej:

~.4/.25/.4/2---+7%"Nov "28@-
xsot
źródło
3

TSQL, 478 296 bajtów

Tylko dla miłośników. Zwykle masz tabelę wymiarów daty, aby uczynić to prostym, select * from dimDate where [Year] = @Year and [Holiday] = 'Thanksgiving'ale bez tego ...

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

Nie golfowany:

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
Peter Vandivier
źródło
Czy to naprawdę najkrótsza droga?
lirtosiast
Przypuszczam, że mogę nie znać zasad gry w golfa, ale odpowiedź tworzy obiekt DB, który przyjmuje dane wejściowe i zwraca dane wyjściowe pasujące do OP. Istnieje pewne oczywiste skrócenie, które może nastąpić, jeśli dane wejściowe mogą zostać zaakceptowane w kodzie wbudowanym, ale tak myślałem o typie obiektu funkcji. Jestem pewien, że w obu przypadkach można by dalej grać w golfa. @ThomasKwa, masz sugestie?
Peter Vandivier
Cóż, wydaje mi się, że możesz użyć formuły czystej matematyki, o której wspomina ta odpowiedź, i nie zawracać sobie głowy tymi wszystkimi obiektami z datą.
lirtosiast
nie jest to czysto matematyczne rozwiązanie, ale przeczytanie tej odpowiedzi zdecydowanie dało mi kilka pomysłów na grę w golfa 200 znaków. Dzięki!!
Peter Vandivier
(Miałem na myśli (28 - ( x - 2 + floor(x / 4) - floor(x / 100) + floor(x / 400) ) % 7) Tak, czytanie innych odpowiedzi bardzo pomaga.
lirtosiast
3

Pyth, 30 28 * 75% = 21 bajtów

Jestem w 100% przekonany, że można to skrócić, ale hej, to mój pierwszy program w języku Pyth! \ o /

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

Zestaw testowy

Wyświetla datę w dd.mmformacie.

Proszę zaproponować sposoby golfowym, jeśli potrafisz! Chciałbym dowiedzieć się więcej o Pyth.

ETHprodukcje
źródło
2

Przewyższać, 64 48

Rok w A1

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

=DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22)
SeanC
źródło
Ponieważ Excel jest oparty na lokalizacji i chciałbym to przetestować. Wyjaśnij, na czym polegają funkcje, abym mógł wybrać właściwą w swoim języku.
Angelo Fuchs,
1
Ponadto nie działa to w przypadku dat sprzed 1900 r. (Przynajmniej w mojej kopii programu Excel)
Angelo Fuchs
Zapisano również 13bajty TEXTz =TEXT(DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22),"d mmm")- wyjście jest liczbą całkowitą bez formatowania.
user3819867,
@ user3819867, tak excel przechowuje swoje daty. formatowanie należy do użytkownika
SeanC,
@AngeloFuchs, DATE zwraca wartość daty, używając roku, miesiąca i dnia jako parametrów. MOD zwraca pozostałą część podziału (moduł). WEEKDAY zwraca dzień tygodnia daty (1 = niedziela, 2 = poniedziałek itp.).
SeanC
2

Befunge, 41 bajtów

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

Uruchom tego tłumacza .

Objaśnienie: Wspólne roku jest 365 = 1 mod 7 dni, więc w roku oraz co 4 -tego roku minus każde 100 th ( dw ASCII) lat, plus co 400 TH roku rachunki za wszystkie dni przestępnych (w tym obecnego roku). Efektem :::4"d"*/\"d"/-\4/++może następnie być traktowane jako March 5 th , pierwszego dnia po lutym spadnie na tego samego dnia jako pierwszy dzień roku we wspólnych lat. Po tym możemy skalibrować do wzoru z 5+7%-odejmując liczbę dni w tygodniu od 28 th (The 47*zapisanej wcześniej) listopada. Następnie wydrukuj.

Wersja korygująca dla lat pne jest obecnie dłuższa niż przewiduje premia, przy 59 -25% = 44,25 bajtów:

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

Matlab, 78 bajtów

x=find(all(bsxfun(@eq,datestr(datenum(input(''),11,1:30),'ddd'),'Thu')'));x(4)
Luis Mendo
źródło
2

Rubinowy, 60 58 57 * 0,75 = 42,75 bajtów

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

58 bajtów

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

60 bajtów

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

Nie golfowany:

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

Stosowanie:

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

=> Nov 26
Vasu Adari
źródło
0

VBA, 124 bajty * 75% = 93 bajty

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

Nie jestem pewien, czy spacje się liczą, jest to gdzieś pomiędzy 102 a 124, możesz je edytować.
Jeśli liczby całkowite są prawidłowym wyjściem, jestem więcej niż szczęśliwy, że mogę usunąć tę Formatczęść.

użytkownik3819867
źródło
Liczą się spacje; jeśli są niepotrzebne dla programu, możesz je jednak usunąć.
lirtosiast
0

PHP 5.3+, 59 bajtów

Używa wbudowanej funkcji PHP strtotimedo analizowania daty.

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

Oczekuje się, że wartość zostanie przekazana przez parametr GET Y LUB powyżej php-cli Y=<year>.

Próbuje znaleźć następny czwartek po 19 listopada.
Do tej pory dzięki testom, które przeprowadziłem, działa dobrze.

Pamiętaj, że dwucyfrowe lata mogą być interpretowane inaczej.

Używam, gmdateaby uniknąć problemów ze strefą czasową, ale działa równie dobrze, używając date(przynajmniej tam, gdzie mieszkam).

Ismael Miguel
źródło
1
Odpowiedź nie jest odpowiednim miejscem do dyskusji na temat ważności metody wprowadzania danych. Stworzyłem tę opcję w domyślnym meta postu I / O (aby społeczność mogła na nią głosować) i przeniosłem twoją rozmowę na czat . (CC @Mego)
Dennis
0

T-SQL 215 bajtów 248 * 0,75 = 186 bajtów

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

Bez golfa

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

które z tym rusztowaniem testowym

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

plony zgodnie z życzeniem

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
Pieter Geerkens
źródło
0

Szczupak , 87 91 107 77 76 bajtów - 25% = 57

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

pozostawiając stary do porównania, ponieważ uważam, że jest bardziej sprytny, jeśli chodzi o korzystanie z modułu Kalendarza, ale powyższe jest znacznie krótsze.

string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();}
eMBee
źródło
To nie wydaje się wymagać danych wejściowych.
Peter Taylor,
tak, pomyliłem się przez to, niektóre rozwiązania mają definicję funkcji, a niektóre po prostu używają zmiennej, która nie jest nigdzie zdefiniowana, więc nie jestem pewien, czego powinienem użyć dla bajtecount.
eMBee
Myślę, że odpowiedzi, które widzisz jako „ zmienna, która nie jest nigdzie zdefiniowana ”, w rzeczywistości używają bardzo krótkiej składni deklaracji funkcji. Istnieje jedna lub dwie odpowiedzi, które używają esolangów, które mają specjalne traktowanie dla standardowego wejścia i dlatego sprzyjają pisaniu pełnych programów. Nie znam Pike'a, ale jeśli możesz usunąć białe spacje i skrócić nazwę funkcji, aby uzyskać string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();}, liczę to jako 107 bajtów.
Peter Taylor,
Myślałem, że widziałem kilka, które nie były deklaracjami funkcji, ale wydaje się, że zostały naprawione, tylko przykład smalltalk nie pasuje. jeśli to jest prawidłowe, mógłbym ogolić kolejne 17 bajtów tego ...
eMBee
Wersja Smalltalk jest napisana jako program - w szczególności wyrażenie Workspace. Powiedziano nam, że otrzymujemy dane wejściowe, a nie prośby o pomoc.
Euan M
0

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

„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

Poprzednie wersje

Wyjście 11nn

"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

Wyjście Nov nn

"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

wyjście nn

"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 Jest to dostarczane jako program - w szczególności wyrażenie Workspace - a nie jako metoda.

Zakłada się, że dane wejściowe są dane (zgodnie z frazą „podany maksymalnie czterocyfrowy rok”.
Włączenie deklaracji i podania danych wejściowych dodałoby kolejnych 11 znaków:

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

Dzięki eMBee za pokazanie, jak usunąć jeszcze jeden znak - spację bezpośrednio przed „w”.

W rzeczywistości zainspirowało mnie to do usunięcia spacji przed „d:”:
|y|y:=2015.(12-(Date y:y m:11d:1)w)\\7+1122
Które działało!

Euan M.
źródło
Zgodnie z wyjaśnieniem PO , wersja numeru dnia jest nieprawidłowa.
Mego
Zgadzam się - ale biorąc pod uwagę, że na liście znajduje się kilka wersji tylko z liczbą dni, umieściłem go tam w celu porównania jabłek z jabłkami
Euan
0

Coreutils GNU, 35 bajtów

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

Po prostu przeszukuje tydzień 22-28 listopada w czwartek. Uruchom go w lokalizacji C lub POSIX, ponieważ zależę od tego, że czwartek to jedyny skrót dnia zawierający „h”.


Oto mądrzejsza odpowiedź, choć bajt dłuższy:

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

Pobieramy numer dnia tygodnia w dość arbitralnym tygodniu między marcem a wrześniem (więc dzień i miesiąc są jednocyfrowe, a ewentualny dzień przestępny nie ma na nas wpływu). Wybieramy dzień tak, aby była to niedziela ( %w==0), kiedy Święto Dziękczynienia przypada 28. Następnie możemy odjąć tę wartość od 28, aby uzyskać odpowiedni czwartek.

Toby Speight
źródło
2
Działa, chyba że Sean Connery go uruchomi.
bkul,
0

TSQL, 53 52 bajty

DECLARE @ CHAR(4)=2000

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

Skrzypce

Obliczanie poniedziałku przed lub w dniu 2 września i dodanie 59 dni

(lepsze niż obliczanie poniedziałku przed lub w dniu 4 października i dodawanie 31 dni, ponieważ październik jest 10. miesiącem, oszczędzając w ten sposób 1 bajt)

t-clausen.dk
źródło
-1

Perl, 92 bajty

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

EDYCJA: Naprawiono format wyjściowy, naprawiono błąd, np. Wynik 2012, zastosowano krótszy format „do”. Dzięki msh210.

Steve
źródło
Jest krótszy i robi to samo: use Time::Local;(localtime(timelocal 0,0,0,$_,10,$ARGV[0]))[6]==4?print:0for 22..29. Ale oba skrypty mają te same wady: (1) nie drukują reprezentacji miesiąca zgodnie z wymaganiami; (2) mają błędne dane wyjściowe, np. 2012 r.
msh210,