Knight on the Rim ist Grim


48

Einführung

Aron Nimzowitsch war ein führender Schachmeister und ein einflussreicher Schachautor.

In seinem Buch "Mein System" befasst sich das erste Kapitel mit der Bedeutung des Zentrums und warum Sie es dominieren sollten. Der einfache Grund ist, dass Ihre Figuren in der Mitte mehr Möglichkeiten für direkte nächste Züge haben, was dem Spieler wiederum mehr Kraft verleiht.

Dies wird sehr deutlich, wenn man sich die verschiedenen Positionen eines Ritters und seine möglichen nächsten Züge (in Pink dargestellt) auf einem leeren Brett ansieht:

Bildbeschreibung hier eingeben

Zielsetzung

Bewerten Sie die Anzahl möglicher direkter nächster Züge eines Ritters auf einem leeren Brett anhand seiner Position.

Eingangsspezifikationen

Die Position des Ritters.

Zuerst das x (Spalte) und dann das y (Zeile). 0 0ist die linke untere Ecke.

Der Einfachheit halber habe ich die Bezeichnungen eines Schachbretts nur in Zahlen geändert. Für unsere Beispiele und Testfälle verwenden wir einen 0-basierten Index. Sie können jedoch auch einen 1-basierten Index verwenden.

Sie können alle möglichen Eingabeformate, ein Array, Funktionsargumente usw. verwenden.

Ausgangsspezifikationen

Die Anzahl der möglichen direkten nächsten Züge eines Ritters auf einem leeren Brett.

Testfälle

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

Testfälle verwenden einen 0-basierten Index. Das vollständige Werteraster ist:

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
Schöne erste Herausforderung! :-)
Luis Mendo

14
"Knight on the rim is grim"

2
@stacey Ihr Kommentar wäre ein großartiger Titel für dieses Puzzle gewesen :)
Starcorder

6
Nun zur wirklich schwierigen Frage: Sind die roten Ritter in den obigen Bildern alle gleichfarben?
mbomb007

Antworten:


25

Python 2 , 35 Bytes

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

Probieren Sie es online!


Python 2 , 39 Bytes

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

Probieren Sie es online!

Nimmt Eingänge mit 0-Index.

Der Ausdruck x*(7-x)/5übernimmt die Koordinatenwerte 0..7bis

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

( min(x,7-x,2)macht dasselbe, ist aber länger.) Summiert dies für xund yergibt das richtige Muster, aber mit den falschen Zahlen

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

(Siehe Neils Lösung für eine bessere Begründung, warum dies das richtige Muster ergibt.)

Das Mapping a -> 50/(8-a)-4mit Floor-Division liefert schließlich die richtigen Werte

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

Eine alternative, gleich lange Lösung mit 1-indizierten Eingaben:

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

(7-a)*a/5ist 3 Bytes kürzer als min(a,7-a,2).
Neil

1
*lTatsächlich kostet dich ein Byte insgesamt lambda a,b:"23468"[(7-a)*a/5+(7-b)*b/5]nur 41 Bytes.
Neil

@Neil Ich hatte gerade das Gleiche mit gefunden x*(9-x)/6, einseitig indiziert.
xnor

1
Warum nutzt du es nicht <strike>wie alle anderen, um Golffortschritte zu zeigen?
Insane

4
@Insane Ich finde es sieht hässlich aus und hilft eigentlich nicht. Der Code ist das Wichtigste, und jeder, der seine Entwicklung sehen möchte, muss noch in der Bearbeitungshistorie nachsehen. Wenn mein alter Code so unterschiedlich ist, dass er es wert ist, gezeigt zu werden, zeige ich die Versionen wie hier . Bei dieser Frage handelt es sich jedoch nur um geringfügige Verbesserungen der gleichen Strategie. Ich fand es daher sauberer, nur um die verschiedenen Möglichkeiten zu erwähnen.
Xnor

17

MATL , 17 14 13 12 Bytes

Danke an @Neil für 1 Byte!

8:HZ^ZP5X^=s

Die Eingabe ist 1-basiert.

Probieren Sie es online!

Erläuterung

Dies berechnet den euklidischen Abstand von der Eingabe zu jeder der 64 Positionen im Schachbrett und ermittelt, wie viele dieser Werte der Quadratwurzel von 5 entsprechen.

Da es sich bei den Koordinaten um ganzzahlige Werte handelt, können wir sicher sein, dass die beiden Gleitkommawerte, die die Quadratwurzel von 5 darstellen (die aus den Koordinaten berechnet wurden und die direkt berechnet wurden), tatsächlich identisch sind.

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
Beeindruckend und danke für die Erklärung
Starcorder

1
Wenn der Vergleich des Quadrats der Quadratwurzel von 5 mit 5 aufgrund von Rundungsfehlern fehlschlägt, können Sie dann nicht zumindest die Quadratwurzel von 5 mit der Quadratwurzel von 5 vergleichen?
Neil

@ Neil Danke für die Idee! Ja, da es sich bei Berechnungen um Ganzzahlen handelt, kann ich sicher sein, dass die beiden "Wurzeln von 5" dieselbe doubleZahl sind. Ant es speichert ein Byte
Luis Mendo

