Jant üzerinde şövalye grim


48

Giriş

Aron Nimzowitsch, önde gelen bir satranç ustası ve etkili bir satranç yazarıydı.

'Sistemim' adlı kitabında, ilk bölüm, merkezin önemi ve neden buna hükmetmeniz gerektiğini ele alıyor. Bunun basit nedeni, taşların merkezde dururken doğrudan oyuncuya daha fazla güç veren doğrudan hamle yapmaktır.

Bu, bir şövalyenin farklı konumlarına ve boş bir tahta üzerindeki sonraki hareketlerine (pembe renkte gösterilen) bakarken çok netleşir:

görüntü tanımını buraya girin

Amaç

Bir şövalyenin potansiyel doğrudan hareketinin sayısını, boş bir tahtanın konumuna göre değerlendirin.

Giriş Özellikleri

Şövalyenin konumu.

Önce x (sütun) ve sonra y (satır). 0 0sol alt köşede.

Basit olması için, satranç tahtasının etiketlerini sadece sayılara değiştirdim. Örneklerimiz ve test durumlarımız için 0 tabanlı bir dizin kullanıyoruz, ancak 1 tabanlı bir dizin kullanmakta özgürsünüz.

Her türlü olası giriş formatını, bir diziyi, işlev değişkenlerini vb. Kullanabilirsiniz.

Çıkış özellikleri

Sıradaki doğrudan potansiyel sayısı boş bir tahtada bir şövalye için hareket eder.

Test Kılıfları

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

Test vakalarında 0 tabanlı bir indeks kullanılıyor. Değerlerin tam listesi:

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

9
Güzel ilk meydan okuma! :-)
Luis Mendo

14
"

2
@stacey Yorumlarınız bu yapboz için harika bir başlık olurdu :)
starcorder

6
Şimdi gerçekten zor bir soru için: Yukarıdaki resimlerdeki kırmızı şövalyeler aynı renkte mi?
mbomb007

Yanıtlar:


25

Python 2,35 bayt

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

Çevrimiçi deneyin!


Python 2,39 bayt

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

Çevrimiçi deneyin!

0 indeksli girişleri alır.

Sentezleme x*(7-x)/5koordinat değerleri alır 0..7için

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

( min(x,7-x,2)aynısını yapar, ancak daha uzundur.) Bunun için toplayın xve ydoğru deseni verin, ancak yanlış numaralarla

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

(Bunun doğru modeli neden verdiğine dair daha iyi bir akıl yürütme için Neil'in çözümüne bakınız .)

Son olarak, a -> 50/(8-a)-4zemin bölünmesi ile haritalama doğru değerleri verir

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

1 indeksli girişe sahip eşit derecede uzun alternatif bir çözüm:

lambda x,y:(x*(9-x)/6+y*(9-y)/6)**2/6+2

(7-a)*a/53 bayttan daha kısa min(a,7-a,2).
Neil

1
*lAslında size genel bir bayt maliyeti lambda a,b:"23468"[(7-a)*a/5+(7-b)*b/5], sadece 41 bayttır.
Neil

@Neil Ben sadece x*(9-x)/6bir indeksli ile aynı şeyi bulmuştum .
xnor

1
Neden <strike>golfün ilerleyişini göstermek için herkes gibi kullanmıyorsun ?
Çılgın

4
@Insane Ben çirkin görünüyor ve aslında yardımcı olmuyor düşünüyorum. Kod önemli bir şeydir ve evrimini görmek isteyen herkesin düzenleme geçmişine bakması gerekir. Eski kod değerinde gösteren olmak için farklı yeterlidir, ben versiyonları gibi göstermek burada . Ancak bu soruda, aynı stratejideki küçük gelişmeler var, bu yüzden farklı olasılıklardan bahsetmeyi daha temiz buldum.
xnor

17

MATL , 17 14 13 12 bayt

@Neil'e 1 byte kapalı teşekkür ederiz!

8:HZ^ZP5X^=s

Giriş 1 tabanlıdır.

Çevrimiçi deneyin!

açıklama

Bu, Euclid'in girişten satranç tahtasındaki 64 konumların her birine olan mesafesini hesaplar ve bu değerlerin kaç tanesinin 5'in kareköküne eşit olduğunu bulur.

Koordinatlar tamsayı değerleri olduğundan, 5'in karekökünü temsil eden iki koordinat değerinin (koordinatlardan hesaplanan ve doğrudan hesaplanan) gerçekten aynı olduğundan emin olabiliriz.

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

1
Etkileyici ve açıklama için teşekkürler
starcorder

1
5 ile 5 arasındaki kareköklerin karelerinin karşılaştırılması, yuvarlama hataları nedeniyle başarısız olursa, en azından 5'in karekökü ile 5'in karekökünü karşılaştıramaz mısınız?
Neil

@Neil Fikir için teşekkürler! Evet, hesaplamalar tam sayılara sahip olduğundan, iki "5 kökün" aynı doublesayı olduğundan emin olabilirim . Karınca bir bayt kazandırır
Luis Mendo

15

Mathematica 63 43 bayt

Martin Ender'in önerileriyle 20 bayt ile kaydedildi!

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

Yukarıdakiler, tüm şövalyeler tur grafiğindeki verilen hücreden 1 atlama uzakta olan karelerin sayısını bulur.


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

şövalyenin tur grafiğini, tepe isimleri ve koordinatlarla gösterir. Mathematica'nın varsayılan olarak koordinatlar için tek tabanlı bir dizine ekleme yapıldığını unutmayın.

grafik


#+1+8#2&[r,f]dönüştürürler , girdi olarak sıfır temelli değerleri kullanarak r, sıradaki kareye (sıra) ve dosyaya (sütun) karşılık gelen tepe noktasını döndürür f.

Örneğin #+1+8#2&[2,1], 11 döndürür.


EdgeCount mahalle grafiğindeki kenar sayısını verir.


2. sıradaki kenarlar, dosya 1 (kare 11):

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

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

Vurgulanan kenarlar:

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]

