Knight on the Rim adalah Grim

48

pengantar

Aron Nimzowitsch adalah seorang pemimpin catur terkemuka dan penulis catur yang berpengaruh.

Dalam bukunya 'My System', bab pertama membahas tentang pentingnya pusat dan mengapa Anda harus mendominasinya. Alasan sederhananya adalah bahwa karya Anda memiliki gerakan langsung berikutnya yang lebih mungkin ketika berada di tengah yang lagi memberi pemain lebih banyak kekuatan.

Ini menjadi sangat jelas ketika melihat posisi ksatria yang berbeda dan potensi pergerakan selanjutnya (ditunjukkan dengan warna merah muda) di papan kosong:

masukkan deskripsi gambar di sini

Objektif

Mengevaluasi jumlah gerakan langsung potensial berikutnya dari seorang kesatria pada papan kosong berdasarkan posisinya.

Spesifikasi Input

Posisi ksatria.

Pertama x (kolom) dan kemudian y (baris). 0 0adalah sudut kiri bawah.

Untuk mempermudah, saya mengubah label papan catur menjadi angka saja. Untuk contoh dan kasus uji kami, kami menggunakan indeks berbasis 0, namun Anda bebas untuk menggunakan indeks berbasis 1.

Anda dapat menggunakan semua jenis format input yang mungkin, array, argumen fungsi, dll.

Spesifikasi Keluaran

Jumlah langkah potensial langsung berikutnya untuk seorang ksatria di papan kosong.

Uji Kasus

3 4 => 8
4 6 => 6
7 7 => 2
1 0 => 3

Kasus uji menggunakan indeks berbasis 0. Kotak nilai penuh adalah:

2 3 4 4 4 4 3 2
3 4 6 6 6 6 4 3
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
3 4 6 6 6 6 4 3
2 3 4 4 4 4 3 2
starcorder
sumber
9
Tantangan pertama yang bagus! :-)
Luis Mendo
14
"Knight on the rim is suram"
2
@stacey Komentar Anda akan menjadi judul yang bagus untuk teka-teki ini :)
starcorder
6
Sekarang untuk pertanyaan yang sangat sulit: Apakah ksatria merah pada gambar di atas semua warna yang sama?
mbomb007

Jawaban:

25

Python 2 , 35 byte

lambda x,y:50/(8+x*x/7-x+y*y/7-y)-4

Cobalah online!


Python 2 , 39 byte

lambda x,y:50/(8-x*(7-x)/5-y*(7-y)/5)-4

Cobalah online!

Mengambil input yang diindeks 0.

Ekspresi x*(7-x)/5membawa nilai koordinat 0..7ke

[0, 1, 2, 2, 2, 2, 1, 0]

( min(x,7-x,2)melakukan hal yang sama, tetapi lebih lama.) Menjumlahkan ini untuk xdan ymemberikan pola yang benar tetapi dengan angka yang salah

0 1 2 2 2 2 1 0
1 2 3 3 3 3 2 1
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
1 2 3 3 3 3 2 1
0 1 2 2 2 2 1 0

(Lihat solusi Neil untuk alasan yang lebih baik mengapa ini memberi tentang pola yang tepat.)

Akhirnya, pemetaan a -> 50/(8-a)-4dengan pembagian lantai memberikan nilai yang tepat

2 3 4 4 4 4 3 2
3 4 6 6 6 6 4 3
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
3 4 6 6 6 6 4 3
2 3 4 4 4 4 3 2

Alternatif solusi yang sama panjangnya dengan input 1-diindeks:

lambda x,y:(x*(9-x)/6+y*(9-y)/6)**2/6+2
Tidak
sumber
(7-a)*a/5lebih pendek 3 byte dari min(a,7-a,2).
Neil
1
*lsebenarnya biaya Anda satu byte secara keseluruhan, lambda a,b:"23468"[(7-a)*a/5+(7-b)*b/5]hanya 41 byte.
Neil
@Neil Saya baru saja menemukan hal yang sama dengan x*(9-x)/6, satu-diindeks.
xnor
1
Mengapa tidak Anda gunakan <strike>seperti orang lain untuk menunjukkan perkembangan golf?
Gila
4
@ Insane Saya pikir itu terlihat jelek dan tidak benar-benar membantu. Kode adalah hal yang penting, dan siapa pun yang ingin melihat evolusinya masih perlu melihat dalam sejarah edit. Ketika kode lama saya cukup berbeda untuk ditampilkan, saya menunjukkan versi-versi seperti di sini . Tetapi pada pertanyaan ini, itu semua perbaikan kecil untuk strategi yang sama, jadi saya merasa lebih bersih hanya untuk menyebutkan kemungkinan yang berbeda.
xnor
17

