Tantangan Anda adalah menulis sebuah program yang, setelah satu tahun, menampilkan jumlah "Friday 13ths" di dalamnya.
Aturan & Detail:
- Anda dapat mengambil input melalui
STDIN
, atau sebagai argumen yang diteruskan ke program Anda. - Anda harus menampilkan hasilnya
STDOUT
. - Anda dapat berasumsi bahwa input akan menjadi tahun yang valid, dan tidak memberi tanggal lebih awal pada kalender Gregorian (perilaku tidak terdefinisi diizinkan dalam kasus-kasus ini).
- Kalender / Pustaka Tanggal diizinkan.
Ini adalah kode-golf , jadi kode terpendek (dalam byte) menang.
Jawaban:
APL (Dyalog APL) dengan kal dari dfns , 29 byte
Cobalah online!
⍳ 12
bilangan bulat satu sampai dua belas⎕ ,¨
mengambil input numerik dan menambahkan masing-masing dari dua belas angka{
...}¨
pada masing-masing pasangan, terapkan fungsinya ...cal⍵
dapatkan kalender untuk tahun-bulan itu2 ↓
turunkan dua baris (keterangan dan hari)⍉
transpos (jadi kita bisa membahas kolom alih-alih baris)¯5 ↑
ambil lima terakhir (dua digit untuk masing-masing hari Jumat dan Sabtu ditambah satu spasi)3 ↑
ambil dua yang pertama (dua digit untuk Jumat ditambah spasi)⍉
transpos (jadi kami mendapat pesanan membaca),
berlepasan⍎
dieksekusi sebagai ekspresi APL (memberikan daftar tanggal Jumat)13 ∊
Apakah tiga belas anggota dari daftar itu?+/
jumlah 12 BooleanDengan menggunakan algoritma @ Wrzlprmft , kita dapat melakukannya tanpa pustaka untuk 53 byte:
-∘0 1
kurangi nol dan satu400 100 4 ∘.|
tabel sisa pembagian selama dua tahun (lintas) dibagi dengan angka-angka ini (turun)0 ≠.=
"produk" dalam dengan 0, tetapi menggunakan ≠ dan = bukannya +. ×⊢ ,
pertahankan tahun argumen yang tidak dimodifikasi2 3 ¯1 +.×
produk dalam dengan angka-angka ini14 |
pembagian divisi ketika dibagi empat belas'21232211321211' ⌷⍨
indeks ke dalam string inisumber
Mathematica
49 46 45 4442Sebagai fungsi murni : 42 karakter
Contoh
Sebagai fungsi bernama : 44 karakter
Contohnya
sumber
f=DayName@{#,m,6}~Table~{m,12}~Count~Friday&
Ruby,
49 48 4746Sunting: Mencukur karakter dengan kembali seminggu, terima kasih kepada Jan, dan lainnya dengan beralih dari Time.new ke Time.gm
Sunting: Dengan mengorbankan sedikit lebih banyak, saya bisa mendapatkan 46 dengan
sumber
Time.gm(m,i).wday<1
. Juga, saya tidak tahu mengapa Anda memberi nama fungsinya.Powershell,
6863585250Terima kasih Iszi atas tipnya.
Menggunakan fakta bahwa jika hari pertama di bulan itu adalah hari Minggu, tanggal 13 akan menjadi hari Jumat.
Saya juga sudah mencoba:
tapi itu tidak sama
$args
di dalam blok skrip.sumber
$n
dengan$args
dalam loop, dan Anda dapat melakukannya tanpa$n=read-host;
sepenuhnya. Menghemat 8. Hapus @, seperti yang disebutkan di atas, dan Anda turun ke 54.$args
untuk$input
, sehingga makan tahun di dari pipa, dan script akan berjalan tapi selalu output 3.R
767257sumber
"%a %d")=="Fri 13"
dengan"%w%d)=="513")
menggunakan dow sebagai angka, dan menghilangkan spasi.seq
satu - satunya pada bulan ini sebenarnya lebih pendek di sini!sum(format(as.Date(paste(scan(),1:12,13,sep="-")),"%w%d")=="513")
hanya 65 karakter!<
akan memaksa karakter ke integer. Trik yang bagus!Python2.7
9086Senin tanggal 9 mungkin tidak memiliki cincin yang sama tetapi berfungsi dengan baik.
Sunting: Satu setengah tahun untuk melihat yang
date
lebih pendek daridatetime
:)sumber
from datetime import*
f=lambda y:sum([date(y,m,13).weekday()==4 for m in range(1,13)])
.... Solusi ukuran yang sama dengan impor (86 byte), meskipun.Tidak menggunakan perpustakaan atau fungsi tanggal bawaan:
Golfscript - 51
Python -
8279Intinya algoritma yang sama.
Dengan menggunakan trik ini , ini dapat diturunkan lebih lanjut ke:
sumber
C
301+287Bukan jawaban terpendek, tetapi tidak menggunakan perpustakaan.
sumber
static char GetNumberOfFriday13s(int year) { const string perpetualCalendar = "1221212213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213112213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122221122213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122221122131"; return perpetualCalendar[year % 400];
. Tidak akan bekerja selama bertahun-tahun negatif.v[0]
seharusnyav[1]
. Anda juga bisa bermain golf ini sedikit; pertimbangkan untuk menggunakanstrcat
, menyimpan karakter untuk langsung dicetaka[]
, dan kurangi konstanta numerik alih-alih konstanta karakter. :)main(int x,char**v){char p[400],*a[]={"1221212213113213","2131222","21122131","1222","112213113","122223113","122221122"},*b="adcadcadcaebcadcadcafbcadcadcagbcadcadcadc";*p=0;for(;*b;b++)strcat(p,a[*b-97]);putchar(p[atoi(v[1])%400]);}
(215 karakter)C (
151145137131130 karakter)Saya terkejut melihat bahwa hanya ada satu solusi lain yang tidak menggunakan alat kalender bawaan. Berikut ini adalah pendekatan matematika (sangat dikaburkan), juga dalam C:
(Kompilasi di atas di GCC tanpa kesalahan)
Solusi alternatif: C (287-> 215 karakter)
Saya agak menikmati solusi Williham Totland dan penggunaan kompresi. Saya memperbaiki dua bug kecil dan mengubah kode untuk mempersingkat panjangnya:
sumber
PHP, 82
<?for($i=1,$c=0;$i<13;$i++)$c+=(date("N",mktime(0,0,0,$i,1,$argv[1]))==7);echo $c;
Berdasarkan
"Setiap bulan yang dimulai pada hari Minggu berisi hari Jumat tanggal 13, dan setidaknya ada satu hari Jumat tanggal 13 di setiap tahun kalender."
Dari http://en.wikipedia.org/wiki/Friday_the_13th
sumber
bash
4736Terima kasih @DigitalTrauma karena telah menyimpan 10 karakter dengan menggunakan
seq
mulai dari awal1
.(Versi sebelumnya menggunakan
echo
bug saat ini karena baris kosong ketika<(echo $1-{1..12}-6$'\n')
. Jadi fungsi ini berfungsi dengan baik sampai hari ini adalah hari Jumat.Ayo lihat:
Apakah tergantung pada lokal , jika tidak berfungsi, Anda mungkin harus
atau
Menjadi suatu fungsi; +7 -> 43
Bonus: +78 -> 121
Dari sana, jika fungsi saya menjadi:
atau
sumber
C
. Tapi ada bug ...%s\\n
seq
untuk menjatuhkan 8 karakter:date -f<(seq -f$1-%g-6 1 12)|grep -c ^F
seq -f$1-%g-6 12|date -f-|grep -c ^F
JavaScript, 70
sumber
,b,c
dari deklarasi fungsi (! Ok itu untuk kebocoran vars untuk golf), juga sebagaib
dilemparkan sebagaiNumber
Anda bisa+=
hasil tes bukan&&b++
:b+=/^F/.test(new Date(a,c,6))
. Namun, Anda dapat menyimpan byte lain, menggunakan!new Date(a,c,1).getDay()
(ini berfungsi karenagetDay
mengembalikan 0 untuk hari Minggu, dan jika tanggal 13 adalah hari Jumat, tanggal 1 akan menjadi hari Minggu) alih-alihtest
yang semuanya akan menghemat 7 byte!k
64 karakter
Baca dari stdin
sumber
Gangguan Umum (CLISP), 149
sumber
C #
1101019392C # Linq 88
Terima kasih kepada Jeppe Stig Nielsen untuk linq dan saran untuk memeriksa minggu pada tanggal 8.
Terima kasih kepada Danko Durbić karena menyarankan
>
alih-alih==
.sumber
c+=(int)new DateTime(y,i,13).DayOfWeek==5?1:0;
, gunakan yang setarac+=new DateTime(y,i,8).DayOfWeek==0?1:0;
. Caranya adalah dengan mengurangi5
, karena dengan begitu Anda dapat menyingkirkan para pemainint
, dan juga jumlahnya8
memiliki satu digit lebih sedikit dari angka tersebut13
. Sunday the Eighth!int g(int y){return Enumerable.Range(1,12).Count(m=>new DateTime(y,m,8).DayOfWeek==0);}
. Tentu saja seperti lambda iniy=>Enumerable.Range(1,12).Count(m=>new DateTime(y,m,8).DayOfWeek==0)
..DayOfWeek<1
.c#
jawaban tetapi tidak yakin bagaimana menerapkannyalinq
.DayOfWeek
dengan bilangan bulat lain selain0
-error CS0019: Operator '<' cannot be applied to operands of type 'System.DayOfWeek' and 'int'
.PHP, 55 byte
Jalankan dengan
echo <year> | php -nR '<code>'
.Pada dasarnya sama dengan yang dicoba Oleg dan Damir Kasipovic , hanya dengan bermain golf yang lebih baik:
Setiap bulan yang dimulai dengan minggu, memiliki hari Jumat tanggal 13.
Jadi saya mengulangi bulan dan menghitung hari-hari pertama minggu.
kerusakan
sumber
K, 42
.
sumber
Bash (
5247 karakter)sumber
Rebol, 63
Contoh penggunaan di konsol Rebol:
Solusi alternatif yang mengumpulkan semua hari Jumat tanggal 13 tahun tertentu adalah:
sumber
Bash and Sed, 39
ncal
mencetak kalender untuk tahun tertentu dengan hari dalam seminggu di sebelah kiri.sed
dengan/g
flag subs semua 13 dengan newlinesgrep -c
menghitung garis yang dimulai dengan "2" (20 selalu mengikuti 13)Terima kasih kepada @DigitalTrauma untuk menemukan bug di versi lama saya dan mengusulkan solusi!
sumber
ncal $1|sed /F/s/13/\\n/g|grep -c ^\ 2
Scala,
7668 karakterDalam 78 karakter:
def f(y:Int)=0 to 11 count(new java.util.GregorianCalendar(y,_,6).get(7)==6)
Tidak ada yang luar biasa, kecuali untuk menggunakan angka ajaib untuk
DAY_OF_WEEK = 7
danFRIDAY = 6
.Versi 68 karakter:
def f(y:Int)=0 to 11 count(new java.util.Date(y-1900,_,6).getDay==5)
Ya, Java mengubah nilai konstanta hari dalam seminggu antara API.
sumber
new java.util.GregorianCalendar
harus begitu lama :(Python 195/204
Hanya berfungsi untuk tahun-tahun sebelumnya, karena
monthdatescalendar
mengembalikan kalender untuk tahun yang diberikan hingga sekarang . Saya pikir ada banyak potensi optimal yang tersisa :).Solusi lain, berfungsi untuk setiap tanggal tetapi tidak lebih kecil:
sumber
Perl 6,
5553Jawaban lama:
sumber
Python (v2) 120
sumber
Perl + lib POSIX 55
Dengan ide tidak mencari
13th
tapi pertama, dan sebagaisunday
adalah0
membiarkan ini Hemat 3 karakter! Terima kasih @ Iszi dan Danko Durbić!Dapat menghitung 2010 hingga 2017 (untuk sampel) dengan cara ini:
(Ok, tidak ada baris baru , tapi itu tidak ditanyakan;)
Posting lama: 63
Beraksi:
sumber
Dalam Smalltalk (Squeak / Pharo flavour), implementasikan metode ini dalam Integer ( 86 karakter)
Kemudian gunakan seperti ini:
2014countFriday13
.Tentu saja, kita bisa menggunakan nama yang lebih pendek, tetapi itu bukan Smalltalk
sumber
C ++ - Terlalu banyak byte :(
Saya mencoba solusi yang tidak menggunakan perpustakaan tanggal apa pun.
Saya menemukan solusi yang cukup keren (jika saya bisa mengatakannya sendiri). Sayangnya saya tidak bisa mendapatkannya lebih pendek dari ini, yang benar-benar mengganggu saya karena rasanya harus ada cara yang lebih baik.
Solusinya bergantung pada algoritma ini yang hanya 44 byte dalam dirinya sendiri. Sayangnya saya perlu 100 byte untuk membungkusnya dengan baik ...
Output melalui kode kembali (dalam C ++, menggunakan
cout
atauprintf
atau sesuatu seperti itu membutuhkan lain#include
, yang akan meledakkan solusi bahkan lebih).Driver / program pengujian:
Output dari program driver:
sumber
($m<3?$y--:$y-2)+3
alih-alihd=13,
,d+=m<3?y--:y-2,
dand+4
harus bekerja juga dan menghemat banyak.+5
bukannya+3
dan-5
harus bekerja juga dan menyimpan 2 byte.for(m=0;++m<13;)
menghemat satu byte. Pindahm=0
ke kepala fungsi menyimpan byte lain; dan pindah()%7||++f
ke kepala loop menyimpan yang lain. Turun dari 149 ke 136 byte.Clojure,
207187 bytes-20 byte dengan menyingkirkan
import
, dan beberapa spasi putih saya lewatkan.Mulai tanggal 1 Janauari pada tahun tertentu, ia berulang setiap hari. Jika hari itu adalah hari Jumat tanggal 13, itu menambah hitungan. Itu terus berulang sampai mencapai tahun berikutnya.
sumber
PHP, tanpa builtin, 81 byte
Jalankan dengan
echo <year> | php -nR '<code>'
.kerusakan
Hari kerja ulangi setiap 400 tahun.
Dalam hasil untuk 1600 hingga 1999 (misalnya), ada periode 28-panjang dengan hanya tiga celah:
Setelah menyesuaikan tahun untuk celah ini, kita bisa mendapatkan hasilnya dengan hash sederhana:
Tidak pendek (95 byte) tetapi cantik. Dan kita bisa bermain golf
sumber
for(;++$m<13;23*$m/9+($m<3?$y--:$y-2)+5+$y/4-$y/100+$y/400)%7?:$f++)$y=$argn;echo$f;
Japt
-x
, 10 byteCobalah
sumber