Reines attaquant mutuellement


26

Soit un échiquier 8x8 représenté par deux valeurs distinctes, l'une étant un carré vide et l'autre une reine. Dans les exemples suivants, j'utilise 0 comme carrés vides et 1 comme reines. Par exemple:

Reines sur un échiquier

est donné par

1 0 1 1 1 0 0 0
1 0 1 0 1 0 1 1
1 0 1 0 1 1 0 1
0 1 0 1 0 1 0 0
0 1 1 0 0 1 0 1
1 0 0 0 1 0 0 0
0 1 0 0 0 1 1 1
0 1 1 1 0 1 0 1

Considérez le nombre de paires de reines qui attaquent chacune à au moins un carré de distance (pour rappel, les reines attaquent orthogonalement et en diagonale). Dans l'exemple ci-dessus, l'incroyable diagramme laid suivant montre toutes ces paires sous forme de flèches.

Attaquer les reines

Il y a 43 paires trouvées ci-dessus donnant le cas de test suivant:

Input:
1 0 1 1 1 0 0 0
1 0 1 0 1 0 1 1
1 0 1 0 1 1 0 1
0 1 0 1 0 1 0 0
0 1 1 0 0 1 0 1
1 0 0 0 1 0 0 0
0 1 0 0 0 1 1 1
0 1 1 1 0 1 0 1
Output: 43

Défi

Écrivez un programme qui, étant donné un état de carte représenté par deux valeurs distinctes, génère le nombre de paires de reines qui s’attaquent avec au moins un carré entre elles.

  • Vous pouvez entrer dans le format le plus pratique qui utilise deux valeurs pour représenter les carrés vides et les reines, par exemple, une chaîne de 64 "." S pour les carrés vides et "Q" pour les reines par lignes de bas en haut, un 8x8 matrice de booléens, une liste de liste d'entiers 0 et 1 etc, pour autant que cela soit expliqué dans votre solution
  • La sortie est un entier
  • Les méthodes d'E / S standard s'appliquent et les failles standard interdites
  • C'est le golf de code, donc la réponse la plus courte en octets gagne

Cas de test:

En utilisant le format 0 et 1, 0 étant des carrés vides et 1 des reines:

Input:
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
Output: 0

Input:
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
Output: 0

Input:
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 1 0 0 0 0 1 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
Output: 1

Input:
0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0
0 1 0 0 0 0 1 0
0 0 0 0 1 0 1 0
0 0 0 0 0 0 0 0
0 0 0 1 0 0 1 0
0 0 0 0 0 0 0 0
Output: 10

Input:
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
Output: 4

Input:
1 1 0 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
Output: 11

J'aurais dû demander avant de publier ma 2ème version: 254 pour une reine et 0 pour un carré vide sont-ils des valeurs d'entrée acceptables?
Arnauld

@Arnauld Vous pouvez entrer dans le format le plus pratique qui utilise deux valeurs pour représenter les carrés vides et les reines. Donc c'est bien sûr
JMigst

Merci. J'ai demandé parce que je pense que cette règle pourrait être un peu trop permissive si elle était prise à la lettre. Je pourrais demander de passer une chaîne contenant la plupart du code JS pour les reines et simplement évaluer cela dans le programme. (Mais cela peut être évité par une échappatoire par défaut. Je ne suis pas sûr.)
Arnauld

Réponses:


14

Python 2 , 105 octets

lambda b:sum(b[i+d::d][:(8,7-i%8,i%8)[d%8%5]].find('1')*int(c)>0for i,c in enumerate(b)for d in[1,7,8,9])

Essayez-le en ligne!

Explication

Nous prenons l'entrée comme une chaîne de 64 caractères '0'ou '1'. En utilisant des tranches de pas, nous lançons quatre "lignes de vue" de chaque reine que nous rencontrons. Par exemple, lorsque i = 10 et d = 7 , marquer la reine comme ♥ et les tuiles sélectionnées par b[i+d::d]comme █:

1 0 1 1 1 0 0 0
1 0  0 1 0 1 1
1  1 0 1 1 0 1
 1 0 1 0 1 0 
0 1 1 0 0 1  1
1 0 0 0 1  0 0
0 1 0 0  1 1 1
0 1 1  0 1 0 1

De toute évidence, nous ne voulons pas réellement que la vision s'enroule autour de la planche comme ça. Nous calculons donc à quelle distance le bord de la planche est dans chaque direction et regardons les tuiles à b[i+d::d][:…].

Pour chaque paire direction tuile, nous comptons:

ray.find('1')*int(c)>0

Cela échouera chaque fois

  • cn'est pas une reine; ou
  • la reine que ce rayon voit est trop proche ( findretourne 0); ou
  • ce rayon ne voit pas de reine ( findrenvoie -1).

