Kapan Thanksgiving?

38

Latar Belakang

Beberapa hari libur memiliki tanggal yang tetap dan mudah diingat, seperti 31 Oktober, 25 Desember, dll. Beberapa, bagaimanapun, ingin menyusahkan. Mereka ditentukan sebagai hal-hal seperti "Senin pertama pada bulan September" atau "Kamis keempat pada bulan November". Bagaimana saya bisa tahu kapan itu terjadi?

Yang saya tahu adalah bahwa Thanksgiving mendekat dengan cepat, jadi saya perlu program untuk membantu saya mencari tahu kapan itu. Beberapa orang bahkan mengatakan bahwa ini besok , jadi program Anda harus sesingkat mungkin untuk memastikan saya dapat mengetik ulang tepat waktu.

Tantangan

Buat program atau fungsi yang, diberi tahun hingga empat digit (misalnya 2015 atau 1984), menampilkan atau mengembalikan tanggal Thanksgiving Amerika Serikat pada tahun itu. Hari Thanksgiving didefinisikan sebagai hari Kamis keempat bulan November menurut halaman Wikipedia . (Petunjuk: halaman itu juga menyertakan beberapa informasi menarik tentang pola tanggal.)

Input : angka desimal dengan maksimum empat digit mewakili satu tahun di Common Era (CE). Contoh: 987, 1984, 2101

Keluaran : tanggal, termasuk bulan dan hari, di mana Thanksgiving jatuh, atau akan jatuh jika ada, di tahun itu. Ini mungkin dalam format yang wajar; gunakan penilaian terbaikmu. Gunakan Kalender Gregorian dalam semua kasus, meskipun itu tidak digunakan pada saat itu.

(Catatan: Pastikan untuk menangani tahun kabisat dengan benar!)

Masukan kasus input 1:

2015

Output 1:

Nov 26

Input 2:

1917

Output 2:

Nov 22

Mencetak gol

Pengajuan akan dicetak dalam byte . Saya merekomendasikan situs web ini untuk melacak jumlah byte Anda, meskipun Anda dapat menggunakan penghitung yang Anda suka.

Bonus

-25% dari skor Anda jika Anda menangani tanggal BCE sebagai angka negatif (misalnya -480 akan menjadi tahun pertempuran Thermopylae).

Masukan kasus tes negatif:

-480

Output yang sesuai:

Nov 25

Ini , jadi skor terendah menang!

Sunting: Saya menandai pengajuan TI-BASIC Thomas Kwa sebagai diterima. Jangan biarkan ini menghalangi Anda untuk mengirimkan entri baru!

Papan peringkat

Berikut ini adalah Stack Snippet untuk menghasilkan leaderboard biasa dan gambaran umum pemenang berdasarkan bahasa.

Untuk memastikan bahwa jawaban Anda muncul, silakan mulai jawaban Anda dengan tajuk utama, menggunakan templat Penurunan harga berikut:

# Language Name, N bytes

di mana Nukuran kiriman Anda. Jika Anda meningkatkan skor Anda, Anda dapat menyimpan skor lama di headline, dengan mencoretnya. Contohnya:

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

Jika Anda ingin memasukkan beberapa angka dalam tajuk Anda (mis. Karena skor Anda adalah jumlah dari dua file atau Anda ingin membuat daftar hukuman penterjemah secara terpisah), pastikan bahwa skor sebenarnya adalah angka terakhir di tajuk:

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

Anda juga dapat membuat tautan nama bahasa yang kemudian akan muncul di cuplikan papan peringkat:

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

