Rabu utama

22

Rabu utama

Tugas Anda adalah menghitung jumlah hari Rabu yang jatuh pada hari pertama bulan itu di tahun tertentu. Misalnya, 7-13-16adalah hari Rabu utama. Untuk konsistensi gunakan kalender Gregorian untuk semua tanggal.

Memasukkan

Input untuk program / fungsi Anda akan satu tahun (misalnya 2016) dan fleksibel. Tahun ini akan menjadi bilangan bulat antara 1912 dan 2233 inklusif.

Keluaran

Outputnya juga fleksibel dan harus berupa jumlah hari Rabu utama (mis 18.).

Mencetak gol

Ini adalah sehingga kode terpendek dalam byte menang!

Uji Kasus

input -> output
--------------------
1912 -> 19
1914 -> 16
1984 -> 17
1996 -> 19
2063 -> 19
2150 -> 16
2199 - > 18
2233 -> 18

Buah Nonlinier
sumber

Jawaban:

7

MATL , 38 36 34 byte

FT+"@llI$YO]q&:t8XO!s9\~)9#1$ZOZps

Cobalah online! Atau verifikasi semua kasus uji (butuh beberapa detik).

Penjelasan

FT+     % Input year implicitly. Add [0 1] element-wise. Gives array with input year
        % and next year
"       % For each of those two years
  @     %   Push year
  ll    %   Push 1 twice. This indicates January 1.
  I$YO  %   Convert year, month, day to serial date number
]       % End for each. We now have the serial date number for January 1 of the input
        % year and that of the following year
q       % Subtract 1 to the latter, to yield December 31 of the input year
&:      % Inclusive range between those two numbers. This gives an array of serial date
        % numbers for the whole input year
t       % Push another copy of that array
8XO     % Convert to date string with format 8. This gives weekday as "Mon", "Tue" etc.
        % The result is a 3-column 2D char array, where each row is a day
!s      % Transpose, sum of each column. 'Wed' gives 288 (sum of ASCII codes)
9\~     % 288 gives 0 modulo 9, and is the only weekday to do so. So we compute modulo 9
        % and negate. This gives true for Wednesdays, false for the rest
)       % Apply as logical index into the array of serial date numbers
9#1$ZO  % Array of month numbers corresponding to those serial date numbers
Zp      % Array that contains true for prime numbers, false for the rest
s       % Sum of array. Display implicitly
Luis Mendo
sumber
Saya yakin bahwa MATL tidak dapat dikalahkan pada tantangan berbasis tanggal. Kita harus membuat DATL yang dioptimalkan lebih lanjut untuk menangani tantangan berbasis tanggal.
Suever
@Suever Haha, nama yang bagus
Luis Mendo
20

Python 2, 95 93 68 67 byte

lambda y:0x10ea2c8dbb06c5619/5**((y+((y-22)/99-y/2002)*16)%28)%5+16

Terima kasih kepada @Josay untuk bermain golf 1 byte!

Uji di Ideone .

Dennis
sumber
3
Anda dapat menyimpan 1 char dengan 0x10ea2c8dbb06c5619bukan 19501370182350951961.
SylvainD
Saya mengerti ide big_constant//5**long_expressiontetapi bagaimana Anda bisa datang dengan ekspresi konstan dan itu? Gila: D
Sherlock9
2
Konstanta adalah tabel pencarian sederhana menggunakan basis 5 digit, tetapi dikonversi ke basis 10, sehingga digit diekstraksi secara numerik daripada menggunakan indeks string. Ekspresi seperti kalender abadi bagi saya. (Masalahnya akan terlalu mudah jika terbatas pada tahun-tahun dari 1901 hingga 2099, karena jawabannya berulang setiap 28 tahun dalam interval itu, jadi itu hanya kasus mengambil tahun mod 28 dan mencarinya di tabel. )
Neil
13

Brain-Flak , 6588 , 2310 , 2308 , 2290 byte

Hal pertama yang pertama, saya tidak menulis hampir 100% dari program ini, yang mungkin dibuktikan dengan besarnya ukuran program. Sebagian besar kode ini ditulis oleh algoritma golf Brain-Flak saya sendiri . Seiring dengan skrip python tambahan saya menulis untuk mengarahkannya ke arah yang benar.

Cobalah online!