vurgulamak


Yöntem 2: Öklid mesafesi

70 bayt

Bu yöntem daha uzundur, ancak muhtemelen bir miktar ilgisi vardır. Yaklaşım, satranç tahtasının merkezi ile ilgilenilen hücre arasındaki Öklid mesafesini kontrol etmektir.

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]&

Örneklemek gerekirse

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


Satranç tahtasının ortasından mesafenin bir değer atamak için nasıl yeterli olduğunu görselleştirmeye yardımcı olmak.

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], 

Daire [{4.5, 4.5}, 4],

Daire [{4.5, 4.5}, 4.6], Düzleştir [f / @ {2, 3, 4, 6, 8}, 1]}, Eksenler -> Doğru, AxesOrigin -> {-1, -1}]


2.2, 3, 4 ve 4.6 sayıları dairelerin yarıçaplarıdır.

görüntü


1
Harika bir tur grafiği
starcorder

20
KnightTourGraphMathematica ve yapıları ... :-)
Luis Mendo

#Kaynak kodunuzun sonunda (hemen önce ]) bir sapma olduğunu düşünüyorum . Kullanılacak gerekir IncidenceListyerine EdgeList@NeighborhoodGraphgerçi. (Alternatif olarak, aynı zamanda var EdgeCount, ama sanırım daha uzun
Martin Ender

