Repérer toutes les (anti) diagonales avec des valeurs dupliquées

17

Défi:

Étant donné une entrée matricielle, déterminez la quantité de diagonales et d'anti-diagonales avec des nombres en double.
Donc, si nous avons une matrice comme celle-ci:

[[aa,ab,ac,ad,ae,af],
 [ba,bb,bc,bd,be,bf],
 [ca,cb,cc,cd,ce,cf],
 [da,db,dc,dd,de,df]]

Toutes les diagonales et anti-diagonales seraient:

[[aa],[ab,ba],[ac,bb,ca],[ad,bc,cb,da],[ae,bd,cc,db],[af,be,cd,dc],[bf,ce,dd],[cf,de],[df],
 [af],[ae,bf],[ad,be,cf],[ac,bd,ce,df],[ab,bc,cd,de],[aa,bb,cc,dd],[ba,cb,dc],[ca,db],[da]]

Exemple:

[[1,2,1,2,1,2],
 [1,2,3,4,5,6],
 [6,5,4,3,2,1],
 [2,1,2,1,2,1]]

Toutes les diagonales et anti-diagonales seraient:

[[1],[2,1],[1,2,6],[2,3,5,2],[1,4,4,1],[2,5,3,2],[6,2,1],[1,2],[1],
 [2],[1,6],[2,5,1],[1,4,2,1],[2,3,3,2],[1,2,4,1],[1,5,2],[6,1],[2]]

Suppression de toutes les diagonales et anti-diagonales contenant uniquement des numéros uniques:

[[2,3,5,2],[1,4,4,1],[2,5,3,2],[1,4,2,1],[2,3,3,2],[1,2,4,1]]

La sortie est donc la quantité de diagonales et d'anti-diagonales contenant des nombres en double:

6

Règles du défi:

  • Si la matrice d'entrée est vide, ne contient qu'un seul nombre ou ne contient que des nombres uniques sur toute la matrice, la sortie est toujours 0.
  • L'entrée est garantie de ne contenir que des chiffres positifs [1,9](sauf si elle est complètement vide).
  • La matrice sera toujours rectangulaire (c'est-à-dire que toutes les lignes ont la même longueur).
  • Les E / S sont flexibles. L'entrée peut être considérée comme une liste de listes d'entiers, ou un tableau 2D d'entiers, ou un objet Matrix, comme une chaîne, etc. etc. Vous êtes également autorisé à prendre une ou les deux dimensions de la matrice comme entrée supplémentaire. s'il sauverait des octets dans la langue de votre choix.

Règles générales:

  • C'est le , donc la réponse la plus courte en octets l'emporte.
    Ne laissez pas les langues de golf de code vous décourager de publier des réponses avec des langues autres que le golf de code. Essayez de trouver une réponse aussi courte que possible pour «n'importe quel» langage de programmation.
  • Des règles standard s'appliquent à votre réponse avec des règles d'E / S par défaut , vous êtes donc autorisé à utiliser STDIN / STDOUT, des fonctions / méthodes avec les paramètres appropriés et des programmes complets de type retour. Ton appel.
  • Les failles par défaut sont interdites.
  • Si possible, veuillez ajouter un lien avec un test pour votre code (par exemple TIO ).
  • De plus, l'ajout d'une explication à votre réponse est fortement recommandé.

Cas de test:

Input:                     Output:

[[1,2,1,2,1,2],            6
 [1,2,3,4,5,6],
 [6,5,4,3,2,1],
 [2,1,2,1,2,1]]

[[]]                       0

[[1,2],                    0
 [3,4]]

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

[[9,9,9],                  6
 [9,9,9],
 [9,9,9]]

[[7,7,7,7],                8
 [7,7,7,7],
 [7,7,7,7]]

[[1,1,1],                  1
 [2,3,4],
 [2,5,1]]

[[1,8,4,2,9,4,4,4],        12
 [5,1,2,7,7,4,2,3],
 [1,4,5,2,4,2,3,8],
 [8,5,4,2,3,4,1,5]]

[[1,2,3,4],                4
 [5,6,6,7],
 [8,6,6,9],
 [8,7,6,5]]
Kevin Cruijssen
la source

Réponses:

4

Gelée , 10 octets

ŒD;ŒdQƑÐḟL

Essayez-le en ligne! ou Découvrez la suite de tests!

Alternatives:

ŒD;ŒdQƑ€¬S
ŒD;ŒdQƑ€ċ0

Comment ça fonctionne?

ŒD;ŒdQƑÐḟL – Monadic link / Full program.
  ;        – Join:
ŒD           – The diagonals
             with
   Œd        – The anti-diagonals.
       Ðḟ  – Discard the lists that are not:
     QƑ      – Invariant under deduplication.
         L – Length (count them).
M. Xcoder
la source
10

R , 92 86 82 78 octets

function(m,x=row(m),y=col(m),`|`=split,`^`=Map)sum(max^table^c(m|x-y,m|x+y)>1)

Essayez-le en ligne!

Explication

Xy

X-y

0 -1 -2 -3 1 0 -1 -2 2 1 0 -1 3 2 1 0

X+y

2 3 4 5 3 4 5 6 4 5 6 7 5 6 7 8

Maintenant split(m, x-y)etsplit(m, x+y) produisons les listes réelles des diagonales et des anti-diagonales, que nous réunissons.

Enfin, nous comptons les entrées de la liste résultante où des doublons sont présents.

Merci pour les octets enregistrés:

-4 par CriminallyVulgar
-4 par digEmAll

Kirill L.
la source
1
Je suppose que je peux ajouter rowet colà ma liste de «fonctions extrêmement situationnelles». Solution vraiment intelligente.
CriminallyVulgar
1
Je pense que vous pouvez déplacer la c(m|x-y,m|x+y)ligne droite dans l'appel sévère, retirer la l=partie. Je ne vois aucun test ayant échoué. Essayez-le en ligne!
CriminallyVulgar
Oui, c'est exact, j'ai juste raté qu'après mon premier golf, il ne restait qu'une seule linstance.
Kirill L.
1
Ils doivent avoir ajouté les fonctions rowet columnà R ce matin, car je n'en ai jamais entendu parler.
ngm
5

J , 21 20 octets

-1 octet merci à Jonah!

1#.|.,&((~:&#~.)/.)]

Essayez-le en ligne!

Explication:

1#.                   find the sum of the  
     ,                concatenation of
       (          )   the result of the verb in the parentheses applied to
                   ]  the input
      &               and
   |.                 the reversed input
        (      )/.    for each diagonal
         ~:&#~.       check if all elements are unique and negate the result 