({}<(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((()()())){}{}){})[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])()())[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])())()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())>[(((((((((()()()()())){}{}){}){}){}){}[()]){}){}){}]){({}[()]<{}>)}{}({}<{{}}>)

Walaupun program ini cukup panjang untuk kode golf, sebenarnya cukup untuk Brain-Flak. Saat ini rekor dunia untuk divisi integer adalah lebih dari 1000 byte.

Penjelasan

Algoritma ini cukup sederhana. Karena ada sejumlah tahun yang tersedia (321), itu hanya mendorong jawaban dalam urutan terbalik di bawah input dan menggunakan algoritma pencarian untuk menemukan jawaban yang benar. Walaupun hardcoding semua 321 kemungkinan mungkin tampak agak tidak efisien dengan tugas serumit yang satu ini dan bahasa yang esoteris seperti brain-flak, mungkin ini adalah solusi terbaik. (Saya berencana untuk mencari tahu dalam minggu mendatang).

Karena sebagian besar dari 321 angka rata-rata sekitar 18 dan mereka sedikit berbeda dari tahun ke tahun alih-alih mendorong semua angka secara individu, saya mendorong tahun pertama (2233) secara normal dan kemudian hanya menduplikasi dan mengubah nilainya sedikit untuk setiap tahun setelah. Dengan cara ini alih-alih membayar untuk mendorong ~ 18 untuk semua 321 tahun, saya hanya membayar untuk mendorong ~ 2 untuk setiap tahun.

Setelah semua jawaban didorong, dikurangi 1912 dari input ({}[(((((((((()()()()())){}{}){}){}){}){}[()]){}){}){}])(Ini mungkin suboptimal, saya menulis ulang pengoptimal untuk melewati nilai-nilai tertentu yang saya yakin tidak akan optimal karena angka hardcoding adalah proses super-eksponensial dan menjalankannya sampai selesai mungkin memiliki diambil beberapa hari).

Kemudian kurangi satu dari elemen pertama dan muncul elemen kedua hingga hasilnya mencapai nol , {({}[()]<{}>)}.

Ini muncul nol, {}dan semua elemen di bawah elemen atas ({}<{{}}>).

Wisaya Gandum
sumber
Apa pendekatan umum untuk angka golf?
Neil
Ide sederhananya adalah jika Anda memiliki angka dengan faktor n dan m Anda menekan n m-1 kali dan kemudian pop m-1 kali. Dorongan awal mengevaluasi n dan setiap pop mengevaluasi sebagai n tambahan, menghasilkan (1 + m-1) (n) yang sama dengan mn. Hal ini dilakukan secara rekursif karena untuk mendorong dan kita harus bermain golf juga. Karena metode ini tidak bekerja dengan baik untuk beberapa bilangan terutama bilangan prima, kami juga melihat sekeliling untuk melihat apakah ada bilangan yang lebih efisien di sekitarnya dan jika demikian kami menyatakan ini sebagai jumlah dari jumlah itu dan perbedaannya.
Wheat Wizard
Begitu ... jadi diberi dua angka ndan mmana yang panjang kdan l, saya anggap n+mpanjangnya k+l? Bagaimana dengan n*m?
Neil
n*makan k+4m-4atau l+4n-4. Ini karena perkaliannya adalah hardcode. Kami pertama n m-1kali mendorong kali. Untuk melakukan ini, kita perlu ksimbol untuk mengekspresikan ndan 2m-2simbol untuk mengekspresikan dorongan (masing-masing dorongan adalah 2 simbol). Lalu kami muncul m-1kali, biaya tambahan kami 2m-2(muncul biaya 2 simbol juga). Ini total k+4m-4. kita juga bisa melipatgandakan m*n(properti komutatif) untuk mendapatkan l+4n-4. Hasilnya akan menjadi lebih pendek dari keduanya.
Wheat Wizard
1
Nah, jika itu benar, maka +1biaya 2, *2biaya 4, *3biaya 8, *4biaya 12, yang lebih mahal daripada *2*2, jadi tidak sepadan (dari angka di bawah 1000 saya hanya menemukan 10 yang tidak menggunakan *2: 1, 2, 3 , 4, 5, 9, 15, 27, 45, 135). Untuk tahun 1912 yang terbaik yang bisa saya lakukan adalah ((((((1+1+1)*2+1)*2*2+1)*2+1)*2+1)*2+1)*2*2*2dengan panjang 52.
Neil
7

Bash + utilitas umum, 39

