Znajdź wszystkie (anty) przekątne o zduplikowanych wartościach

17

Wyzwanie:

Na podstawie danych wejściowych macierzy określ ilość przekątnych i przekątnych ze zduplikowanymi liczbami.
Więc jeśli mamy taką matrycę:

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

Wszystkie przekątne i anty przekątne byłyby:

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

Przykład:

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

Wszystkie przekątne i anty przekątne byłyby:

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

Usuwanie wszystkich przekątnych i przekątnych zawierających tylko unikalne liczby:

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

Tak więc wynikiem jest liczba przekątnych i przekątnych zawierających zduplikowane liczby:

6

Zasady konkursu:

  • Jeśli macierz wejściowa jest pusta, zawiera tylko 1 liczbę lub zawiera tylko unikalne liczby w całej macierzy, wynik jest zawsze taki sam 0.
  • Dane wejściowe z pewnością zawierają tylko cyfry dodatnie [1,9](chyba że są całkowicie puste).
  • Matryca zawsze będzie prostokątna (tzn. Wszystkie rzędy mają tę samą długość).
  • I / O jest elastyczny. Dane wejściowe można traktować jako listę liczb całkowitych, tablicę liczb całkowitych 2D lub obiekt Matrix, jako ciąg znaków itp. Itp. Można również przyjąć jeden lub oba wymiary macierzy jako dodatkowe dane wejściowe jeśli pozwoliłoby to zaoszczędzić bajty w wybranym języku.

Główne zasady:

  • To jest , więc wygrywa najkrótsza odpowiedź w bajtach.
    Nie pozwól, aby języki gry w golfa zniechęcały Cię do publikowania odpowiedzi w językach niekodujących golfa. Spróbuj znaleźć możliwie najkrótszą odpowiedź na „dowolny” język programowania.
  • Do odpowiedzi mają zastosowanie standardowe reguły z domyślnymi regułami We / Wy , więc możesz używać STDIN / STDOUT, funkcji / metody z odpowiednimi parametrami i typem zwracanych, pełnych programów. Twoja decyzja.
  • Domyślne luki są zabronione.
  • Jeśli to możliwe, dodaj link z testem kodu (tj. TIO ).
  • Zalecane jest również dodanie wyjaśnienia do odpowiedzi.

Przypadki testowe:

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
źródło

Odpowiedzi:

4

Galaretka , 10 bajtów

ŒD;ŒdQƑÐḟL

Wypróbuj online!lub Sprawdź zestaw testowy!

Alternatywy:

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

Jak to działa?

Œ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).
Pan Xcoder
źródło
10

R , 92 86 82 78 bajtów

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

Wypróbuj online!

Wyjaśnienie

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

Teraz split(m, x-y)i split(m, x+y)produkują rzeczywiste list przekątnych i anty-przekątnych, które łączymy ze sobą.

Na koniec zliczamy wpisy wynikowej listy, na których znajdują się duplikaty.

Dzięki za zapisane bajty:

-4 przez CriminallyVulgar
-4 przez digEmAll

Kirill L.
źródło
1
Chyba mogę dodać rowi coldo mojej listy „ekstremalnie sytuacyjnych funkcji”. Naprawdę sprytne rozwiązanie.
CriminallyVulgar
1
Myślę, że możesz przenieść c(m|x-y,m|x+y)prosto do szafirowego połączenia i usunąć l=część. Nie widzę żadnych nieudanych testów. Wypróbuj online!
CriminallyVulgar
Tak, zgadza się, właśnie przegapiłem, że po moim pierwszym golfie pozostała tylko jedna linstancja.
Kirill L.
1
Musieli dodać funkcje rowi columndo R dziś rano, ponieważ nigdy o nich nie słyszałem.
ngm
5

J , 21 20 bajtów

-1 bajt dzięki Jonasz!

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

Wypróbuj online!

Wyjaśnienie:

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 Iwanow
źródło
1
to trochę szalone, że nie możesz zrobić nic lepszego niż (-.@-:~.)„unikalne przedmioty się nie zgadzają” w J, ale ja też spotkałem się z tym wiele razy i nie sądzę, żebyś mógł ... mamy =i ~:na jednym ręka -:i <this is missing>.
Jonah
Rzeczywiście, udało się golić 1 bajt off: 1#.|.,&((~:&#~.)/.)]. Wypróbuj online!
Jonasz
@Jonah: fajne wykorzystanie &, dzięki!
Galen Iwanow
5

Japt , 31 bajtów

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

Wypróbuj wszystkie przypadki testowe

Wyjaśnienie:

Ë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

Próbowałem także wersji opartej na odpowiedzi Kirka L. Haskella, ale nie mogłem znaleźć dobrego sposobu na „pogrupowanie według funkcji wskaźników X i Y”, a alternatywa, którą znalazłem, nie była wystarczająca.

Kamil Drakari
źródło
31 bajtów
Kudłaty
4

JavaScript (ES6),  107 105 101  98 bajtów

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

Wypróbuj online!

Uwaga

Sposób w jaki ten kod jest golfowany, anty-przekątna składająca się z jedynej dolnej lewej komórki nigdy nie jest testowana. Zgadza się, ponieważ nie może zawierać zduplikowanych wartości.

Skomentował

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
źródło
4

05AB1E , 25 bajtów

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

Wypróbuj online! lub jako pakiet testowy

Wyjaśnienie