Chaque paire de reines n'est vérifiée une fois, puisque les rayons sont toujours casted en avant dans l' ordre de lecture, d'un « plus tôt » la reine à un « plus tard ».


10

JavaScript (ES7), 86 octets

Prend l'entrée comme un tableau de 64 entiers avec 254 pour une reine et 0 pour un carré vide.

a=>[s=0,6,7,8].map(d=>a.map(g=(n,p)=>(p%8-(p+=~d)%8)**2<n%4?a[p]?s+=n&1:g(n/2,p):0))|s

Essayez-le en ligne!

Cette version abuse du sous-dépassement arithmétique pour obtenir une condition d'arrêt dans la partie récursive.


JavaScript (ES7), 89 octets

Prend l'entrée comme un tableau de 64 bits.

a=>[s=0,6,7,8].map(d=>a.map(g=(n,p,x)=>(p%8-(p+=~d)%8)**2>1|p<0?0:a[p]?s+=!x&n:g(n,p)))|s

Essayez-le en ligne!

Comment?

Nous appelons récursivement une fonction de rappel nommée de map()pour parcourir les carrés dans une direction donnée. Bien que nous n'ayons pas vraiment besoin du contenu du troisième paramètre du rappel (le tableau a map()été appelé), nous l'utilisons néanmoins indirectement pour savoir s'il s'agit de la première itération ou non.