15

Mathematica 63 43 Bytes

Mit 20 Bytes gespart dank Vorschlägen von Martin Ender!

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

Oben finden Sie die Anzahl der Quadrate, die 1 Sprung von der angegebenen Zelle entfernt sind, in der vollständigen Ritter-Tour-Grafik.


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

Zeigt das vollständige Tourdiagramm des Ritters mit Scheitelpunktnamen und Koordinaten an. Beachten Sie, dass Mathematica standardmäßig eine einseitige Indexierung für die Koordinaten verwendet.

Graph


#+1+8#2&[r,f]converts gibt den Scheitelpunkt zurück, der dem Quadrat in Rang (Zeile) rund Datei (Spalte) entspricht f, wobei nullbasierte Werte als Eingabe verwendet werden.

Zum Beispiel #+1+8#2&[2,1]gibt 11 zurück.


EdgeCount gibt die Anzahl der Kanten im Nachbarschaftsgraphen an.


Die Kanten für Rang 2, Datei 1 (Quadrat 11):

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

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

Die hervorgehobenen Kanten:

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]

Markieren


Methode 2: Euklidischer Abstand

70 Bytes

Diese Methode ist länger, aber möglicherweise von Interesse. Der Ansatz besteht darin, den euklidischen Abstand zwischen der Mitte des Schachbretts und der interessierenden Zelle zu überprüfen.

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

Vorbildlich

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


Zur Veranschaulichung, wie weit der Abstand von der Mitte des Schachbretts ausreicht, um einen Wert zuzuweisen.

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

Kreis [{4.5, 4.5}, 4],

Kreis [{4.5, 4.5}, 4.6], Abflachen [f / @ {2, 3, 4, 6, 8}, 1]}, Achsen -> Wahr, AchsenOrigin -> {-1, -1}]


Die Zahlen 2.2, 3, 4 und 4.6 sind die Radien der Kreise.

Bild


1
Tolle
Tourgrafik

20
KnightTourGraphMathematica und seine eingebauten ... :-)
Luis Mendo

Ich denke, es gibt einen Fehler #am Ende Ihres Quellcodes (kurz vor dem ]). Sie sollten in der Lage sein, IncidenceListanstatt zu verwenden EdgeList@NeighborhoodGraph. (Alternativ gibt es auch EdgeCount, aber ich denke, das wird länger.)
Martin Ender

1
Oh warte, es ist eigentlich kürzer:EdgeCount[8~KnightTourGraph~8,#+1+8#2<->_]&
Martin Ender

EdgeCountist sehr cool!
DavidC

12

JavaScript (ES6), 38 Byte

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

Nimmt 0-indizierte Eingaben entgegen. Erklärung: Schauen Sie sich die Quadrate der Abstände zum Zentrum an:

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

Die Anzahl der erreichbaren Felder ist in fünf Bereiche unterteilt:

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

Ich berechne tatsächlich 24,5 - (3,5 - x) ** 2 - (3,5 - y) ** 2 = (7 - x) * x + (7 - y) * y, da es eine kürzere Berechnung ist, aber alles, was es tut, ist umgekehrt die Reihenfolge der Bands.


Super prägnante und sehr nette Herangehensweise, damit ich meine eigene JS-Lösung nicht mehr starten muss :)
starcorder

Guter Punkt, wenn die Formel dem Quadrat des Radius entspricht. Ich hatte mir x*(7-x)nur eine Operation vorgestellt, die wie ein abwärts gerichteter Bogen aussieht 0..7und eine Kurvenanpassung durchführt, aber dies erklärt, warum sie ein so schönes Muster ergibt, wenn sie für xund summiert wird y.
xnor

11

Gelee, 10 Bytes

8ṗ2_³²S€ċ5

1-indiziert. Nimmt ein einzelnes Argument des Formulars an [x,y]. Probieren Sie es hier aus.

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

Dennis hat ein Byte gespeichert!


Nur elf Bytes, wow!
Starcorder

Ich habe diese Frage am Morgen gesehen und das ist der genaue Algorithmus, von dem ich dachte, dass ich ihn in Jelly implementieren würde, wenn ich Zeit hätte. : P
PurkkaKoodari

8

Mathematica, 44-40 Bytes

Momentan habe ich drei Lösungen mit derselben Byteanzahl:

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

All dies sind unbenannte Funktionen, die ein Koordinatenpaar annehmen {3, 4}, das auf 1 basiert.

Ich habe versucht, eine etwas explizite Formel zu finden. Das allgemeine Muster auf dem gesamten Board sieht folgendermaßen aus:

Bildbeschreibung hier eingeben

Die tatsächlichen Werte dieser Farben (von hell bis dunkel) sind 2, 3, 4, 6, 8. Das ist:

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