í                          # 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

Czuję, że coś tu przegapiłem.
Spróbuj później zagrać w golfa.

Emigna
źródło
1
W ogóle nie pomaga, ale rotate N leftbyłoby N._teraz. Tak í‚εεygÅ0«N._]też działa. Może również usunąć spłaszczenie dzięki tej nowej zmianie ... wciąż bez oszczędności bajtów:í‚vyεygÅ0«N._}ø}«ʒ0KDÙÊ}g
Magic Octopus Urn
1
@MagicOctopusUrn: Ciekawe. Przegapiłem to polecenie. Ale tylko lewica. To jest dziwne.
Emigna
1
@Emigna Chyba możesz iść w prawo N(._, ale masz NFÁ}taką samą długość, a nawet w tym przypadku krótszą z powodu jednoczesnego ]zamknięcia pętli i map. Ogólnie rzecz biorąc, użycie ._jest przydatne tylko wtedy, gdy idzie się w lewo, aby zapisać 1 bajt, w porównaniu do NFÀ}.
Kevin Cruijssen
@KevinCruijssen: Ach, spoko. Chociaż, jak mówisz, niezbyt przydatne.
Emigna
3

Python 2 , 144 136 bajtów

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

Wypróbuj online!

TFeld
źródło
3

Oktawa , 98 bajtów

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

Wypróbuj online!

Sanchises
źródło
1
Czy tablice są naprawdę zabawne? ; p
Kevin Cruijssen
I dziękuję za przygotowanie przypadków testowych w formacie Octave!
Luis Mendo,
2
@KevinCruijssen Nie tylko tablice! Ty też możesz mieć cellfun, a także dla masochisty structfun. W Octave jest to albo for-loop, albo posiadanie fun!
Sanchises
I nie zapomnij b-sx-fun!
Luis Mendo,
3

Haskell, 118 112 bajtów

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)

Wypróbuj online!

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
źródło
2

Węgiel drzewny , 61 56 53 bajtów

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

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

F²

Pętla po przekątnych do przodu i do tyłu; i=0reprezentuje przekątne do przodu, podczas gdy i=1reprezentuje przekątne do tyłu.

FLθ

Pętla nad indeksem każdego wiersza. To reprezentuje wskaźnik początku przekątnej.

FL§θ⁰«

Pętla nad indeksem każdej kolumny.

F⟦⁻κ×⊖⊗ιλ⟧

Oblicz indeks wierszy przekątnej przy tym indeksie kolumny. Używam forpętli nad tablicą jednoelementową zamiast przypisania, ponieważ pozwala to uniknąć zawijania przypisania do bloku za pomocą następującej instrukcji, oszczędzając w ten sposób bajt.

⎇∧λ﹪⁺μιLθ

Sprawdź, czy jest to pierwsza kolumna, czy przekątna ma się zawinąć między dolną a górną częścią.

⊟υ

Jeśli tak nie jest, wstaw ostatnią listę z listy.

⟦⟧

jeśli tak, zacznij nową pustą listę.

⊞O...§§θμλ

Dodaj bieżącą pozycję ukośną do tej listy.

⊞υ

I wypchnij tę listę (z powrotem) do listy list.

ILΦυ⊙ι‹⌕ιλμ

Policz liczbę list zawierających duplikaty.

Weźmy przykład, kiedy i=0i k=1. Oznacza to, że mamy już zebrane dwóch przekątnych [[1,1,5,2],[9,4,3,5]]. Oto nasz wkład:

 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

Następnie zapętlamy lod 0do 7. Powoduje to przesunięcie zarówno wiersza, jak i kolumny o 1 za każdym razem:

 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

Lista jest teraz [[1,1,5,2],[9,4,3,5],[5,4,4]]. Jednak kiedy ljest 3, mamy k+l=4wielokrotność wysokości tablicy. Oznacza to, że musimy zacząć nową listę: [[1,1,5,2],[9,4,3,5],[5,4,4],[]]. Następnie nadal zbieramy elementy ukośne:

 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

Lista jest teraz [[1,1,5,2],[9,4,3,5],[5,4,4],[2,7,2,1]]. Teraz, kiedy ljest 7, mamy k+l=8kolejną wielokrotność wysokości tablicy. Oznacza to, że musimy zacząć nową listę, która kończy się z ostatnim elementem, że przekątna: [[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

Zbierając przekątne zawijania zaczynające się od pierwszego elementu każdego rzędu, ostatecznie gromadzimy wszystkie przekątne tablicy.

Neil
źródło
2

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

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

Wypróbuj online!

  • Function[a,a~Diagonal~#&/@Range[t=-#~Total~2,-t]]pobiera wszystkie przekątne a- co działa, ponieważ #~Total~2jest większe niż jakikolwiek wymiar a.
lirtosiast
źródło
1

APL + WIN, 69 bajtów

Monity o matrycę 2D w postaci 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

Daje to:

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

Wypróbuj online! Dzięki uprzejmości Dyalog Classic

Wyjaśnienie:

(⌽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

Wydajność:

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
źródło
1

Perl 5, 89 82 bajtów

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

TIO

Nahuel Fouilleul
źródło
1

TSQL, 140 128 bajtów

Znalazłem sposób na golfa 12 postaci. To nie jest już najdłuższe rozwiązanie.

Gra w golfa:

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

Nie golfowany:

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

Wypróbuj to

t-clausen.dk
źródło