Galen Ivanov
la source
1
c'est un peu fou que vous ne puissiez pas faire mieux que (-.@-:~.)pour "les articles uniques ne correspondent pas" en J mais je l'ai rencontré plusieurs fois aussi et je ne pense pas que vous puissiez ... nous avons =et ~:, sur une main, et -:et <this is missing>.
Jonah
En fait, a réussi à se raser 1 octet supplémentaire hors: 1#.|.,&((~:&#~.)/.)]. Essayez-le en ligne!
Jonah
@Jonah: utilisation cool de &, merci!
Galen Ivanov
5

Japt , 31 octets

ËcUî
ËéEÃÕc¡XéYnÃÕ mf fÊk_eZâÃl

Essayez tous les cas de test

Explication:

Ëc                            #Pad each row...
  Uî                          #With a number of 0s equal to the number of rows

ËéEÃÕ                         #Get the anti-diagonals:
ËéEÃ                          # Rotate each row right a number of times equal to the row's index
    Õ                         # Get the resulting columns
     c                        #Add to that...
      ¡XéYnÃÕ                 #The diagonals:
      ¡XéYnà                  # Rotate each row left a number of times equal to the row's index
            Õ                 # Get the resulting columns
              mf              #Remove the 0s from each diagonal
                 fÊ           #Remove the all-0 diagonals
                   k_   Ã     #Remove the ones where:
                     eZâ      # The list contains no duplicates
                         l    #Return the number of remaining diagonals

J'ai également essayé une version basée sur la réponse Haskell de Kirill L., mais je n'ai pas pu trouver un bon moyen de "grouper en fonction des indices X et Y" et l'alternative que j'ai trouvée n'était pas assez bonne.

Kamil Drakari
la source
31 octets
Shaggy
4

JavaScript (ES6),  107 105 101  98 bytes

f=(m,d=s=1)=>(m+0)[s-=~d/2]?m.some(o=(r,y)=>!r.every((v,x)=>x+d*y+m.length-s?1:o[v]^=1))+f(m,-d):0

Essayez-le en ligne!

Remarque

La façon dont ce code est joué, l'anti-diagonale composée de la seule cellule en bas à gauche n'est jamais testée. C'est OK car il ne peut pas contenir de valeurs dupliquées.

Commenté