bkul
sumber
25
Bagi siapa saja yang bertanya-tanya kapan Thanksgiving akan datang tahun ini: Thanksgiving akan besok.
TheNumberOne
6
Tapi saya merayakan Thanksgiving pada tanggal 10 Oktober? Maaf, pertanyaan Anda terlambat.
JimmyJazzx
5
@Downgoat Gunakan penghitung byte mana saja yang Anda inginkan. Itu hanya yang saya gunakan secara pribadi dan akan merekomendasikan.
bkul
22
"Beberapa hari libur menetapkan tanggal yang mudah diingat, seperti 31 Oktober, 25 Desember" Contoh-contoh itu mudah diingat karena mereka benar-benar hari yang sama: 31 oktal == desimal 25. ;-)
Adrian McCarthy
7
Untuk jawaban yang memberikan bonus, haruskah ada tahun 0 antara -1 dan 1 atau tidak?
feersum

Jawaban:

40

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

Diuji pada kalkulator TI-84 + saya

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

Ucapan terima kasih adalah tanggal 29 November, dikurangi hari pada tanggal 1 September, di mana 1 adalah hari Minggu dan 7 adalah hari Sabtu. Ini menghasilkan dalam format MMDD.

Kasus uji: 2015-> 1126, 1917-> 1122, -480-> 1125telah diverifikasi. TI-BASIC tampaknya menggunakan kalender Gregorian untuk semua tanggal.

TI-BASIC tidak mendukung tahun negatif, tetapi ini mendapat bonus karena kami menambahkan 10.000 ke input. Karena kalender Gregorian memiliki periode 400 tahun, ini tidak mengubah hari dalam seminggu.

