Cari semua diagonal (anti) dengan nilai duplikat

17

Tantangan:

Diberikan input matriks, tentukan jumlah diagonal dan anti-diagonal dengan angka duplikat.
Jadi jika kita memiliki matriks seperti ini:

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

Semua diagonal dan anti-diagonal adalah:

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

Contoh:

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

Semua diagonal dan anti-diagonal adalah:

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

Menghapus semua diagonal dan anti-diagonal hanya berisi angka unik:

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

Jadi outputnya adalah jumlah diagonal dan anti-diagonal yang mengandung angka duplikat:

6

Aturan tantangan:

  • Jika matriks input kosong, hanya berisi 1 angka, atau hanya berisi angka unik di seluruh matriks, hasilnya selalu 0.
  • Input dijamin hanya mengandung digit positif [1,9](kecuali benar-benar kosong).
  • Matriks akan selalu berbentuk persegi panjang (yaitu semua baris memiliki panjang yang sama).
  • I / O fleksibel. Input dapat diambil sebagai daftar daftar bilangan bulat, atau array 2D bilangan bulat, atau objek Matrix, sebagai string, dll. Anda juga dapat mengambil satu atau kedua dimensi matriks sebagai input tambahan apakah itu akan menyimpan byte dalam bahasa pilihan Anda.

Aturan umum:

  • Ini adalah , jadi jawaban tersingkat dalam byte menang.
    Jangan biarkan bahasa kode-golf mencegah Anda memposting jawaban dengan bahasa non-codegolf. Cobalah untuk memberikan jawaban sesingkat mungkin untuk bahasa pemrograman 'apa saja'.
  • Aturan standar berlaku untuk jawaban Anda dengan aturan I / O default , sehingga Anda diizinkan untuk menggunakan STDIN / STDOUT, fungsi / metode dengan parameter yang tepat dan tipe pengembalian, program penuh. Panggilanmu.
  • Celah default tidak diperbolehkan.
  • Jika memungkinkan, silakan tambahkan tautan dengan tes untuk kode Anda (yaitu TIO ).
  • Juga, menambahkan penjelasan untuk jawaban Anda sangat dianjurkan.

Kasus uji:

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
sumber

Jawaban:

4

Jelly , 10 byte

ŒD;ŒdQƑÐḟL

Cobalah online! atau Lihat test suite!

Alternatif:

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

Bagaimana itu bekerja?

Œ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).
Tuan Xcoder
sumber
10

R , 92 86 82 78 byte

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

Cobalah online!

Penjelasan

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

Sekarang split(m, x-y)dan split(m, x+y)buat daftar diagonal dan anti-diagonal yang sebenarnya, yang kita gabungkan bersama.

Akhirnya, kami menghitung entri dari daftar yang dihasilkan di mana duplikat hadir.

Terima kasih untuk byte yang disimpan:

-4 oleh CriminallyVulgar
-4 oleh digEmAll

Kirill L.
sumber
1
Kira saya dapat menambahkan rowdan colke daftar 'fungsi yang sangat situasional'. Solusi yang sangat pintar.
Kriminal
1
Saya pikir Anda dapat memindahkan c(m|x-y,m|x+y)langsung ke panggilan sapply, menghapus l=bagian itu. Saya tidak melihat tes yang gagal. Cobalah online!
Penjahat
Yap, itu benar, saya baru saja melewatkan itu setelah golf pertama saya, hanya ada satu lcontoh yang tersisa.
Kirill L.
1
Mereka pasti telah menambahkan rowdan columnberfungsi ke R pagi ini, karena saya belum pernah mendengarnya.
ngm
5

J , 21 20 byte

-1 byte terima kasih kepada Jonah!

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

Cobalah online!

Penjelasan:

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
sumber
1
Agak gila bahwa Anda tidak bisa melakukan lebih baik daripada (-.@-:~.)untuk "item unik tidak cocok" di J tetapi saya sudah berkali-kali bertemu ini dan saya tidak berpikir Anda bisa ... kami punya =dan ~:, pada satu tangan, dan -:dan <this is missing>.
Jonah
Sebenarnya, berhasil mencukur 1 byte lebih off: 1#.|.,&((~:&#~.)/.)]. Cobalah online!
Jonah
@Jonah: penggunaan keren &, terima kasih!
Galen Ivanov
5

Japt , 31 byte

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

Coba semua uji kasus

Penjelasan:

Ë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

Saya juga mencoba versi yang didasarkan pada jawaban Haskell dari Kirill L., tetapi tidak menemukan cara yang baik untuk "dikelompokkan berdasarkan fungsi indeks X dan Y" dan alternatif yang saya temukan tidak cukup baik.

Kamil Drakari
sumber
31 byte
Shaggy
4

JavaScript (ES6),  107 105 101  98 byte

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

Cobalah online!

Catatan

Cara kode ini di-golf, anti-diagonal yang terdiri dari satu-satunya sel kiri bawah tidak pernah diuji. Tidak apa-apa karena tidak mungkin mengandung nilai duplikat.

Berkomentar

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
sumber
4

05AB1E , 25 byte

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

Cobalah online! atau sebagai Test Suite

Penjelasan

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