f = (                    // f = recursive function taking:
  m,                     //   m[] = input matrix
  d =                    //   d   = direction (1 for anti-diagonal or -1 for diagonal)
  s = 1                  //   s   = expected diagonal ID, which is defined as either the sum
) =>                     //         or the difference of x and y + the length of a row
  (m + 0)[               //
    s -= ~d / 2          // increment s if d = -1 or leave it unchanged otherwise
  ] ?                    // if s is less than twice the total number of cells:
    m.some(o =           //   o = object used to store encountered values in this diagonal
    (r, y) =>            //   for each row r[] at position y in m[]:
      !r.every((v, x) => //     for each cell of value v at position x in r[]:
        x + d * y +      //       x + d * y + m.length is the ID of the diagonal
        m.length - s ?   //       if it's not equal to the one we're looking for:
          1              //         yield 1
        :                //       else:
          o[v] ^= 1      //         toggle o[v]; if it's equal to 0, v is a duplicate and
                         //         every() fails which -- in turn -- makes some() succeed
      )                  //     end of every()
    )                    //   end of some()
    + f(m, -d)           //   add the result of a recursive call in the opposite direction
  :                      // else:
    0                    //   stop recursion
Arnauld
la source
4

05AB1E , 25 octets

í‚εεygÅ0«NFÁ]€ø`«ʒ0KDÙÊ}g

Essayez-le en ligne! ou en tant que suite de tests

Explication

í                          # reverse each row in input
 ‚                         # and pair with the input
  ε                        # for each matrix
   ε                       # for each row in the matrix
    ygÅ0«                  # append len(row) zeroes
         NFÁ               # and rotate it index(row) elements to the right
            ]              # end loops
             €ø            # transpose each matrix
               `«          # append them together
                 ʒ     }   # filter, keep only rows that
                  0K       # when zeroes are removed
                    DÙÊ    # are not equal to themselves without duplicate values                           
                        g  # push length of the result

J'ai l'impression d'avoir raté quelque chose ici.
Besoin d'essayer de jouer au golf plus tard.

Emigna
la source
1
N'aide pas du tout, mais le rotate N leftserait N._maintenant. Ça í‚εεygÅ0«N._]marche aussi. Peut également supprimer l'aplatissement avec ce nouveau changement ... toujours pas d'économie d'octets cependant:í‚vyεygÅ0«N._}ø}«ʒ0KDÙÊ}g
Urne de poulpe magique
1
@MagicOctopusUrn: Intéressant. J'avais manqué cette commande. Seulement une gauche cependant. C'est bizarre.
Emigna
1
@Emigna Vous pouvez aller à droite avec N(._je suppose, mais votre NFÁ}longueur est la même, et encore plus courte dans ce cas en raison de la ]fermeture simultanée de la boucle et des cartes. Dans l'ensemble, l'utilisation de ._n'est utile que lorsque vous allez à gauche pour enregistrer 1 octet, par rapport à NFÀ}.
Kevin Cruijssen
@KevinCruijssen: Ah, cool. Bien que comme vous le dites, pas très utile.
Emigna
3

Python 2 , 144 136 octets

lambda m:sum(l(set(d))<l(d)for d in[[r[i*x+o]for i,r in enumerate(m)if-1<i*x+o<l(r)]for o in range(-l(`m`),l(`m`))for x in[-1,1]])
l=len

Essayez-le en ligne!

TFeld
la source
3

Octave , 98 octets

@(A)nnz([(q=@(Q)arrayfun(@(n)nnz(z=diag(Q,n))-nnz(unique(z)),-([m,n]=size(Q)):n))(A),q(rot90(A))])

Essayez-le en ligne!

Sanchises
la source
1
Les tableaux sont-ils vraiment amusants? ; p
Kevin Cruijssen
Et merci d'avoir préparé les cas de test au format Octave!
Luis Mendo
2
@KevinCruijssen Pas seulement des tableaux! Vous pouvez en avoir cellfunaussi, et pour les masochistes structfunaussi. Dans Octave, c'est soit une boucle for, soit un ayant fun!
Sanchises
Et n'oubliez pas b-sx-fun!
Luis Mendo
3

Haskell, 118 112 octets

import Data.List
r#(a:b)=sum[1|(/=)=<<nub$[h|h:_<-a:r]]+[t|_:t<-a:r]#b
[]#_=0
a#_=a#[[]]
h x=[]#x+[]#(reverse x)

Essayez-le en ligne!

