Chevalier sur le bord est sinistre


48

introduction

Aron Nimzowitsch était un grand maître d'échecs et un écrivain influent sur les échecs.

Dans son livre «Mon système», le premier chapitre traite de l'importance du centre et des raisons pour lesquelles vous devriez le dominer. La raison simple en est que vos pièces ont plus de possibilités de mouvements directs lorsqu’elles sont au centre, ce qui donne encore plus de puissance au joueur.

Cela devient très clair lorsque vous regardez les différentes positions d’un chevalier et son potentiel de déplacement (indiqué en rose) sur un tableau vide:

entrez la description de l'image ici

Objectif

Évaluez le nombre de déplacements directs potentiels d'un chevalier sur un plateau vide en fonction de sa position.

Spécifications d'entrée

La position du chevalier.

D'abord le x (colonne) et ensuite le y (rangée). 0 0est le coin inférieur gauche.

Pour plus de simplicité, j'ai changé les étiquettes d'un échiquier en chiffres uniquement. Pour nos exemples et cas de test, nous utilisons un index basé sur 0, mais vous êtes libre d'utiliser un index basé sur 1.

Vous pouvez utiliser tout type de formats d'entrée possibles, un tableau, des arguments de fonction, etc.

Spécifications de sortie

Le nombre de potentiels mouvements directs suivants pour un chevalier sur un plateau vide.

Cas de test

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

Les cas de test utilisent un index basé sur 0. La grille de valeurs complète est:

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
Beau premier challenge! :-)
Luis Mendo

14
"Le chevalier sur le rebord est sinistre"

2
@stacey Votre commentaire aurait été un très bon titre pour ce puzzle :)
starcorder

6
Maintenant pour la question très difficile: les chevaliers rouges dans les images ci-dessus sont-ils tous de la même couleur?
mbomb007

Réponses:


25

Python 2 , 35 octets

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

Essayez-le en ligne!


Python 2 , 39 octets

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

Essayez-le en ligne!

Prend les entrées indexées par 0.

L'expression x*(7-x)/5prend les valeurs de coordonnées 0..7pour

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

( min(x,7-x,2)Fait la même chose, mais est plus.) Pour résumer cela pour xet ydonne le bon modèle , mais avec les mauvais chiffres

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

(Voir la solution de Neil pour un meilleur raisonnement expliquant pourquoi cela donne le bon schéma.)

Enfin, la cartographie a -> 50/(8-a)-4avec division du sol donne les bonnes valeurs

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

Une solution alternative de même longueur avec des entrées à 1 index:

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

(7-a)*a/5est 3 octets plus court que min(a,7-a,2).
Neil

1
*lcoûte en fait un octet au total, lambda a,b:"23468"[(7-a)*a/5+(7-b)*b/5]n’est que de 41 octets.
Neil

@ Neil je venais de trouver la même chose, avec x*(9-x)/6un index.
xnor

1
Pourquoi n'utilisez-vous pas, <strike>comme tout le monde, les progrès du golf?
Insane

4
@ Insane Je pense que ça a l'air moche et ça n'aide pas vraiment. Le code est la chose importante, et quiconque veut voir son évolution doit toujours consulter l'historique d'édition. Lorsque mon ancien code est suffisamment différent pour qu'il soit intéressant de le montrer, je montre les versions comme ici . Mais sur cette question, toutes les améliorations mineures apportées à la même stratégie, j'ai donc trouvé plus propre de mentionner les différentes possibilités.
xnor

17

MATL , 17 14 13 12 octets

Merci à @Neil pour 1 octet de moins!

8:HZ^ZP5X^=s

L'entrée est basée sur 1.

Essayez-le en ligne!

Explication

Ceci calcule la distance euclidienne entre l'entrée et chacune des 64 positions de l'échiquier et détermine combien de ces valeurs sont égales à la racine carrée de 5.

Étant donné que les coordonnées sont des valeurs entières, nous pouvons être sûrs que les deux valeurs à virgule flottante représentant la racine carrée de 5 (calculée à partir des coordonnées et calculée directement) sont bien identiques.

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
Impressionnant et merci pour l'explication
starcorder

1
Si la comparaison du carré de la racine carrée de 5 à 5 échoue à cause d’erreurs d’arrondi, ne pouvez-vous pas au moins comparer la racine carrée de 5 à la racine carrée de 5?
Neil