1
Bekle, aslında daha kısa:EdgeCount[8~KnightTourGraph~8,#+1+8#2<->_]&
Martin Ender

EdgeCountçok havalı!
DavidC,

12

JavaScript (ES6), 38 bayt

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

0 indeksli girişleri alır. Açıklama: Merkeze olan uzaklıkların karelerine bakın:

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

Ulaşılabilir karelerin sayısı beş gruba ayrılır:

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

Aslında, 24,5 - (3,5 - x) ** 2 - (3,5 - y) ** 2 = (7 - x) * x + (7 - y) * y'yi daha kısa bir hesaplama olarak hesaplıyorum, fakat yaptığı işlem tersi. grupların sırası.


Süper özlü ve çok güzel bir yaklaşım, bu yüzden artık kendi JS çözümümü başlatmam
gerekmiyor

Formül ile ilgili yarıçap kare ile aynıdır. Ben düşünmüştü x*(7-x)üzerinde aşağıya doğru bir yay gibi görünüyor bu sadece bir operasyon olarak 0..7uyum eğrisinin olur, ama için özetlenebilir böyle güzel bir desen üreten açıklıyor xve y.
xnor

11

Jöle, 10 bayt

8ṗ2_³²S€ċ5

1 endeksli. Formun tek bir argümanını alır [x,y]. Burada dene.

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

Dennis bir bayt kurtardı!


Sadece on bir bayt, vay!
starcorder

Sabahları bu soruyu gördüm ve zamanım olduğunda Jelly'de uygulayacağımı düşündüğüm kesin algoritma bu. : P
PurkkaKoodari

8

Mathematica, 44 40 bayt

Şu anda aynı bayt sayısında üç çözüm buldum:

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⌋&

Bunların hepsi {3, 4}, 1 tabanlı olan koordinat çiftini alan isimsiz fonksiyonlardır .

Biraz açık bir formül bulmaya çalıştım. Tüm tahtadaki genel kalıp şuna benzer:

görüntü tanımını buraya girin

Bu renklerin gerçek değerleri (en açıktan en koyuya) 2, 3, 4, 6, 8. Yani:

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

Simetriyi ilk önce orijini merkeze kaydırarak, mutlak değeri alarak ve sonucu çıkartarak kullanırız 4. Bu bize koordinatları veriyor 0.5için 3.5her köşesinden artar. Merkez koordinatlarımız haritaya aynı biz gereğini yapmak için 0.5ve 1.5farklı değerler ve 2.5ve 3.5aynı değere. Bu, sonucu çarparak 0.8(verir {0.4, 1.2, 2., 2.8}) ve döşeyerek kolayca yapılır . Yani şimdi {0, 1, 2, 2}merkeze olan mesafelerimiz var . Her hücreye koordinatları eklersek, bu tabloyu alırız:

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

Bunun mümkün olan tüm farklı sonuçlar için benzersiz değerleri vardır, bu yüzden onu basitçe bir indeks olarak kullanırız 2[3,4,6,8].

İkinci versiyonda taban yerine tavan kullanıyoruz. Bu şekilde, 2, 3ve 4zaten doğru, ama biz almak 5ve 6yerine 6ve 8bir ikame kuralına manuel olanlar düzeltmek böylece.

Son olarak, üçüncü versiyonu, biz uzanan 5ve 6yukarı doğru 6ve 8bir kat işlemi takip üs vasıtasıyla.


Tahtanın genel şeklini kullanan yaklaşımı çok seviyorum, harika!
starcorder

6

APL, 21 karakter

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

İngilizcede:

  • (⍳8 8): Tüm hücrelerin koordinatlarını içeren 8x8 rank-2 dizisi;
  • +/¨×⍨(⍳8 8)-⊂⍵: verilen hücrenin öklid mesafelerinin tahtadaki her hücreye göre karesi;
  • 5=: 0/1 matrisi, ki burada 1'ler 5'e eşit kare mesafelerde görünürler;
  • +/,: düzleştirilmiş matrisin toplamı

Test (başlangıç ​​1'de):

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

Bu formda:

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

Sol argüman pano boyutlarını belirleyebilir. Dolayısıyla 8 8 fstandart kare satranç tahtası için çalışacak. Ancak daha büyük ve dikdörtgen bir panoda, test durumları farklı sonuçlar verecektir. Örneğin, 12x10'luk bir panoda:

    g←(10 12)∘f
    g¨1+(3 4)(4 6)(7 7)(1 0)
8 8 8 3

APL jargonunda bir matris, bir rütbe 2 dizisidir, hücrelerin içeriği hakkında hiçbir şey söylenmez. Yılları (ab) terimlerin kullanımı beni buna duyarsız yaptı. Daha geleneksel olarak eğimli okuyucular için açıklamaları güncelleyeceğim. Teşekkür ederim.
lstefano

@Istefano "Boyut" olarak "rütbe" nin kullanılması aynı rahatsızlıktan muzdarip görünüyor:
Luis Mendo

Ben olacağım ... Haklısın! Linear Cebirini kullanmaya başladığımdan bu yana bir süre geçtiğini görüyorsunuz.
Pes

1
Tam program, 27: ≢⍸5=+/¨×⍨-∘⎕¨⍳8 8 Çevrimiçi deneyin!
Adám

@ Adám demek istiyorsun ki 17
ngn

6

Java - 160 150 bayt

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;}

Ungolfed:

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;
}

Ungolfed kod 4 bayt kurtarmak için for döngüsünün sınırlarını değiştirme dışında aynıdır. Her olası hareket boyunca yineleme ve sınır kontrolü gerçekleştirerek çalışır (> 0 ve <8). Ofsetlerin (1, 2), (2, 1), (-1, 2), (-2, 1), vb. Olduğunu ve i ve j'nin her değeri için 2 hareketi kontrol edebildiği gerçeğini kullanır.

Düzenleme: 10 bayt Leaky Nun ve u902383'ün önerileri sayesinde kaydedildi.


Bu da hızlıydı, güzeldi!
starcorder, 28.06.2016

Orada bir hata oluştu, düzeltildi.
ejaszewski

1
int m=0,i=-1,j;bazı baytları kurtarmak için
Leaky Nun

1
mantıksal olarak VE bitsel olarak değiştirin ve bu da ek 6 karakteri kaldırmanıza izin verir
user902383 9


5

Haskell, 49 48 bayt

w=[0..7]
x%y=sum[1|a<-w,b<-w,(a-x)^2+(b-y)^2==5]

1
[0..7]1 baytlık bir değişkene kaydedebilirsiniz .
xnor

5

Java, 81 karakter (113 bayt)

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

Sonuç tablosunun tamamını unicode tablosu olarak kodlayın ve ardından bit yönünde işlemler yaparak uygun baytları alın.

Buradan çevrimiçi olarak görebilirsiniz: https://ideone.com/K9BojC






1

Aslında, 18 bayt

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

Çevrimiçi deneyin!

Bu, pek çok diğer cevaplar kullanıyoruz aynı formülü uygular: 50/(8-x*(7-x)//5+y*(7-y))//5)-4. Giriş bir liste olarak alınır: [x,y](veya Python'da yinelenen değişmez (x,y)veya benzeri x,y).

Açıklama:

`;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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.