r#(a:b)                      -- function '#' calculates the ant-diagonals of a matrix
                             -- where 'a' is the first row and 'b' all the others
                             -- as we recursively walk down the rows of the matrix,
                             -- 'r' holds the rows from before with the respective
                             -- head dropped
                             --
          [h|h:_<-a:r]       -- if the heads of the the current row and the rows
                             -- before
       (/=)=<<nub$           -- contain duplicates
    [1|                ]     -- make a singleton list [1] (else the empty list)
 sum                         -- and take the sum thereof
      +                      -- and add
             #               -- a recursive call with
 [t|_:t<-a:r]                -- the tails of the current row and the rows before
              b              -- and the rows below
                             --
[]#_=0                       -- base case if there aren't any tails anymore, return 0
a#_=a#[[]]                   -- if there are tails, but no further rows below,
                             -- continue with tails

h x=[]#x+[]#(reverse x)      -- main function, call '#' with input matrix 'x'
                             -- and the reverse of it to get the number of diagonals
                             -- and anti-diagonals. Recursion starts with no
                             -- rows before the 1st row.

-- example trace of function '#'
-- input matrix:
--   [[1,2,3,4],
--    [5,6,7,8],
--    [9,9,9,9]]
--
--  | r         a          b              a:r          heads   tails (r of next call)
-- -+----------------------------------------------------------------------------------
-- 1| []        [1,2,3,4]  [[5,6,7,8],    [[1,2,3,4]]  [1]     [[2,3,4]]
--  |                       [9,9,9,9]]
--  | 
-- 2| [[2,3,4]]  [5,6,7,8]  [[9,9,9,9]]   [[5,6,7,8],  [5,2]   [[6,7,8],
--  |                                      [2,3,4  ]]           [3,4  ]]
--  |
-- 3| [[6,7,8],  [9,9,9,9]  []            [[9,9,9,9],  [9,6,3] [[9,9,9],
--  |  [3,4  ]]                            [6,7,8  ],           [7,8  ]
--  |                                      [3,4    ],           [4    ]
--  |
--  | ....
nimi
la source
2

Fusain , 61 56 53 octets

F²FLθFL§θ⁰F⟦⁻κ×⊖⊗ιλ⟧⊞υ⊞O⎇∧λ﹪⁺μιLθ⊟υ⟦⟧§§θμλILΦυ⊙ι‹⌕ιλμ

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

F²

Boucle sur les diagonales avant et arrière; i=0représente les diagonales avant tandis que i=1représente les diagonales inverses.

FLθ

Boucle sur chaque index de ligne. Cela représente l'indice du début de la diagonale.

FL§θ⁰«

Boucle sur chaque index de colonne.

F⟦⁻κ×⊖⊗ιλ⟧

Calculez l'indice de ligne de la diagonale à cet indice de colonne. J'utilise unfor boucle sur un tableau à un élément au lieu d'une affectation car cela évite d'avoir à encapsuler l'affectation dans un bloc avec l'instruction suivante, économisant ainsi un octet.

⎇∧λ﹪⁺μιLθ

Vérifiez s'il s'agit de la première colonne ou si la diagonale est sur le point de passer entre le bas et le haut.

⊟υ

Si ce n'est pas le cas, sautez la dernière liste de la liste des listes.

⟦⟧

si c'est le cas, commencez une nouvelle liste vide.

⊞O...§§θμλ

Ajoutez l'entrée diagonale actuelle à cette liste.

⊞υ

Et repoussez cette liste (retour) vers la liste des listes.

ILΦυ⊙ι‹⌕ιλμ

Comptez le nombre de listes contenant des doublons.

Prenons un exemple quand i=0et k=1. Cela signifie que nous avons déjà obtenu deux diagonales, [[1,1,5,2],[9,4,3,5]]. Voici notre contribution:

 1 8 4 2 9 4 4 4
[5]1 2 7 7 4 2 3
 1 4 5 2 4 2 3 8
 8 5 4 2 3 4 1 5

Nous bouclons ensuite lde 0à 7. Cela fait avancer la ligne et la colonne de 1 à chaque fois:

 1 8 4 2 9 4 4 4
[5]1 2 7 7 4 2 3
 1[4]5 2 4 2 3 8
 8 5[4]2 3 4 1 5

La liste est maintenant [[1,1,5,2],[9,4,3,5],[5,4,4]]. Cependant, quand lest 3, nous avons k+l=4, un multiple de la hauteur du tableau. Cela signifie que nous devons commencer une nouvelle liste: [[1,1,5,2],[9,4,3,5],[5,4,4],[]]. Nous continuons ensuite à collecter des éléments diagonaux:

 1 8 4[2]9 4 4 4
[5]1 2 7[7]4 2 3
 1[4]5 2 4[2]3 8
 8 5[4]2 3 4[1]5

La liste est maintenant [[1,1,5,2],[9,4,3,5],[5,4,4],[2,7,2,1]]. Maintenant, quand lest 7, nous avons k+l=8, un autre multiple de la hauteur du tableau. Cela signifie que nous devons commencer une nouvelle liste, qui se termine avec le dernier élément de cette diagonale: [[1,1,5,2],[9,4,3,5],[5,4,4],[2,7,2,1],[4]].

 1 8 4[2]9 4 4[4]
[5]1 2 7[7]4 2 3
 1[4]5 2 4[2]3 8
 8 5[4]2 3 4[1]5

En collectant les diagonales enveloppantes à partir du premier élément de chaque ligne, nous finissons par accumuler toutes les diagonales du réseau.

Neil
la source
2

Wolfram Language (Mathematica) , 99 98 96 94 83 octets

Count[DuplicateFreeQ@Diagonal[#,i]~Table~{i,-t,t=#~Total~2}&/@{#,Reverse@#},1<0,2]&

Essayez-le en ligne!

  • Function[a,a~Diagonal~#&/@Range[t=-#~Total~2,-t]]obtient toutes les diagonales de a- ce qui fonctionne parce qu'il #~Total~2est plus grand que n'importe quelle dimension de a.
lirtosiast
la source
1

APL + WIN, 69 octets

Demande une matrice 2d de la forme 4 6⍴1 2 1 2 1 2 1 2 3 4 5 6 6 5 4 3 2 1 2 1 2 1 2 1

Cela donne:

1 2 1 2 1 2
1 2 3 4 5 6
6 5 4 3 2 1
2 1 2 1 2 1

+/~(v⍳¨v)≡¨⍳¨⍴¨v←(v←⊂[1](⌽0,⍳1↓n)⌽(n⍴0),m,((n←0 ¯1+↑⍴m)⍴0),⌽m←⎕)~¨0

Essayez-le en ligne! Gracieuseté de Dyalog Classic

Explication:

(⌽0,⍳1↓n)⌽(n⍴0),m pad m with zeros to isolate diagonals

((n←0 ¯1+↑⍴m)⍴0),⌽m pad rotated m with zeros to isolate anti-diagonals

Rendements:

1 2 1 2 1 2 0 0 0 2 1 2 1 2 1 0 0 0
0 1 2 3 4 5 6 0 0 0 6 5 4 3 2 1 0 0
0 0 6 5 4 3 2 1 0 0 0 1 2 3 4 5 6 0
0 0 0 2 1 2 1 2 1 0 0 0 1 2 1 2 1 2

v←(v←⊂[1](.....)~¨0 enclose the diagonals as a nested vector with padded zeros removed

+/~(v⍳¨v)≡¨⍳¨⍴¨v identify diagnols with duplicate entries and sum
Graham
la source
1

Perl 5, 89 82 octets

map{$i=0;map{$a[$x+$i].=$_;$b[@F-$x+$i++].=$_}/\d/g;$x++}@F;$_=grep/(.).*\1/,@a,@b

TIO

Nahuel Fouilleul
la source
1

TSQL, 140 128 octets

Trouver un moyen de jouer au golf à 12 personnages. Ce n'est plus la solution la plus longue.

Golfé:

SELECT sum(iif(y+x=j+i,1,0)+iif(y-x=j-i,1,0))FROM
@,(SELECT x i,y j,max(y)over()m,v w
FROM @)d WHERE(x*y=0or m=y)and v=w and x<i

Non golfé:

DECLARE @ table(v int,x int,y int)
-- v = value
-- x = row 
-- y = column
INSERT @ values
(1,0,0),(2,0,1),(1,0,2),(2,0,3),(1,0,4),(2,0,5),
(1,1,0),(2,1,1),(3,1,2),(4,1,3),(5,1,4),(6,1,5),
(6,2,0),(5,2,1),(4,2,2),(3,2,3),(2,2,4),(1,2,5),
(2,3,0),(1,3,1),(2,3,2),(1,3,3),(2,3,4),(1,3,5)


SELECT sum(iif(y+x=j+i,1,0)+iif(y-x=j-i,1,0))
FROM @,(SELECT x i,y j,max(y)over()m,v w FROM @)d
WHERE
  (x*y=0or m=y)
  and v=w
  and x<i

Essaye le

t-clausen.dk
la source