@Neil Merci pour l'idée! Oui, puisque les calculs sont faits avec des entiers, je peux être sûr que les deux "racines de 5" ont le même doublenombre. Pour la sauvegarde d'un octet
Luis Mendo

15

Mathematica 63 43 octets

Avec 20 octets sauvés grâce aux suggestions de Martin Ender!

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

Ce qui précède détermine le nombre de carrés situés à 1 saut de la cellule donnée sur le graphique complet de la tournée des chevaliers.


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

affiche le graphe complet du tour du chevalier, avec les noms et les coordonnées des sommets. Notez que Mathematica utilise par défaut une indexation unique pour les coordonnées.

graphique


#+1+8#2&[r,f]convertts renvoie le sommet correspondant au carré au rang (ligne), ret au fichier (colonne), fen utilisant des valeurs de base zéro en entrée.

Par exemple, #+1+8#2&[2,1]retourne 11.


EdgeCount donne le nombre d'arêtes dans le graphe de voisinage.


Les arêtes du rang 2, fichier 1 (carré 11):

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

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

Les bords surlignés:

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]

surligner


Méthode 2: distance euclidienne

70 octets

Cette méthode est plus longue, mais peut-être d'un certain intérêt. L'approche consiste à vérifier la distance euclidienne entre le centre de l'échiquier et la cellule d'intérêt.

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

Illustrant

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


Pour aider à visualiser comment la distance entre le centre de l’échiquier est suffisante pour attribuer une valeur.

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

Cercle [{4.5, 4.5}, 4],

Cercle [{4.5, 4.5}, 4.6], Aplatir [f / @ {2, 3, 4, 6, 8}, 1]}, Axes -> Vrai, AxesOrigin -> {-1, -1}]


Les nombres 2.2, 3, 4 et 4.6 sont les rayons des cercles.

image


1
Grand tour graphique
starcorder

20
KnightTourGraphMathematica et ses prémices ... :-)
Luis Mendo

Je pense qu'il y a un écart #à la fin de votre code source (juste avant le ]). Vous devriez pouvoir utiliser IncidenceListau lieu de EdgeList@NeighborhoodGraphbien. (Alternativement, il y a aussi EdgeCount, mais je pense que ça finit par être plus long.)
Martin Ender

1
Oh, attendez, c'est en fait plus court:EdgeCount[8~KnightTourGraph~8,#+1+8#2<->_]&
Martin Ender

EdgeCountest très cool!
DavidC

12

JavaScript (ES6), 38 octets

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

Prend des entrées à index 0. Explication: Regardez les carrés des distances au centre:

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

Le nombre de carrés accessibles se divise en cinq bandes:

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

En fait, je calcule 24,5 - (3,5 - x) ** 2 - (3,5 - y) ** 2 = (7 - x) * x + (7 - y) * y car c'est un calcul plus court, mais tout ce qu'il fait est inversé l'ordre des bandes.


Approche super concise et très agréable, donc je n'ai plus à démarrer ma propre solution JS :)
starcorder

Bon point sur la formule étant équivalente au rayon au carré. Je pensais x*(7-x)simplement à une opération qui ressemble à un arc descendant 0..7et qui arrive à ajuster la courbe, mais cela explique pourquoi elle produit un si joli motif quand elle est additionnée pour xet y.
xnor

11

Gelée, 10 octets

8ṗ2_³²S€ċ5

1 indexé. Prend un seul argument de la forme [x,y]. Essayez ici.

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

Dennis a sauvegardé un octet!


Juste onze octets, wow!
starcorder

J'ai vu cette question le matin et c'est l'algorithme exact que je pensais implémenter dans Jelly quand j'avais le temps. : P
PurkkaKoodari

8

Mathematica, 44 40 octets

J'ai actuellement trois solutions au même nombre d'octets:

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

Toutes ces fonctions sont des fonctions non nommées qui prennent une paire de coordonnées du type {3, 4}1.

J'ai essayé de trouver une formule quelque peu explicite. Le schéma général sur tout le tableau ressemble à ceci:

entrez la description de l'image ici

Les valeurs réelles de ces couleurs (du plus clair au plus foncé) sont 2, 3, 4, 6, 8. C'est:

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