MATL , 17 14 13 12 byte

Terima kasih kepada @Neil selama 1 byte!

8:HZ^ZP5X^=s

Input berbasis 1.

Cobalah online!

Penjelasan

Ini menghitung jarak Euclidean dari input ke masing-masing posisi 64 di papan catur, dan menemukan berapa banyak dari nilai-nilai itu yang sama dengan akar kuadrat dari 5.

Karena koordinat adalah nilai integer, kita dapat yakin bahwa dua nilai floating-point yang mewakili akar kuadrat dari 5 (yang dihitung dari koordinat dan yang dihitung secara langsung) memang sama.

8:      % Push array [1 2 ... 8]
H       % Push 2
Z^      % Cartesian power. Gives 2D array [1 1; 1 2; ... 1 8; 2 1; ... 8 8]     
ZP      % Implicit input. Compute Euclidean distances, considering each row as a point
5X^     % Square root of 5
=s      % Compute how many squared distances equal sqrt(5). Implicit display
Luis Mendo
sumber
1
Mengesankan dan terima kasih atas penjelasannya
starcorder
1
Jika membandingkan kuadrat dari akar kuadrat dari 5 sampai 5 gagal karena kesalahan pembulatan, bisakah Anda setidaknya membandingkan akar kuadrat dari 5 dengan akar kuadrat dari 5?
Neil
@Neil Terima kasih atas idenya! Ya, karena perhitungan menggunakan bilangan bulat, saya dapat yakin bahwa dua "akar 5" adalah angka yang sama double. Ant itu menyimpan byte
Luis Mendo
15

Mathematica 63 43 byte

Dengan 20 byte disimpan berkat saran dari Martin Ender!