ncal $1|grep W|factor|egrep -c ': \S+$'

Mengambil tahun input sebagai parameter baris perintah. Biasanya menampilkan pesan seperti ini ke STDERR - Saya pikir ini sah sesuai meta-jawaban ini :

factor: We is not a valid positive integer

Jika Anda ingin secara eksplisit menekan output STDERR maka Anda bisa melakukan ini untuk skor 43 :

ncal $1|grep W|factor 2>-|egrep -c ': \S+$'
Trauma Digital
sumber
Perhatikan bahwa ini mengasumsikan lokal bahasa Inggris atau C / POSIX. Ini tidak berfungsi dengan baik di gd_GB.utf8mana semua nama hari disingkat Di.
Toby Speight
6

Oktaf, 86 byte

Ini tidak cepat, dengan cara apa pun. Tapi itu bukan tujuan dari kode golf, bukan?

function r=p(y)r=0;for(i=698346:7:815953)d=datevec(i);r+=d(1)==y*isprime(d(3));end;end

Oktaf dapat melacak tanggal dengan "nomor tanggal" - jumlah hari yang telah berlalu di mana 1 Jan 0 adalah hari 1. Dengan ukuran ini, 3 Jan 1912 (hari Rabu pertama di set kami) adalah hari 698.346. Mulai di sana, dan ulangi setiap 7 hari (semua hari Rabu) hingga akhir 2233, dan tambahkan 1 jika tahun adalah tahun target DAN hari-bulan adalah yang utama.

dcsohl
sumber
5

Python 2.7, 166 , 165 , 150 byte

from datetime import*
y=input()
d,c=date(y,1,1),0
while d.year==y:n=d.day;c+=n>1<2==d.weekday()>0<all(n%x for x in range(2,n));d+=timedelta(1)
print c

Pasti ada ruang untuk perbaikan di sini. Saya agak baru bermain golf dengan python. Ini menggunakan datetimemodul. Itu loop sepanjang hari dalam setahun menambahkan satu ke akumulator jika sesuai dengan kriteria. Itu kemudian mencetak hasilnya. Sebagian besar pengangkatan berat ada di modul sehingga kode bisa sangat ramping.

Satu byte disimpan berkat Morgan Thrapp dan 15 byte yang disimpan oleh Pietu1998 .

Wisaya Gandum
sumber
1
Anda dapat menyimpan satu byte dengan beralih n%x==0ke n%x<1.
Morgan Thrapp
2
Ini -1tidak perlu karena rangeindeks akhir eksklusif. Selain itu, Anda dapat mengonversikannya filtermenjadi generator. [0for x in range(2,n)if n%x<1]
PurkkaKoodari
Anda bisa menggunakan any(...)atau all(...)bukannya not filter(...).
kennytm
1
Dengan menggabungkan perbandingan berantai dan allAnda dapat menyimpan sejumlah besar. c+=n>1<2==d.weekday()>0<all(n%x for x in range(2,n))
PurkkaKoodari
3

J, 44 byte

+/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)

Saya baru tahu bahwa J memiliki bawaan untuk manipulasi tanggal.

Pemakaian

Perintah tambahan digunakan untuk memformat beberapa input / output.

   f =: +/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)
   (,.f"0) 1912 1914 1984 1996 2063 2150 2199 2233
1912 19
1914 16
1984 17
1996 19
2063 19
2150 16
2199 18
2233 18

Penjelasan

+/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)  Input: year
                                       i.12   The range [0, ..., 11]
                              >:              Increment each to get the months [1, ..., 12]
                                    p:        Get the first 12 primes [2, ..., 37]
                                ,"0/          Make a table between each month and prime
                           ,/                 Join the rows
                       ,.&                    Prepend the year to each
                                              The date format is YYYY MM DD
            3=weekday                         Check if each date occurs on Wednesday
    valdate*                                  and is a valid date
+/@                                           Count the number of true values and return
mil
sumber
1

PowerShell v3 +, 99 95 byte

Pendekatan kekerasan -

param($y)(1..12|%{$m=$_;2,3,5,7,11,13,17,19,23,29,31|?{(date "$m-$_-$y").DayofWeek-eq3}}).Count

Mengambil input $y, loop dari 1ke 12, menyimpan bulan sementara ke dalam $m, kemudian loop setiap prime dari 2ke 31. Untuk masing-masing dari itu, kami membuat a Get-Datedari hari itu, lalu memilih hanya mereka yang DayOfWeek -equal ke 3(yaitu, Rabu). Meringkas bahwa semua dalam parens untuk merumuskan array, dan mengambilnya .Count.