arr.map (rappel de fonction (currentValue [, index [, array]])

Il s'agit de la variable x dans le code.

a =>                        // given the input array a[]
  [ s = 0,                  // initialize the sum s to 0
    6, 7, 8 ].map(d =>      // for each direction d in [0, 6, 7, 8]:
    a.map(g = (n, p, x) =>  //   for each square n at position p in a[]:
      (                     //     we are out of the board if:
        p % 8 -             //       - abs(p % 8 - p' % 8) is greater than 1
        (p += ~d) % 8       //         where p' = p - (d + 1)
      ) ** 2 > 1 |          //         (squaring is shorter than using Math.abs)
      p < 0 ?               //       - or p' is less than 0
        0                   //       if so, stop recursion
      :                     //     else:
        a[p] ?              //       if there's a queen on the target square:
          s +=              //         increment s if:
            !x &            //           x is undefined (this is not the 1st iteration)
            n               //           and n = 1 (there's a queen on the source square)
        :                   //       else:
          g(n, p)           //         do a recursive call to g(), with x undefined
    )                       //   end of inner map()
  ) | s                     // end of outer map(); return s

8

Escargots , 14 octets

A
rdaa7\1\0+\1

Essayez-le en ligne!

L'entrée est au format 0/1, sans espaces dans les lignes.

Snails a été créé pour un défi PPCG de conception de langage de correspondance de motifs 2D . Plus important encore, il affiche par défaut le nombre de correspondances trouvées, ce qui est parfait pour ce défi.


A définit l'option "tous les chemins", de sorte que si une reine est dans plusieurs paires, chacune de ces paires générerait une correspondance.

rdaa7définit la direction de correspondance sur S, SE, E et NE. La définition de toutes les directions ( z) entraînerait un double comptage.

\1\0+\1correspond à un 1, puis un ou plusieurs 0s, puis un autre 1.


6

APL (Dyalog Classic) , 41 39 32 octets

(+/+⌿-⌈⌿)2<⌿0⍪⊢,⍉,8 31⍴⊢,≠⍨,⌽,≠⍨

Essayez-le en ligne!

≠⍨ est "pas égal à lui-même" - une matrice 8x8 tout à zéro

⊢,≠⍨,⌽,≠⍨- si la matrice d'origine est ABC..., cette expression renvoie:

A B C D E F G H 0 0 0 0 0 0 0 0 H G F E D C B A 0 0 0 0 0 0 0 0
I J K L M N O P 0 0 0 0 0 0 0 0 P O N M L K J I 0 0 0 0 0 0 0 0
Q R S T U V W X 0 0 0 0 0 0 0 0 X W V U T S R Q 0 0 0 0 0 0 0 0
Y Z A B C D E F 0 0 0 0 0 0 0 0 F E D C B A Z Y 0 0 0 0 0 0 0 0
G H I J K L M N 0 0 0 0 0 0 0 0 N M L K J I H G 0 0 0 0 0 0 0 0
O P Q R S T U V 0 0 0 0 0 0 0 0 V U T S R Q P O 0 0 0 0 0 0 0 0
W X Y Z A B C D 0 0 0 0 0 0 0 0 D C B A Z Y X W 0 0 0 0 0 0 0 0
E F G H I J K L 0 0 0 0 0 0 0 0 L K J I H G F E 0 0 0 0 0 0 0 0

8 31⍴ le remodèle de 8x32 à 8x31, en réutilisant les éléments dans l'ordre des lignes principales:

A B C D E F G H 0 0 0 0 0 0 0 0 H G F E D C B A 0 0 0 0 0 0 0
0 I J K L M N O P 0 0 0 0 0 0 0 0 P O N M L K J I 0 0 0 0 0 0
0 0 Q R S T U V W X 0 0 0 0 0 0 0 0 X W V U T S R Q 0 0 0 0 0
0 0 0 Y Z A B C D E F 0 0 0 0 0 0 0 0 F E D C B A Z Y 0 0 0 0
0 0 0 0 G H I J K L M N 0 0 0 0 0 0 0 0 N M L K J I H G 0 0 0
0 0 0 0 0 O P Q R S T U V 0 0 0 0 0 0 0 0 V U T S R Q P O 0 0
0 0 0 0 0 0 W X Y Z A B C D 0 0 0 0 0 0 0 0 D C B A Z Y X W 0
0 0 0 0 0 0 0 E F G H I J K L 0 0 0 0 0 0 0 0 L K J I H G F E

⊢,⍉, ajoute la matrice d'origine et sa transposition (espaces supplémentaires pour plus de clarté):

A B C D E F G H  A I Q Y G O W E  A B C D E F G H 0 0 0 0 0 0 0 0 H G F E D C B A 0 0 0 0 0 0 0
I J K L M N O P  B J R Z H P X F  0 I J K L M N O P 0 0 0 0 0 0 0 0 P O N M L K J I 0 0 0 0 0 0
Q R S T U V W X  C K S A I Q Y G  0 0 Q R S T U V W X 0 0 0 0 0 0 0 0 X W V U T S R Q 0 0 0 0 0
Y Z A B C D E F  D L T B J R Z H  0 0 0 Y Z A B C D E F 0 0 0 0 0 0 0 0 F E D C B A Z Y 0 0 0 0
G H I J K L M N  E M U C K S A I  0 0 0 0 G H I J K L M N 0 0 0 0 0 0 0 0 N M L K J I H G 0 0 0
O P Q R S T U V  F N V D L T B J  0 0 0 0 0 O P Q R S T U V 0 0 0 0 0 0 0 0 V U T S R Q P O 0 0
W X Y Z A B C D  G O W E M U C K  0 0 0 0 0 0 W X Y Z A B C D 0 0 0 0 0 0 0 0 D C B A Z Y X W 0
E F G H I J K L  H P X F N V D L  0 0 0 0 0 0 0 E F G H I J K L 0 0 0 0 0 0 0 0 L K J I H G F E

2<⌿0⍪ajoute des 0 en haut et compare en utilisant <chaque élément contre l'élément en dessous, nous obtenons donc un 1 pour le premier 1 dans chaque groupe vertical de 1, et nous obtenons des 0 partout ailleurs

+⌿-⌈⌿ les sommes par colonne moins les maxima par colonne - nous calculons le nombre d'écarts entre les 1-groupes dans chaque colonne, 0 s'il n'y en a pas

+/ somme



3

Retina 0.8.2 , 60 58 octets

1
¶1$';___¶
_
$n$%`7$*_
(.)(?=.*;(_)*)(?<-2>.)*
$1
m`^10+1

Essayez-le en ligne! Prend l'entrée sous la forme de 8 chaînes binaires de 8 caractères séparées par des virgules, mais l'en-tête convertit le format fourni pour vous. Explication:

1
¶1$';___¶

Créez toutes les sous-chaînes de la planche en commençant par une reine. Suffixez une valeur de marqueur à chaque sous-chaîne. Edit: enregistré 2 octets en laissant quelques chaînes de vidage derrière; ceux-ci sont effectivement ignorés.

_
$n$%`7$*_

Divisez chaque marqueur en une plage inclusive et ajoutez 7 aux éléments non nuls.

(.)(?=.*;(_)*)(?<-2>.)*
$1

Supprimez chaque série de caractères égale à la longueur du marqueur. Cela revient à trouver chaque rayon est, sud-ouest, sud ou sud-est de chaque reine.

m`^10+1

Comptez tous les rayons qui traversent au moins une case vide avant de rencontrer une autre reine.


3

JavaScript (ES6) + SnakeEx , 38 octets

s=>snakeEx.run('m:<*>10+1',s).length/2

Prend la saisie dans le formulaire '10111000\n10101011\n10101101\n01010100\n01100101\n10001000\n01000111\n01110101'. Il s'avère que SnakeEx peut toujours être utilisé en dehors de son défi d'origine!


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.