lirtosiast
sumber
5
Omong kosong xD Saya tidak akan pernah berpikir ini akan bekerja seperti ini, +1.
Addison Crump
Ide bagus untuk menambah 10000. Bagus.
agtoever
Saya menghitung 23 Surat. Bagaimana ini bisa 15 Bytes?
Stephan Schinkel
1
@StephanSchinkel TI-BASIC menggunakan token yang disimpan dalam memori kalkulator, saya percaya semua karakter di sini adalah 1 byte kecuali untuk token dayofWK(dan Ansmasing-masing 2 dan 1 byte.
FryAmTheEggman
Anda mengujinya di kalkulator? Wow.
23

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

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

Mengambil input sebagai argumen baris perintah pertama. Dijalankan dengan peringatan, yang dapat diterima oleh aturan kami. Cetakan NovDD, di mana DDhari Thanksgiving.

Tidak ada tautan online karena ideone tidak mendukung argumen baris perintah dan saya tidak tahu ada penerjemah online yang mendukung.

Terima kasih kepada Alexander O'Mara karena mengajari saya trik baru, dan terutama untuk pengurangan yang signifikan

Mego
sumber
2
Ini lebih lucu dari Mathematica.
lirtosiast
2
@Tryth Bahkan lebih pendek: "4thuXI". Anda bahkan dapat menjatuhkan ruang antara tahun "4thuXI2015".
Alexander O'Mara
1
Menggunakan opsi baris perintah -F, input dapat disingkat menjadi "4thuXI$argn".
primo
3
Tunggu, ini benar-benar berfungsi? Itu ... itu hanya ... Aku bahkan tidak ...
ETHproduk
1
Bekerja untukku . Sementara saya melakukannya, Mdtidak perlu penawaran, dengan E_NOTICEcacat.
primo
18

Mathematica, 59 38 byte

DayRange[{#,11},{#,12},Thursday][[4]]&
LegionMammal978
sumber
+1 Pintar. Ada juga WolframAlpha["Thanksgiving " <> #] &tempat tanggal dimasukkan sebagai string.
DavidC
WolframAlpha mengembalikan tanggal hari Thanksgiving AS dari tahun 1863 (ketika Lincoln menyatakan itu pada Kamis TERAKHIR November) ke depan. AS telah merayakan Thanksgiving sejak 1789.
DavidC
@DavidCarraher Namun, OP menyatakan bahwa program harus bekerja setidaknya untuk 0 - 9999 CE
LegionMammal978
17

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

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

Karena tanggal "mungkin dalam format yang masuk akal", fungsi ini digunakan DD.MM. Saya menulis jawaban TeaScript dengan teknik yang berbeda, tetapi rumus ini lebih pendek.

Penjelasan

Karena bulan berbasis nol, new Date(a,10)mengembalikan Dateobjek yang mewakili 1 November tahun yang ditentukan.

Karena getDay()mengembalikan angka yang mewakili hari dalam seminggu dari yang 0..6ingin kami petakan

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  

lalu tambahkan 22. Ternyata (11 - new Date(a,10).getDay()) % 7akan melakukan trik. Seperti @Thomas Kwa tunjukkan, ini sama dengan 28-new Date(a,8).getDay()yang 28 dikurangi hari minggu 1 September.

intrepidcoder
sumber
Solusi yang bagus, saya suka betapa singkatnya dan masih lebih mudah dimengerti daripada kebanyakan entri.
Marko Grešak
16

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

Japt adalah versi singkat dari Ja vaScri pt .

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

Hahaha, saya menemukan trik yang benar - benar curang: penafsir mengabaikan tanda kurung di dalam string (digunakan untuk memasukkan kode) saat mendekompresinya, sehingga kita dapat mengompres seluruh kode sumber untuk menyimpan byte>: D

Keduanya ?haruslah Unicode unintables U + 0098 dan U + 0085, masing-masing. Cobalah online!

Setelah dekompresi, kode dievaluasi untuk ini:

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

Yang mengevaluasi ke:

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

Yang memberikan output yang tepat.

Menggunakan teknik intrepidcoder , menghasilkan dalam format dd.mm. Mendukung tahun-tahun negatif dengan benar. Saran diterima!

Sunting: Pada 2 Desember, Anda sekarang dapat menggunakan kode 11-byte ini (mencetak 8,25 poin ):

28.11-ÐU8 e

(Saya sangat berharap saya telah menerapkan ini lebih cepat!)

Produksi ETH
sumber
Dilakukan dengan sangat baik.
bkul
Ini sekarang lebih panjang dari JavaScript vanilla. Thomas Kwa memiliki formula yang jauh lebih pendek .
intrepidcoder
@intrepidcoder Terima kasih, sudah diperbaiki.
ETHproduksi
12

Vitsy , 44 byte

Saya menghitung dengan matematika murni !

Golf:

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

Tidak Digubah (memindahkan pemanggilan metode ke baris pertama agar dapat dibaca):

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

V Simpan input sebagai variabel akhir.
 e2 * Tekan 28 ke tumpukan.
    V Dorong input ke tumpukan.
     2- Kurangi dua.
       V4 / D1M- Dapatkan lantai (input / 4).
              + Tambahkan ke total.
               Vaa * Dv / D1M- Dapatkan lantai (input / 100), dan simpan 100 sebagai temp
                                    variabel dalam proses.
                          - Kurangi dari total.
                           Vv4 * / D1M- Dapatkan lantai (input / 400).
                                    + Tambahkan ke total.
                                     7M Modulo oleh tujuh.
                                       - Kurangi hasil dari 28.
                                        baa * / + Tambahkan .11
                                              N Output sebagai angka.

Mungkin ada algoritma yang lebih baik untuk ini (dan ini kemungkinannya adalah golf yang mengerikan), tetapi bagi mereka yang bertanya-tanya, algoritma saya berasal dari sini .

Cobalah online!

Apakah saya mendapatkan poin bonus untuk menghitungnya dan memiliki tepat 42 byte? Mimpi hancur.

Terima kasih kepada @ Hosch250 untuk menunjukkan bahwa saya melakukan kesalahan. : D Diperbaiki.

Addison Crump
sumber
2
Tidak, tetapi Anda mendapatkan +1 dari saya;)
Conor O'Brien
Dikatakan bahwa Thanksgiving pada 2016 adalah 28 November. Ini benar-benar 24 November.
Hosch250
@ Hosch250 Anda benar - diperbaiki sekarang.
Addison Crump
10

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

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

Ini bekerja dengan tahun-tahun negatif dengan cara yang ditentukan dalam pertanyaan, meskipun menarik perhatian saya bahwa tidak ada tahun 0 dalam kalender Gregorian sehingga perilaku ini agak mencurigakan.

Luke
sumber
1
Anda bisa jatuh f=.
feersum
1
Bagaimana cara kerjanya untuk tanggal negatif? Apakah modulo dalam Python berlaku untuk negatif? : O
Addison Crump
Seharusnya lebih pendek menggunakan repetisi string,"Nov "+`...`
xnor
@VoteToClose Python modulo memberikan jawaban dengan tanda yang sama dengan argumen kedua. Jadi -40%7==2tapi-40%-7==-5
kuintopia
@quintopia Tunggu, tunggu, aku idiot. Baik. Itu masuk akal.
Addison Crump
10

JavaScript (ES6), 43.5

Hitungan byte aktual adalah 58. Bonus -25% berlaku => 58 * 0,75 = 43,5

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

Cara yang cukup lurus dan konyol , tanpa penyelesaian atau perhitungan yang rumit.

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

Perhatikan, bahwa memasuki tahun 0-100 menghasilkan 1900-2000 tahun. Padahal, sepertinya 0-100 tahun memberikan tanggal yang sama dengan 1900-2000, dilihat dari jawaban lainnya.


Mengganti a+18dengan 22, karena itu disebut hanya dalam "lain", dan "lain" hanya terjadi jika a tidak lebih besar atau kurang dari 4, yaitu tepat 4.


Mengganti a<4?26-a:a>4?a+21:22dengana<=4?26-a:a+21

nicael
sumber
2
Maafkan saya jika saya salah, tetapi tidak a<4?x:a>4?y:a+18setara dengan a<4?x:a>4?y:22?
ETHproduksi
BTW, ini memberi tahu saya tahun yang salah untuk input dari 0 hingga 99. Namun, tidak yakin apakah ini penting.
ETHproduksi
@Eth LOL tentu saja Anda benar, tidak berpikir itu selalu 4 + 18: D
nicael
Eth hm, 0 hingga 99 memang salah, biarkan saya mencoba memperbaikinya.
nicael
@ Eth Sepertinya 0-100 memberikan tanggal yang sama dengan 1900-2000, dilihat dari jawaban lainnya.
nicael
8

TeaScript, 35 33 24 byte - 25% = 18

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

Ini adalah metode yang sama dengan jawaban JavaScript saya , yang menggunakan rumus pintar Thomas Kwa .

Versi Alternatif dengan Penjelasan

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
sumber
Ini 35 karakter, tetapi 36 byte karena :) :)
nicael
@nicael Bukan oleh situs ini , bukan;)
ETHproduk
Hm, berusia 36 tahun dengan mothereff.in/… .
nicael
@Downgoat biasanya menggunakan format ini , di mana semua karakter hingga U + 00FF adalah 1 byte.
ETHproduksi
5