Atau, pendekatan matematika -

PowerShell v3 +, 105 byte

param($y)(16,19,18,20,16,18,19)[($a=(date "1-1-$y").DayOfWeek)]+(1,-3,0,1,2)[$y%5]*($a-in0,2,3,4)*!($y%4)

Akhirnya menjadi hanya rambut lebih panjang dari pendekatan brute force, tapi saya memasukkannya di sini karena mungkin bermanfaat bagi orang lain.

Sekali lagi menerima input $ysebagai tahun. Kali ini kami melakukan operasi matematika ketat berdasarkan pada hari pertama tahun ini. Kami pertama menghitung hari apa dalam minggu itu, dan menyimpannya $auntuk digunakan nanti. Itu indeks ke dalam array pertama, yang memberi kita nomor yang biasanya benar. Kita harus menambahkan bahwa indeks kedua berdasarkan apakah itu tahun kabisat potensial, apakah itu hari Minggu, Selasa, Rabu, atau Kamis, dan berdasarkan tahun berapa itu.

Ini berdasarkan pengamatan berikut. Kolom pertama adalah hari apa pada minggu 1 Januari, yang kedua adalah output biasa. Kecuali jika tahun adalah salah satu angka tengah, maka itu adalah angka di parens. Kolom terakhir menjelaskan cara kerja pengindeksan% 5.

Jan-1 -> #  ... Except if $y=       (then it's this number) | $y % 5 =
Sun   -> 16 ... 1928 1956 1984 etc. (17)                    |    3
Mon   -> 19
Tue   -> 18 ... 1924 1952 1980 etc. (20)                    |    4
Wed   -> 20 ... 1936 1964 1992 etc. (17)                    |    1
Thur  -> 16 ... 1920 1948 1976 etc. (17)                    |    0
Fri   -> 18
Sat   -> 19

Catatan: Kedua asumsi ini en-usadalah pengaturan PowerShell saat ini untuk informasi budaya / tanggal. Pemformatan dan DayOfWeeknomor tanggal mungkin perlu disesuaikan untuk varian budaya lainnya.

AdmBorkBork
sumber
1

Ruby, 83 + 15 ( -rdate -rprimebendera) = 98 byte

Cobalah online! (Modul yang diimpor diikutsertakan karena idk jika saya dapat menggunakan flag di repl.it)

->y{k=0;Prime.each(31){|d|k+=(1..12).count{|m|Date.new(y,m,d).wday==3 rescue p}};k}
Nilai Tinta
sumber
1

JavaScript ES6, 187 182 181 179 byte

179 Ditukar dalam for-loop untuk while-loop

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);for(;a()<=y;c())N+=y-a()?0:-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());return N}

181 Memadatkan terner

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<=y){N+=y-a()?0:-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());c()}return N}

182 Menggabungkan dua loop

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<=y){N+=a()==y?-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b()):0;c()}return N}

187

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<y)c();for(;a()==y;c())N+=-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());return N}
Pandacoder
sumber
Saya tidak berpikir ini diperhitungkan karena Anda telah memberikan Rabu awal pertama untuk tahun tertentu, dalam contoh ini. Tantangan OP menyatakan bahwa itu membutuhkan tahun sebagai satu-satunya parameter ... Upaya besar sejauh ini ...
WallyWest
"Input untuk program / fungsi Anda akan menjadi tahun" - tetapi apa yang Anda tunjukkan bukan itu. Saya menggunakan hari Rabu pertama tahun 1912 sebagai benih karena sebelum atau setiap hari Rabu lainnya dalam periode waktu yang diberikan oleh OP, tetapi saya dapat dengan mudah menggunakan setiap hari Rabu yang sewenang-wenang dari tahun 1911 atau sebelum menabur benih itu juga. Masukan untuk fungsi saya masih satu tahun, dan fungsi masih menghitung jumlah hari Rabu utama pada tahun tertentu dalam kerangka waktu yang disarankan oleh OP, jadi saya tidak yakin bagaimana ini tidak sesuai dengan tantangan.
Pandacoder
Ah, permintaan maaf ... Saya awalnya tidak menyadari Anda menggunakannya sebagai komponen penyemaian ... Ide bagus ... Terutama mengingat solusi Anda mengalahkan tambang sekitar 30 ..;)
WallyWest
1
Terima kasih. Saya mendapatkan inspirasi dari implementasi Brain-Flak Eamon Olive, yang sebenarnya memiliki semua jawaban yang sudah diprogram, menurut penjelasannya.
Pandacoder
1