Saya merasa seperti melewatkan sesuatu di sini.
Perlu mencoba dan golf ini nanti.

Emigna
sumber
1
Sama sekali tidak membantu, tetapi rotate N leftakan N._sekarang. Begitu í‚εεygÅ0«N._]juga bekerja. Juga dapat menghapus rata dengan perubahan baru ini ... masih tanpa penghematan byte:í‚vyεygÅ0«N._}ø}«ʒ0KDÙÊ}g
Magic Octopus Gn
1
@MagicOctopusUrn: Menarik. Saya telah melewatkan perintah itu. Hanya yang tersisa. Itu aneh.
Emigna
1
@ Emigna Anda dapat langsung melakukannya dengan N(._saya kira, tetapi Anda NFÁ}memiliki panjang yang sama, dan bahkan lebih pendek dalam hal ini karena] menutup loop dan peta secara bersamaan. Secara keseluruhan penggunaan ._hanya berguna bila dibiarkan menghemat 1 byte, dibandingkan dengan NFÀ}.
Kevin Cruijssen
@KevinCruijssen: Ah, keren. Meskipun seperti yang Anda katakan, tidak terlalu berguna.
Emigna
3

Python 2 , 144 136 byte

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

Cobalah online!

TFeld
sumber
3

Oktaf , 98 byte

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

Cobalah online!

Sanchises
sumber
1
Apakah array memang menyenangkan? ; p
Kevin Cruijssen
Dan terima kasih telah menyiapkan kasus uji dalam format Octave!
Luis Mendo
2
@KevinCruijssen Bukan hanya array! Anda juga bisa cellfun, dan untuk yang masokis structfunjuga. Di Octave, itu untuk loop atau memiliki fun!
Sanchises
Dan jangan lupa b-sx-fun!
Luis Mendo
3

Haskell, 118 112 byte

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)

Cobalah 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
sumber
2

Arang , 61 56 53 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

F²

Loop di depan dan diagonal terbalik; i=0mewakili diagonal maju sementara i=1mewakili diagonal terbalik.

FLθ

Ulangi setiap indeks baris. Ini merupakan indeks awal diagonal.

FL§θ⁰«

Ulangi setiap indeks kolom.

F⟦⁻κ×⊖⊗ιλ⟧

Hitung indeks baris diagonal pada indeks kolom ini. Saya menggunakan afor loop pada array elemen tunggal alih-alih tugas karena ini menghindari harus membungkus tugas menjadi blok dengan pernyataan berikut, sehingga menghemat satu byte.

⎇∧λ﹪⁺μιLθ

Periksa apakah ini kolom pertama atau diagonal akan membungkus antara bawah dan atas.

⊟υ

Jika tidak maka pop daftar terakhir dari daftar daftar.

⟦⟧

jika kemudian mulai daftar kosong baru.

⊞O...§§θμλ

Tambahkan entri diagonal saat ini ke daftar itu.

⊞υ

Dan dorong daftar itu (kembali) ke daftar daftar.

ILΦυ⊙ι‹⌕ιλμ

Hitung jumlah daftar yang berisi duplikat.

Mari kita ambil contoh kapan i=0dan k=1. Ini berarti bahwa kami telah mengumpulkan dua diagonal [[1,1,5,2],[9,4,3,5]],. Inilah masukan kami:

 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

Kami kemudian beralih ldari 0ke 7. Ini memajukan baris dan kolom sebanyak 1 setiap kali:

 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

Daftarnya sekarang [[1,1,5,2],[9,4,3,5],[5,4,4]]. Namun ketika ladalah 3, kita memiliki k+l=4, kelipatan dari ketinggian array. Ini berarti bahwa kita harus mulai daftar baru: [[1,1,5,2],[9,4,3,5],[5,4,4],[]]. Kami kemudian terus mengumpulkan elemen diagonal:

 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

Daftarnya sekarang [[1,1,5,2],[9,4,3,5],[5,4,4],[2,7,2,1]]. Sekarang ketika ladalah 7, kita memiliki k+l=8, beberapa lain dari ketinggian dari array. Ini berarti bahwa kita harus mulai daftar baru, yang berakhir dengan elemen terakhir dari yang diagonal: [[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

Dengan mengumpulkan diagonal pembungkus mulai dari elemen pertama dari setiap baris, kami akhirnya mengumpulkan semua diagonal array.

Neil
sumber
2

Bahasa Wolfram (Mathematica) , 99 98 96 94 83 byte

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

Cobalah online!

  • Function[a,a~Diagonal~#&/@Range[t=-#~Total~2,-t]]mendapat semua diagonal a- yang berfungsi karena #~Total~2lebih besar dari dimensi a.
lirtosiast
sumber
1

APL + WIN, 69 byte

Anjuran untuk matriks 2d dari formulir 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

Ini menghasilkan:

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

Cobalah online! Atas perkenan Dyalog Classic

Penjelasan:

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

Hasil:

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
sumber
1

Perl 5, 89 82 byte

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

TIO

Nahuel Fouilleul
sumber
1

TSQL, 140 128 byte

Menemukan cara untuk bermain golf 12 karakter. Ini bukan lagi solusi terpanjang.

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

Tidak Disatukan:

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

Cobalah

t-clausen.dk
sumber