Wir nutzen die Symmetrie zunächst aus, indem wir den Ursprung in die Mitte verschieben, den absoluten Wert nehmen und das Ergebnis von subtrahieren 4. Dies gibt uns Koordinaten, 0.5um 3.5von jeder Ecke zuzunehmen. Um die Mittelpunktkoordinaten die gleiche müssen wir Karte zu machen 0.5und 1.5auf unterschiedliche Werte und 2.5und 3.5auf den gleichen Wert. Dies kann leicht durch Multiplikation mit 0.8(ergibt {0.4, 1.2, 2., 2.8}) und Bodenbildung des Ergebnisses erreicht werden. Jetzt haben wir also {0, 1, 2, 2}möglichst große Entfernungen vom Zentrum. Wenn wir die Koordinaten in jeder Zelle addieren, erhalten wir diese Tabelle:

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

Dies hat eindeutige Werte für alle möglichen Ergebnisse, daher verwenden wir sie einfach als Index für 2[3,4,6,8].

In der zweiten Version verwenden wir Decke statt Boden. Auf diese Weise 2, 3und 4ist schon richtig, aber wir bekommen 5und 6statt 6und 8, so dass wir diejenigen manuell mit einer Substitutionsregel korrigieren.

Schließlich wird in der dritten Version, wir erweitern 5und 6nach oben 6und 8durch Potenzierung von einem anderen Stockwerk Operation folgt.


Mir gefällt der Ansatz, das allgemeine Muster des Boards zu verwenden, sehr gut!
Starcorder

6

APL, 21 Zeichen

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

Auf Englisch:

  • (⍳8 8): 8x8 Rang-2-Array mit den Koordinaten aller Zellen;
  • +/¨×⍨(⍳8 8)-⊂⍵: Quadrat der euklidischen Abstände der gegebenen Zelle in Bezug auf jede Zelle auf dem Brett;
  • 5=: Matrix von 0/1, wobei die Einsen in quadratischen Abständen gleich 5 erscheinen;
  • +/,: summiere die abgeflachte Matrix

Test (in Ursprung 1):

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

In dieser Form:

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

Das linke Argument kann die Abmessungen der Platine angeben. Daher 8 8 fwird für das Standardquadrat Schachbrett arbeiten. Auf einer größeren und rechteckigen Tafel würden die Testfälle jedoch unterschiedliche Ergebnisse liefern. Zum Beispiel auf einer 12x10 Karte:

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

Im APL-Jargon ist eine Matrix ein Array mit Rang 2, nichts sagt über den Inhalt der Zellen aus. Die jahrelange (ab-) Verwendung der Begriffe machte mich dafür unempfindlich. Ich werde die Beschreibung für die traditionelleren Leser aktualisieren. Danke.
lstefano

@Istefano Die Verwendung von "Rang" als "Anzahl der Dimensionen" scheint unter dem gleichen Leiden zu leiden :-P
Luis Mendo

Ich werde ... Du hast recht! Sie können sehen, dass es eine Weile her ist, dass ich Linear Algebra genommen habe. Ich gebe auf :-)
lstefano

1
Volles Programm, 27: ≢⍸5=+/¨×⍨-∘⎕¨⍳8 8 Online ausprobieren!
Adám

@ Adám du meinst 17
ngn

6

Java - 160 bis 150 Bytes

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

Der ungolfed Code ist identisch, außer dass die Grenzen der for-Schleife geändert werden, um 4 Bytes zu sparen. Durchläuft jede mögliche Bewegung und führt eine Grenzprüfung durch (> 0 und <8). Verwendet die Tatsache, dass die Offsets (1, 2), (2, 1), (-1, 2), (-2, 1) usw. sind und in der Lage sind, 2 Züge für jeden Wert von i und j zu überprüfen.

Edit: 10 Bytes gespeichert dank Vorschlägen von Leaky Nun und u902383.


Das ging auch schnell, schön!
Starcorder

Hatte dort einen Fehler, wurde dieser behoben.
Ejaszewski

1
int m=0,i=-1,j;um ein paar Bytes zu retten
Leaky Nun

1
Ändern Sie das logische UND in bitweises UND, um weitere 6 Zeichen zu entfernen
user902383


5

Haskell, 49 48 Bytes

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

1
Sie können [0..7]für 1 Byte in einer Variablen speichern.
xnor

5

Java, 81 Zeichen (113 Bytes)

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

Codieren Sie die gesamte Ergebnistabelle als Unicode-Tabelle und erhalten Sie dann die entsprechenden Bytes, indem Sie bitweise Operationen ausführen.

Sie können es hier online sehen: https://ideone.com/K9BojC


3

Python, 94 Bytes

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)

Verwendet 1-basierte Indizierung.

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


2

Pyth - 33 15 Bytes

Vielen Dank an @LeakyNun für die Reduzierung meiner Größe um die Hälfte.

Das Umstellen der Karten und der Karten Vwird wahrscheinlich dazu führen, dass das Golfen ein wenig ausfällt.

/sM*Fm^R2-Rd8Q5

Test Suite .


1
Das war schnell, nett!
Starcorder




1

Eigentlich 18 Bytes

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

Probieren Sie es online!

Dies implementiert die gleiche Formel , dass viele andere Antworten wurden mit: 50/(8-x*(7-x)//5+y*(7-y))//5)-4. Die Eingabe wird als Liste genommen: [x,y](oder ein beliebiges iterierbares Literal in Python, wie (x,y)oder x,y).

Erläuterung:

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.