Batch, 248 byte

@set/ad=0,l=1,n=20
@for /l %%i in (1913,1,%1)do @set/ad=(d+l+1)%%7,l=!(%%i%%4)-!(%%i%%100)+!(%%i%%400)
@goto %l%%d%
:03
:06
@set/an-=1
:12
:13
:16
@set/an-=1
:01
:04
:14
@set/an-=1
:00
:05
:10
:15
@set/an-=1
:02
:11
@echo %n%

Penjelasan: dadalah hari dalam seminggu, dengan 0untuk hari Senin, yang merupakan tanggal 1 Januari 1912. ladalah bendera untuk apakah tahun tersebut merupakan tahun kabisat, 1untuk tahun 1912. Kami kemudian beralih dari tahun 1913 ke tahun input, memperbarui hari dari minggu dan menghitung ulang bendera tahun kabisat saat kita pergi. Akhirnya kami menggunakan bendera tahun kabisat dan hari dalam seminggu untuk mengindeks ke dalam apa yang secara efektif merupakan pernyataan peralihan besar untuk menentukan n, jumlah hari Rabu utama. Menetapkan nke 20 dan menurunkannya dengan jatuh meskipun lebih murah daripada menggunakan logika kontrol aliran, tetapi hasilnya adalah jika tanggal 1 Januari tahun non-kabisat adalah Kamis atau Minggu maka ada 16 Rabu utama dan seterusnya untuk kasus lainnya .

Neil
sumber
1

JavaScript ES6 206 203 199 197 195 183 182 179

Bukan yang terpendek, tapi terbaik yang bisa saya lakukan untuk saat ini ... Saran bermain golf disambut ...

p=n=>--d-1?n%d&&p(n):1;v=Date;D=(x,y)=>new v(x.setDate(x.getDate()-y));W=a=>eval('for(Z=0,z=D(w=new v(a,11,31),(w.getDay()+4)%7);z>new v(a,0,1);)Z+=~~p(d=z.getDate()),z=D(z,7);Z')

Perubahan:

  1. mengubah komponen ternary dari: 3>=x?3-x:10-xke 6-(x+10)%7, hemat: 3 Perubahan ke lokasi deklarasi;
  2. digabung x=w.getDay();z=D(w,6-(x+10)%7)menjadi z=D(w,6-(w.getDay()+10)%7), hemat: 4
  3. bergeser Z=0dari forloop ke Deklarasi tanggal dan mendorong z=D(w,6-(x+10)%7)ke forloop untuk merapikan, menghemat: 2
  4. menggeser w=new Date(a,Z=0,1)deklarasi menjadi forloop, menggabungkan dengan wdeklarasi yang ada , menyimpan: 2
  5. menulis ulang fungsi temuan utama ke fungsi pengujian utama, menghemat: 12
  6. mengubah +!!ke ~~untuk mengurangi dan masih mengonversi p(d=1)dari NaNke 0, memungkinkan fungsi Uji Perdana tetap berfungsi, menghemat: 1
  7. Pindahkan semua fungsi tambahan dari fungsi panggilan utama W, redefined forloop - mundur dari 31 Desember, menulis Dateobjek sebagai variabel terpisah, kemudian menulis ulang forloop menjadi evalpanggilan; hemat 3.

@ PandaCoder, saya menyusul Anda, sobat!

WallyWest
sumber
1

R, 149 147 byte

y=function(x){s=strftime;b=ISOdate
a=seq(b(x,1,1),t=b(x,12,31),b='d')
length(a[s(a,'%u')==3&trimws(s(a,'%e'))%in%c(2,3,5,7,11,13,17,19,23,29,31)])}

Uji di Ideone .

chrki
sumber
0

Groovy, 126

Groovy tidak memiliki validasi bilangan prima, harus membangunnya juga.

{n->p={x->x<3||(2..Math.sqrt(x)).every{x%it}};(new Date("1/1/$n")..new Date("12/31/$n")).collect{it[7]==4&&p(it[5])?it:0}-[0]}
Guci Gurita Ajaib
sumber