Jython, 141 155 Bytes

Menggunakan kelas Kalender Java dan Pemindai dengan sintaksis 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)

Sunting: Masalah sintaksis minor, ditambahkan 14 byte.

Lihat juga versi Brainfuck .

Komunitas
sumber
5

Python, 83 81 78 byte

from datetime import*
lambda a:'Nov '+`((10-datetime(a,11,1).weekday())%7)+22`
  • -2 byte: menambahkan nama untuk diimpor (terima kasih @ Κριτικσι Λίθος)
  • -1 byte: diubah menjadi * import ** (terima kasih @FryAmTheEggman)
  • -2 byte: diubah menjadi repr untuk mengonversi hari (terima kasih @willem)
tongkat
sumber
1
Hanya saran untuk mengurangi jumlah byte: gunakan import datetime as ddan kemudian Anda dapat menggunakannya duntuk setiap kali Anda gunakan datetimedalam program Anda.
Kritixi Lithos
2
Anda juga bisa mencoba panda. import pandas;print'Nov '+`((10-pandas.datetime(input(),11,1).weekday())%7)+22`
Willem
@ ΚριτικσιΛίθος tapi kemudian datetime.datetime hanya akan menjadi d.datetime, bukan?
TanMath
2
from datetime import*bahkan sedikit lebih pendek, karena Anda tidak perlu d.lagi
FryAmTheEggman
5

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