EdgeCount[8~KnightTourGraph~8,#+1+8#2/<->_]&

Di atas ditemukan jumlah kotak yang berjarak 1 hop dari sel yang diberikan pada grafik tur ksatria lengkap.


g=KnightTourGraph[8,8,VertexLabels->"Name",Axes->True]

menampilkan grafik tur knight lengkap, dengan nama dan koordinat titik. Perhatikan bahwa Mathematica default ke pengindeksan berbasis satu untuk koordinat.

grafik


#+1+8#2&[r,f]konversi mengembalikan titik yang sesuai dengan kuadrat di peringkat (baris) r,, dan file (kolom) f,, menggunakan nilai-nilai berbasis nol sebagai input.

Misalnya #+1+8#2&[2,1]mengembalikan 11.


EdgeCount memberikan jumlah tepi pada grafik lingkungan.


Tepi untuk peringkat 2, file 1 (persegi 11):

IncidenceList[8~KnightTourGraph~8, 8 #2 + # + 1] &[2, 1]

(*{1 <-> 11, 5 <-> 11, 11 <-> 17, 11 <-> 21, 11 <-> 26, 11 <-> 28}*)

Tepi yang disorot:

HighlightGraph[g, {1, 5, 11, 17, 21, 26, 28, Style[1 <-> 11, Thick, Blue], Style[5 <-> 11, Thick, Blue], Style[11 <-> 17, Thick, Blue], Style[11 <-> 21, Thick, Blue], Style[11 <-> 26, Thick, Blue], Style[11 <-> 28, Thick, Blue]},GraphHighlightStyle -> "DehighlightFade", PlotRangePadding -> .5]

menyoroti


Metode 2: Jarak Euclidean

70 byte

Metode ini lebih panjang, tetapi mungkin menarik. Pendekatannya adalah memeriksa jarak Euclidean antara pusat papan catur dan sel yang diminati.

Which[(x=Sqrt@Tr[({3.5, 3.5}-#)^2])<2.2,8,x<3,6,x<4,4,x<4.6,3,x>4.6,2]&

Contoh

Which[(x=Sqrt@Tr[({3.5, 3.5}-#)^2])<2.2,8,x<3,6,x<4,4,x<4.6,3,x>4.6,2]&@{0, 0}
Which[(x=Sqrt@Tr[({3.5, 3.5}-#)^2])<2.2,8,x<3,6,x<4,4,x<4.6,3,x>4.6,2]&@{3, 3}

2

8


Untuk membantu memvisualisasikan bagaimana jarak dari pusat papan catur cukup untuk menetapkan nilai.

values={{2,3,4,4,4,4,3,2},{3,4,6,6,6,6,4,3},{4,6,8,8,8,8,6,4},{4,6,8,8,8,8,6,4},{4,6,8,8,8,8,6,4},{4,6,8,8,8,8,6,4},{3,4,6,6,6,6,4,3},{2,3,4,4,4,4,3,2}};
f[x_]:=Text[x,#]&/@Position[values,x]r_~w~p_:=RegionMember[{3.5`,3.5`}~Disk~r,p]
h@y_:=Which[2.2~w~y,8,3~w~y,6,4~w~y,4,4.6~w~y,3,2<3,2]

Graphics[{Circle[{4.5, 4.5}, 2.3], Circle[{4.5, 4.5}, 3], 

Lingkaran [{4.5, 4.5}, 4],

Lingkaran [{4.5, 4.5}, 4.6], Ratakan [f / @ {2, 3, 4, 6, 8}, 1]}, Sumbu -> True, AxesOrigin -> {-1, -1}]


Angka 2.2, 3, 4, dan 4.6 adalah jari-jari lingkaran.

gambar

DavidC
sumber
1
Grafik tur luar biasa
starcorder
20
KnightTourGraphMathematica dan bawaannya ... :-)
Luis Mendo
Saya pikir ada nyasar #di akhir kode sumber Anda (tepat sebelum ]). Anda harus dapat menggunakan IncidenceListbukan EdgeList@NeighborhoodGraphsekalipun. (Atau, ada juga EdgeCount, tapi saya pikir itu berakhir lebih lama.)
Martin Ender
1
Oh, tunggu, ini sebenarnya lebih pendek:EdgeCount[8~KnightTourGraph~8,#+1+8#2<->_]&
Martin Ender
EdgeCountsangat keren!
DavidC
12

JavaScript (ES6), 38 byte

(x,y)=>+"23468"[((7-x)*x+(7-y)*y)/5|0]

Mengambil input yang diindeks 0. Penjelasan: Lihatlah kuadrat jarak ke pusat:

24.5 18.5 14.5 12.5 12.5 14.5 18.5 24.5
18.5 12.5  8.5  6.5  6.5  8.5 12.5 18.5
14.5  8.5  4.5  2.5  2.5  4.5  8.5 14.5
12.5  6.5  2.5  0.5  0.5  2.5  6.5 12.5
12.5  6.5  2.5  0.5  0.5  2.5  6.5 12.5
14.5  8.5  4.5  2.5  2.5  4.5  8.5 14.5
18.5 12.5  8.5  6.5  6.5  8.5 12.5 18.5
24.5 18.5 14.5 12.5 12.5 14.5 18.5 24.5

Jumlah kotak yang dapat dijangkau jatuh ke dalam lima pita:

8    0-5
6    5-10
4   10-15
3   15-20
2   20-25

Saya sebenarnya menghitung 24.5 - (3.5 - x) ** 2 - (3.5 - y) ** 2 = (7 - x) * x + (7 - y) * y karena ini perhitungan yang lebih pendek, tetapi yang dilakukannya hanyalah membalikkan urutan band.

Neil
sumber
Pendekatan super ringkas dan sangat bagus, jadi saya tidak perlu memulai solusi JS saya sendiri :)
starcorder
Poin bagus tentang rumus yang setara dengan jari-jari kuadrat. Saya telah memikirkan x*(7-x)sebagai hanya operasi yang terlihat seperti busur ke bawah 0..7dan kebetulan kurva cocok, tetapi ini menjelaskan mengapa itu menghasilkan pola yang bagus ketika dijumlahkan untuk xdan y.
xnor
11

Jelly, 10 byte

8ṗ2_³²S€ċ5

1-diindeks. Membawa argumen tunggal dari formulir [x,y]. Coba di sini.

8ṗ2          Cartesian square [[1,1],[1,2]…[8,8]]
   _³        Subtract the input
     ²S€     Compute the norm of each vector
        ċ5   Count fives

Dennis menyimpan satu byte!

Lynn
sumber
Sebelas byte, wow!
starcorder
Saya melihat pertanyaan ini di pagi hari dan ini adalah algoritma yang tepat yang saya pikir akan saya terapkan di Jelly ketika saya punya waktu. : P
PurkkaKoodari
8

Mathematica, 44 40 byte

Saat ini saya punya tiga solusi pada jumlah byte yang sama:

2[3,4,6,8][[Tr@⌊3.2-.8Abs[#-4.5]⌋]]&
Tr@⌈.85(4-Abs[#-4.5])⌉/.{5->6,6->8}&
⌊Tr@⌈.85(4-Abs[#-4.5])⌉^1.1608⌋&

Semua itu adalah fungsi yang tidak disebutkan namanya yang mengambil pasangan koordinat seperti {3, 4}, yang berbasis 1.

Saya mencoba membuat formula yang agak eksplisit. Pola umum di seluruh papan terlihat seperti ini:

masukkan deskripsi gambar di sini

Nilai aktual dari warna tersebut (dari yang paling terang ke yang paling gelap) adalah 2, 3, 4, 6, 8. Itu adalah:

2 3 4 4 4 4 3 2
3 4 6 6 6 6 4 3
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
3 4 6 6 6 6 4 3
2 3 4 4 4 4 3 2

Kami pertama-tama mengeksploitasi simetri dengan menggeser asal ke pusat, mengambil nilai absolut dan mengurangi hasilnya 4. Ini memberi kita koordinat 0.5untuk 3.5meningkat dari setiap sudut. Untuk membuat koordinat pusat sama, kita perlu memetakan 0.5dan 1.5untuk nilai yang berbeda 2.5dan 3.5ke nilai yang sama. Ini mudah dilakukan dengan mengalikan dengan 0.8(memberi {0.4, 1.2, 2., 2.8}) dan memberi dasar pada hasilnya. Jadi sekarang kita punya {0, 1, 2, 2}jarak dari pusat. Jika kami menambahkan koordinat di setiap sel, kami mendapatkan tabel ini:

0 1 2 2 2 2 1 0
1 2 3 3 3 3 2 1
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
1 2 3 3 3 3 2 1
0 1 2 2 2 2 1 0

Ini memiliki nilai unik untuk semua hasil yang mungkin berbeda, jadi kami cukup menggunakannya sebagai indeks 2[3,4,6,8].

Pada versi kedua kami menggunakan plafon sebagai ganti lantai. Dengan cara ini 2,, 3dan 4sudah benar, tetapi kami mendapatkan 5dan 6bukannya 6dan 8, jadi kami memperbaikinya secara manual dengan aturan substitusi.

Akhirnya, dalam versi ketiga, kami memperluas 5dan 6ke atas ke 6dan 8melalui eksponensial, diikuti oleh operasi lantai lain.

Martin Ender
sumber
Saya sangat menyukai pendekatan menggunakan pola umum dewan, hebat!
starcorder
6

APL, 21 karakter

{+/,5=+/¨×⍨(⍳8 8)-⊂⍵}

Dalam Bahasa Inggris:

  • (⍳8 8): 8x8 peringkat-2 array yang berisi koordinat semua sel;
  • +/¨×⍨(⍳8 8)-⊂⍵: kuadrat dari jarak euclidean sel yang diberikan sehubungan dengan setiap sel di papan;
  • 5=: matriks 0/1, di mana 1s muncul pada jarak kuadrat sama dengan 5;
  • +/,: jumlah matriks yang diratakan

Tes (asal 1):

    f←{+/,5=+/¨×⍨(⍳8 8)-⊂⍵}
    f¨1+(3 4)(4 6)(7 7)(1 0)
8 6 2 3

Dalam bentuk ini:

f←{+/,5=+/¨×⍨(⍳⍺)-⊂⍵}

argumen kiri dapat menentukan dimensi papan. Maka 8 8 fakan bekerja untuk papan catur persegi standar. Tetapi pada papan yang lebih besar dan persegi panjang, kotak uji akan memberikan hasil yang berbeda. Misalnya, pada papan 12x10:

    g←(10 12)∘f
    g¨1+(3 4)(4 6)(7 7)(1 0)
8 8 8 3
lstefano
sumber
Dalam jargon APL, sebuah matriks adalah array dari peringkat 2, tidak ada yang dikatakan tentang konten sel. Bertahun-tahun penggunaan istilah itu membuat saya tidak peka terhadapnya. Saya akan memperbarui deskripsi untuk pembaca yang cenderung lebih tradisional. Terima kasih.
lstefano
@Istefano Bahwa penggunaan "peringkat" sebagai "jumlah dimensi" tampaknya menderita kesengsaraan yang sama :-P
Luis Mendo
Aku akan ... Kamu benar! Anda dapat melihat bahwa sudah lama sejak saya mengambil Linear Algebra. Saya menyerah :-)
lstefano
1
Program lengkap, 27: ≢⍸5=+/¨×⍨-∘⎕¨⍳8 8 Cobalah online!
Adám
@ Adám maksudmu 17
ngn
6

Java - 160 150 byte

int m(int r,int c){int m=0,i,j;for(i=0;i<3;i+=2)for(j=0;j<3;j+=2){m+=r+i>0&r+i<9&c+2*j>1&c+2*j<11?1:0;m+=r+2*i>1&r+2*i<11&c+j>0&c+j<9?1:0;}return m;}

Tidak Disatukan:

public static int m(int r, int c) {
    int m=0;
    for(int i=-1;i<2;i+=2)
        for(int j=-1;j<2;j+=2){
            m += r+i>-1 && r+i<8 && c+2*j>0 && c+2*j<8 ? 1:0;
            m += r+2*i>0 && r+2*i<8 && c+j>1 && c+j<8 ? 1:0;
        }
    return m;
}

Kode ungolfed identik kecuali untuk mengubah batas-batas loop for untuk menghemat 4 byte. Bekerja dengan mengulangi setiap gerakan yang dimungkinkan dan melakukan pemeriksaan batas (> 0 dan <8). Menggunakan fakta bahwa offset adalah (1, 2), (2, 1), (-1, 2), (-2, 1), dll. Dan dapat memeriksa 2 gerakan untuk setiap nilai i dan j.

Sunting: 10 byte disimpan berkat saran dari Leaky Nun dan u902383.

ejaszewski
sumber
Ini juga cepat, bagus!
starcorder
Terjadi kesalahan di sana, telah diperbaiki.
ejaszewski
1
int m=0,i=-1,j;untuk menyimpan beberapa byte
Leaky Nun
1
ubah logika DAN ke bitwise DAN dan itu akan memungkinkan Anda untuk menghapus 6 karakter tambahan
user902383
6

C, 44 Bytes

f(x,y){return "23468"[((7-x)*x+(7-y)*y)/5];}

Tapi ini lebih baik:

f(x,y){return "2344443234666643468888644688886446888864468888643466664323444432"[x*8+y];}
Giacomo Garabello
sumber
1
Hilang ;. Tidak akan dikompilasi.
ugoren
@GiacomoGarabello See: meta.codegolf.stackexchange.com/a/1146/55729
Jacajack
1
Ini bukan cuplikan, ini fungsi dan bukan fungsi posting yang dilarang. Maaf untuk titik koma yang hilang. Tetap.
Giacomo Garabello
5

Haskell, 49 48 byte

w=[0..7]
x%y=sum[1|a<-w,b<-w,(a-x)^2+(b-y)^2==5]
Damien
sumber
1
Anda dapat menyimpan [0..7]ke variabel selama 1 byte.
xnor
5

Java, 81 karakter (113 byte)

int r(int a,int b){return "⍄䐲㑦晃䚈衤䚈衤䚈衤䚈衤㑦晃⍄䐲".codePointAt(a*2+b/4)>>(3-b%4)*4&15;}

Encode seluruh tabel hasil sebagai tabel unicode dan kemudian dapatkan byte yang tepat melakukan operasi bitwise.

Anda dapat melihatnya online di sini: https://ideone.com/K9BojC

cliffroot
sumber
3

Python, 94 byte

lambda x,y,a=[2,1,-1,-2,-2,-1,1,2]:list((9>x+a[i]>0)&(9>y+a[5-i]>0)for i in range(8)).count(1)

Menggunakan 1 pengindeksan berbasis.

Demo di https://repl.it/C6gV .

Chuck Morris
sumber
2

Pyth - 33 15 byte

Terima kasih kepada @LeakyNun untuk mengurangi ukuran saya hingga setengahnya.

Mengatur ulang peta dan Vmungkin akan sedikit golf.

/sM*Fm^R2-Rd8Q5

Test Suite .

Maltysen
sumber
1
Ini cepat, bagus!
starcorder
2
15 byte
Leaky Nun
2

J , 23 bytes

1#.1#.5=[:+&*://]-/i.@8

Cobalah online!

Penghormatan kepada metode Lynn, dikonversi ke J

Jonah
sumber
1

Sebenarnya, 18 byte

`;7-2km`MΣ8-:50\¬¬

Cobalah online!

Ini mengimplementasikan rumus yang sama bahwa banyak jawaban yang lain telah menggunakan: 50/(8-x*(7-x)//5+y*(7-y))//5)-4. Input diambil sebagai daftar: [x,y](atau literal iterable dengan Python, suka (x,y)atau x,y).

Penjelasan:

`;7-2km`MΣ8-:50\¬¬
`;7-2km`M           for each value in input:
 ;7-                  make a copy, subtract from 7
    2                 push 2
     km               minimum of the three values (x, 7-x, 2)
         Σ          sum
          8-        subtract from 8
            :50\    integer divide 50 by the value
                ¬¬  subtract 2 twice
Mego
sumber