Nous exploitons d’abord la symétrie en déplaçant l’origine au centre, en prenant la valeur absolue et en soustrayant le résultat 4. Cela nous donne des coordonnées 0.5à 3.5augmenter de chaque coin. Pour que les coordonnées du centre soient identiques, nous devons mapper 0.5et 1.5sur différentes valeurs 2.5et 3.5sur la même valeur. Cela se fait facilement en multipliant par 0.8(donne {0.4, 1.2, 2., 2.8}) et en recouvrant le résultat. Alors maintenant, nous avons {0, 1, 2, 2}comme distances du centre. Si nous additionnons les coordonnées dans chaque cellule, nous obtenons ce tableau:

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

Cela a des valeurs uniques pour tous les différents résultats possibles, nous l’utilisons donc simplement comme index 2[3,4,6,8].

Dans la deuxième version, nous utilisons plafond au lieu de plancher. De cette façon, 2, 3et 4sont déjà corrects, mais nous obtenons 5et au 6lieu de 6et 8, donc nous corrigeons les manuellement à l' aide d' une règle de substitution.

Enfin, dans la troisième version, nous étendons 5et 6montons vers 6et 8à l'aide d'une exponentiation, suivie d'une autre opération d'étage.


J'aime beaucoup l'approche utilisant le modèle général du conseil, super!
Starcorder

6

APL, 21 caractères

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

En anglais:

  • (⍳8 8): Tableau 8x8 rang-2 contenant les coordonnées de toutes les cellules;
  • +/¨×⍨(⍳8 8)-⊂⍵: carré des distances euclidiennes de la cellule donnée par rapport à chaque cellule du tableau;
  • 5=: matrice de 0/1, où les 1 apparaissent à des distances au carré égales à 5;
  • +/,: somme la matrice aplatie

Test (en origine 1):

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

Sous cette forme:

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

l'argument de gauche peut spécifier les dimensions du tableau. Par conséquent 8 8 ftravaillera pour l'échiquier carré standard. Mais sur un tableau plus grand et rectangulaire, les cas de test donneraient des résultats différents. Par exemple, sur un tableau 12x10:

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

Dans le jargon APL, une matrice est un tableau de rang 2, rien n’est dit sur le contenu des cellules. Des années d'utilisation (ab) des termes m'ont rendu insensible. Je mettrai à jour la description pour les lecteurs plus enclins à la tradition. Je vous remercie.
lstefano

@Istefano Que l'utilisation du "rang" en tant que "nombre de dimensions" semble souffrir du même malheur :-P
Luis Mendo

Je serai ... Tu as raison! Vous pouvez voir que cela fait longtemps que je n'ai pas pris l'algèbre linéaire.
J'abandonne

1
Programme complet, 27 ans: ≢⍸5=+/¨×⍨-∘⎕¨⍳8 8 essayez-le en ligne!
Adám

@ Adám vous voulez dire 17
ngn

6

Java - 160 150 octets

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

Le code non-golfé est identique sauf que vous modifiez les limites de la boucle for pour économiser 4 octets. Fonctionne en parcourant chaque déplacement possible et en effectuant une vérification des limites (> 0 et <8). Utilise le fait que les décalages sont (1, 2), (2, 1), (-1, 2), (-2, 1), etc., et est capable de contrôler 2 coups pour chaque valeur de i et j.

Edit: 10 octets enregistrés grâce aux suggestions de Leaky Nun et de u902383.


C'était aussi rapide, gentil!
Starcorder

S'il y avait une erreur, cela a été corrigé.
ejaszewski

1
int m=0,i=-1,j;pour économiser quelques octets
Lonne Nonne

1
changez logique AND en bit AND et cela vous permettra de supprimer 6 caractères supplémentaires
user902383


5

Haskell, 49 48 octets

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

1
Vous pouvez enregistrer [0..7]dans une variable pour 1 octet.
xnor

5

Java, 81 caractères (113 octets)

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

Encodez l'intégralité de la table de résultats sous forme de table unicode, puis obtenez les octets appropriés lors d'opérations au niveau du bit.

Vous pouvez le voir en ligne ici: https://ideone.com/K9BojC


3

Python, 94 octets

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)

Utilise 1 indexation basée.

Démo sur https://repl.it/C6gV .





1

En fait, 18 octets

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

Essayez-le en ligne!

Ce met en œuvre la même formule que beaucoup d' autres réponses ont utilisé: 50/(8-x*(7-x)//5+y*(7-y))//5)-4. L'entrée est considérée comme une liste: [x,y](ou tout littéral itérable en Python, comme (x,y)ou x,y).

Explication:

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.