Asumsikan tahun diadakan di sel A1, dalam format Tanggal. Mengembalikan bilangan bulat hari pada bulan November di mana Thanksgiving diadakan.

Ini hanya menyumbang tahun kabisat normal. Itu tidak menjelaskan fakta bahwa tahun-tahun, 2100, 2200, 2300 bukan tahun kabisat.

Ini hanya dirancang untuk bekerja pada tahun 1621 dan seterusnya - yaitu sejak Thanksgiving mulai diadakan. (Meskipun pasti akan bekerja sepanjang jalan kembali ke 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"))))))

Cukup dicetak:

=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! Alih-alih menghitung berdasarkan tanggal 1 Januari, kemudian melakukan banyak perhitungan tahun kabisat untuk mengatasi tanggal 29 Februari, saya seharusnya mendasarkan perhitungan pada tanggal 1 November. Nb Ini sekarang berhubungan dengan tahun 2100, 2200 dan 2300 dengan benar. , tetapi membuat implementasinya tergantung pada format tanggal default instalasi Excel Anda. Versi ini dirancang untuk dd / mm / yyyy:

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

Dan sekarang setelah melakukan pfaffing untuk mendapatkan perhitungan singkat di Smalltalk, membuat backport ke Excel menghasilkan:

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

(dengan tahun masih di A1, tetapi sebagai bilangan bulat). Ini bekerja bahkan untuk tahun 2100, 2200 dan 2300, untuk semua tanggal dari 7700BC / E dan seterusnya, menggunakan trik pengulangan tanggal Thomas Kwa.

Euan M
sumber
1
Ketika saya mencoba ini dengan tanggal sebelum 1900 itu tidak berfungsi dalam salinan excel saya.
Angelo Fuchs
Versi panjang tidak berfungsi juga.
Angelo Fuchs
Untuk tanggal lama, gunakan buku kerja pengguna Excel pra-1900 tanggal. < exceluser.com/downloads/examples/post_900_123/index.html >
Euan M
Pertanyaan tentang apakah ini bekerja di samping, saya tidak berpikir Anda diizinkan untuk mengeluarkan tanggal di bulan November; Anda memerlukan "Nov" atau "11" dalam beberapa bentuk.
lirtosiast
@ Thomas Kwa Input tanggal adalah tahun, dalam format tanggal. Perhitungan kemudian bekerja pada hari minggu dimana tanggal 1 November jatuh, lalu menghitung tanggal berapa hari Kamis keempat di bulan November.
Euan M
4

PowerShell, 67 64 84 72 58 45 Bytes

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

Kami mengambil integer input kami sebagai $a, dan segera mengeluarkan Novdan baris baru. Lalu kami mengambil $adan menambahkannya dengan nol dan 1 September dengan 00$a/9/1sebelum menghasilkan yang baru datedan menentukan apa DayOfWeekitu. Jika 1 September adalah pada hari Minggu ( .DayOfWeeksama dengan 0), Thanksgiving pada tanggal 28. Jika 1 September adalah pada hari Senin ( .DayOfWeeksama dengan 1), Thanksgiving pada tanggal 27. Dan seterusnya. Jadi, kita kurangi hari itu dalam seminggu 28untuk mengeluarkan jawaban kita.

Mempertahankan dengan nol ganda menyumbang tahun tunggal dan dua digit tanpa mengganggu penguraian selama tiga atau empat digit tahun. Tidak berfungsi untuk angka negatif, karena .NET datetimetidak mendukung tahun kurang dari 0.

Terima kasih kepada TessellatingHeckler dan Toby Speight untuk bantuannya.

AdmBorkBork
sumber
"{0:D3}/Nov/$_" -f $alebih pendek dari "$($a.ToString("000"))/Nov/$_"dan menghasilkan hasil yang sama, dan saya pikir Anda bisa menggunakan 11bukannyaNov
n0rd
@ n0rd Ah, luar biasa! Ya - Novitu adalah sisa dari ketika saya mencoba untuk membuatnya mengenali dua digit tahun dengan benar, jadi saya akan menukar itu juga. Terima kasih!
AdmBorkBork
@TessellatingHeckler Pendekatan itu berhasil, tetapi Anda perlu menambahkan dua nol ke akun selama satu digit tahun, kalau tidak Anda kembali ke 20XX yang saya temui. Terima kasih atas bantuannya - Saya memperbarui jawabannya.
AdmBorkBork
1
@TessellatingHeckler Di sistem saya, setidaknya, memasukkan tahun satu digit ke dalam date "11/1/$a"hasil Thursday, November 1, 2007 12:00:00 AM. Ini karena kita tidak sedang mengedit properti Calendar.TwoDigitYearMax , jadi ketika ia mem - parsing , kita terjebak dengan double-zero-padding untuk menyiasatinya.
AdmBorkBork
Benar, benar. Padding ganda itu.
TessellatingHeckler
3

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

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

Ini menggunakan rumus Sakamoto untuk hari dalam seminggu. Karena ada orang yang melakukan ini, hasilnya adalah dalam bentuk dd-mm. Kiriman saya sebelumnya dapat ditemukan di bawah:

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

TSQL, 478 296 byte

Hanya untuk bersenang-senang. Biasanya, Anda akan memiliki tabel dimensi tanggal untuk membuatnya menjadi sederhana select * from dimDate where [Year] = @Year and [Holiday] = 'Thanksgiving'namun tanpa adanya ...

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

Tidak Disatukan:

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
sumber
Apakah ini benar-benar jalan terpendek?
lirtosiast
Saya kira saya mungkin tidak terbiasa dengan aturan kode golf, tetapi jawabannya menciptakan objek DB yang menerima input dan mengembalikan output agar sesuai dengan OP. Ada beberapa pemendekan yang dapat terjadi jika input dapat diterima ke dalam kode sebaris tapi ini adalah pemikiran saya untuk tipe objek fungsi. Saya yakin itu bisa golf lebih lanjut dalam kedua kasus. @ ThomasKwa, apakah Anda punya saran?
Peter Vandivier
Nah, menurut saya Anda bisa menggunakan rumus matematika murni yang jawaban ini sebutkan dan tidak repot dengan semua benda tanggal itu.
lirtosiast
bukan solusi matematika murni, tetapi membaca jawaban itu pasti memberi saya beberapa ide untuk mengeluarkan 200 karakter. Terima kasih!!
Peter Vandivier
(Maksud saya (28 - ( x - 2 + floor(x / 4) - floor(x / 100) + floor(x / 400) ) % 7) Ya, membaca jawaban lain cenderung banyak membantu.
lirtosiast
3

Pyth, 30 28 * 75% = 21 byte

Saya 100% positif bahwa ini bisa dibuat lebih pendek, tapi hei, ini program Pyth pertama saya! \Hai/

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

Suite uji

Keluaran tanggal dalam dd.mmformat.

Tolong sarankan cara untuk bermain golf ini jika Anda bisa! Saya ingin belajar lebih banyak tentang Pyth.

Produksi ETH
sumber
2

Unggul, 64 48

Tahun dalam A1

= DATE (A1,11, PILIH (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
sumber
Karena Excel berbasis lokalisasi dan saya ingin menguji ini. Tolong jelaskan apa fungsinya, sehingga saya dapat memilih yang benar dalam bahasa saya.
Angelo Fuchs
1
Juga, ini tidak berfungsi untuk tanggal sebelum 1900 (setidaknya dalam salinan Excel saya)
Angelo Fuchs
Selain itu, Anda menyimpan 13byte TEXTdari =TEXT(DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22),"d mmm")- output adalah bilangan bulat tanpa memformat.
user3819867
@ user3819867, itulah cara excel menyimpan tanggalnya. pemformatan diserahkan kepada pengguna
SeanC
@AngeloFuchs, DATE mengembalikan nilai tanggal, menggunakan tahun, bulan, hari sebagai parameter. MOD mengembalikan bagian sisa dari sebuah divisi (modulus). WEEKDAY mengembalikan hari dalam seminggu dari tanggal (1 = Minggu, 2 = Senin, dll).
SeanC
2

Befunge, 41 Bytes

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

Jalankan penerjemah ini .

Penjelasan: Tahun biasa adalah 365 = 1 mod 7 hari, jadi tahun ditambah setiap tahun ke- 4 , minus setiap tahun ke- 100 ( ddalam ascii), ditambah setiap tahun ke- 400 menyumbang setiap hari kabisat (termasuk tahun ini). Hasil :::4"d"*/\"d"/-\4/++kemudian dapat dianggap sebagai 5 Mar th , hari pertama setelah Februari jatuh pada hari yang sama dengan hari pertama tahun di tahun yang sama. Setelah itu kita mengkalibrasi untuk pola dengan 5+7%-mengurangkan jumlah hari dalam seminggu dari 28 th (yang 47*disimpan sebelumnya) November. Lalu cetak.

Versi yang mengoreksi untuk BC tahun saat ini lebih lama dari yang diberikan bonus, pada 59 -25% = 44,25 byte:

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

Matlab, 78 byte

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

Ruby, 60 58 57 * 0,75 = 42,75 byte

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

58 byte

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

60 byte

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

Tidak Disatukan:

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

Pemakaian:

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

=> Nov 26
Vasu Adari
sumber
0

VBA, 124 byte * 75% = 93 byte

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

Saya tidak yakin jika spasi dihitung, ada di antara 102 dan 124, jangan ragu untuk mengedit.
Jika bilangan bulat adalah output yang valid, saya lebih dari senang untuk menghapus Formatbagian.

pengguna3819867
sumber
Ruang menghitung; jika mereka tidak perlu untuk program ini, Anda dapat menghapusnya.
lirtosiast
0

PHP 5.3+, 59 byte

Ini menggunakan fungsi PHP bawaan strtotimeuntuk mengurai tanggal.

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

Ini mengharapkan nilai yang akan melewati parameter GET Y ATAU lebih php-cli Y=<year>.

Mencoba untuk menemukan Kamis berikutnya setelah 19 November.
Sejauh ini, dengan tes yang saya buat, itu berfungsi dengan baik.

Sadarilah bahwa tahun 2 digit dapat ditafsirkan berbeda.

Saya menggunakan gmdateuntuk menghindari masalah zona waktu, tetapi berfungsi sama baiknya menggunakan date(setidaknya, tempat saya tinggal).

Ismael Miguel
sumber
1
Jawaban bukanlah tempat yang tepat untuk membahas validitas metode input. Saya telah membuat opsi ini di pos meta I / O default (sehingga komunitas dapat memilihnya) dan memindahkan percakapan Anda ke obrolan . (CC @Mego)
Dennis
0

T-SQL 215 byte 248 * 0,75 = 186 byte

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

Tidak disatukan

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

yang dengan perancah tes ini

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

hasil yang diinginkan

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

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

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

meninggalkan yang lama untuk perbandingan karena saya merasa lebih pintar dalam hal memanfaatkan modul Kalender, tetapi cara di atas jauh lebih pendek.

string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();}
eMBee
sumber
Ini sepertinya tidak menerima masukan.
Peter Taylor
ya, saya bingung dengan itu, beberapa solusi memiliki definisi fungsi dan beberapa hanya menggunakan variabel yang tidak didefinisikan di mana saja, jadi saya tidak yakin apa yang seharusnya saya gunakan untuk bytecount.
eMBee
Saya pikir jawaban yang Anda lihat menggunakan " variabel yang tidak didefinisikan di mana saja " sebenarnya menggunakan sintaks deklarasi fungsi yang sangat singkat. Ada satu atau dua jawaban yang menggunakan esolang yang memiliki perlakuan khusus untuk stdin dan sangat suka menulis program lengkap. Saya tidak tahu Pike, tetapi jika Anda bisa menghapus spasi dan menyingkat nama fungsi untuk mendapatkannya string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();}maka saya menghitungnya sebagai 107 byte.
Peter Taylor
Saya pikir saya telah melihat beberapa yang tidak berfungsi deklarasi, tetapi mereka tampaknya telah diperbaiki, hanya contoh smalltalk tidak cocok. jika itu valid saya bisa mencukur 17 byte yang lain ini ...
eMBee
Versi Smalltalk ditulis sebagai program - khususnya ekspresi Workspace. Kami diberi tahu bahwa kami diberi input, bukan meminta masukan.
Euan M
0

Smalltalk - Squeak and 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

Versi sebelumnya

Output 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

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

dalam keluaran

"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 Ini disediakan sebagai program - khususnya ekspresi Workspace - bukan sebagai metode.

Diasumsikan input diberikan (sesuai dengan frasa "diberikan tahun hingga empat digit".
Termasuk menyatakan dan memberi input akan menambah 11 karakter lainnya:

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

Terima kasih kepada eMBee, karena menunjukkan cara menghapus satu karakter lagi - spasi putih sebelum tanda 'w'.

Sebenarnya, itu mengilhami saya untuk mencoba menghapus spasi putih sebelum 'd:':
|y|y:=2015.(12-(Date y:y m:11d:1)w)\\7+1122
Yang berhasil!

Euan M
sumber
Sesuai klarifikasi OP , versi nomor hari tidak valid.
Mego
Saya setuju - tetapi mengingat ada beberapa versi hari-nomor-saja dalam daftar, saya menaruhnya di sana untuk perbandingan apel-ke-apel
Euan M
0

GNU coreutils, 35 byte

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

Cukup cari pada minggu 22-28 November untuk hari Kamis. Jalankan di C atau POSIX lokal, karena saya bergantung pada Kamis menjadi satu-satunya singkatan hari yang mengandung 'h'.


Inilah jawaban yang lebih pintar, meskipun satu byte lebih lama:

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

Kami mengambil nomor hari-minggu dari tanggal dalam minggu yang cukup sewenang-wenang antara Maret dan September (jadi hari dan bulan masing-masing satu digit, dan kami tidak terpengaruh oleh kemungkinan hari kabisat). Kami memilih hari sehingga hari Minggu ( %w==0) saat Thanksgiving tanggal 28. Kami kemudian dapat mengurangi nilai itu dari 28 untuk mendapatkan Kamis yang sesuai.

Toby Speight
sumber
2
Ini berfungsi kecuali Sean Connery menjalankannya.
bkul
0

TSQL, 53 52 byte

DECLARE @ CHAR(4)=2000

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

Biola

Menghitung senin sebelum atau pada 2 september dan menambahkan 59 hari

(lebih baik daripada menghitung Senin sebelum atau pada 4 Oktober dan menambahkan 31 hari karena Oktober adalah bulan ke 10 sehingga menghemat 1 byte)

t-clausen.dk
sumber
-1

Perl, 92 byte

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

EDIT: Memperbaiki format output, memperbaiki bug misalnya hasil 2012, menggunakan format "untuk" yang lebih pendek. Berkat msh210.

steve
sumber
Ini lebih pendek dan melakukan hal yang sama: use Time::Local;(localtime(timelocal 0,0,0,$_,10,$ARGV[0]))[6]==4?print:0for 22..29. Tetapi kedua skrip menderita dari kesalahan yang sama: (1) mereka tidak mencetak representasi bulan seperti yang dipersyaratkan; (2) mereka memiliki output yang salah untuk mis 2012.
msh210