Yinelenen değerlerle tüm (anti) çaprazları tespit edin


17

Meydan okuma:

Bir matris girişi verildiğinde, yinelenen sayılarla diyagonal ve anti-diyagonal miktarını belirleyin.
Yani böyle bir matrisimiz varsa:

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

Tüm çapraz ve anti-çapraz:

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

Misal:

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

Tüm çapraz ve anti-çapraz:

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

Yalnızca benzersiz sayılar içeren tüm çapraz ve anti-çaprazları kaldırma:

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

Böylece çıktı, yinelenen sayılar içeren köşegenlerin ve köşegenlerin miktarıdır:

6

Zorluk kuralları:

  • Giriş matrisi boşsa, yalnızca 1 sayı içeriyorsa veya tüm matris boyunca yalnızca benzersiz sayılar içeriyorsa, çıktı her zaman olur 0.
  • Girişin yalnızca pozitif rakam içermesi garanti edilir [1,9](tamamen boş değilse).
  • Matris her zaman dikdörtgen şeklinde olacaktır (yani tüm satırlar aynı uzunluktadır).
  • G / Ç esnektir. Giriş, tamsayıların listesi veya 2D tamsayı dizisi veya bir Matrix nesnesi, dize vb. Olarak alınabilir. Ayrıca, matrisin boyutlarından birini veya her ikisini ek giriş olarak almanıza izin verilir. tercih ettiğiniz dilde bayt tasarruf ederse.

Genel kurallar:

  • Bu , bayt en kısa cevap kazanır.
    Kod golf dillerinin, kod yazmayan dillerle yanıt göndermenizi engellemesine izin vermeyin. 'Herhangi bir' programlama dili için olabildiğince kısa bir cevap bulmaya çalışın.
  • Varsayılan I / O kuralları ile cevabınız için standart kurallar geçerlidir , bu nedenle STDIN / STDOUT, fonksiyonlar / yöntem uygun parametreler ve dönüş tipi, tam programlar ile kullanılabilir. Çağrınız.
  • Varsayılan Loopholes yasaktır.
  • Mümkünse, lütfen kodunuz için bir test içeren bir bağlantı ekleyin (örn. TIO ).
  • Ayrıca, cevabınız için bir açıklama eklemeniz şiddetle tavsiye edilir.

Test senaryoları:

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

Yanıtlar:


4

Jöle , 10 bayt

ŒD;ŒdQƑÐḟL

Çevrimiçi deneyin! veya Test takımına göz atın!

Alternatifler:

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

Nasıl çalışır?

Œ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).

10

R , 92 86 82 78 bayt

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

Çevrimiçi deneyin!

açıklama

xy

xy

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

Şimdi split(m, x-y)vesplit(m, x+y) katıldığımız gerçek diyagonal ve anti-diyagonal listelerini üretin.

Son olarak, sonuç listesinin kopyaların bulunduğu girişlerini sayarız.

Kaydedilen bayt için teşekkürler:

-4 CriminallyVulgar tarafından
-4 digEmAll tarafından


1
Sanırım ekleyebilirim rowve col'son derece durumsal fonksiyonlar' listeme. Gerçekten akıllı bir çözüm.
CriminallyVulgar

1
Ben c(m|x-y,m|x+y)doğrudan aptalca çağrı içine taşıyabilirsiniz düşünüyorum , l=parçayı çıkarın . Başarısız testler görmüyorum. Çevrimiçi deneyin!
CriminallyVulgar

Evet, bu doğru, ilk golften sonra sadece tek bir lörnek kaldığını kaçırdım .
Kirill L.

1
Bu sabah R'ye rowve columnişlevlerini eklemiş olmalılar , çünkü onları hiç duymadım.
ngm

5

J , 21 20 bayt

Jonah'a -1 bayt teşekkürler!

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

Çevrimiçi deneyin!

Açıklama:

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 

1
(-.@-:~.)J "benzersiz öğeleri eşleşmez" için daha iyi yapamazsınız çılgınca ama ben de bu defalarca karşılaştım ve ben yapabileceğini sanmıyorum ... biz =ve ~:, bir el ve -:ve <this is missing>.
Jonah

Aslında kapalı 1 byte daha tıraş başardı: 1#.|.,&((~:&#~.)/.)]. Çevrimiçi deneyin!
Jonah

@Jonah: serin kullanımı &, teşekkürler!
Galen Ivanov

5

Japt , 31 bayt

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

Tüm test senaryolarını deneyin

Açıklama:

Ë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

Ayrıca Kirill L.'nin Haskell cevabına dayanan bir versiyon denedim , ancak "X ve Y indekslerinin bir fonksiyonuna göre gruplandırmak" için iyi bir yol bulamadım ve bulduğum alternatif yeterince iyi değildi.



4

JavaScript (ES6),  107 105 101  98 bayt

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

Çevrimiçi deneyin!

Not

Bu kodun golf oynama şekli, sol alt sol hücreden oluşan anti-diyagonal asla test edilmez. Yinelenen değerler içeremeyeceği için sorun değil.

Yorumlananlar

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

4

05AB1E , 25 bayt

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

Çevrimiçi deneyin! veya Test Paketi olarak

açıklama

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

Burada bir şeyleri özlediğimi hissediyorum.
Bu daha sonra denemek ve golf gerekiyor.


1
Hiç yardımcı rotate N leftolmaz , ama N._şimdi olur. Yani í‚εεygÅ0«N._]işe yarıyor. Ayrıca bu yeni değişiklikle yassılaştırmayı kaldırabilirsiniz ... yine de bayt tasarrufu yok:í‚vyεygÅ0«N._}ø}«ʒ0KDÙÊ}g
Sihirli Ahtapot Urn

1
@MagicOctopusUrn: İlginç. O komutu kaçırmıştım. Sadece bir sol olsa. Bu tuhaf.
Emigna

1
@Emigna N(._Sanırım doğru gidebilirsin , ama NFÁ}aynı uzunlukta ve bu durumda ]döngü ve haritaları aynı anda kapatması nedeniyle daha da kısa . Genel olarak, kullanımı ._sadece 1 bayt tasarruf için sola giderken yararlıdır NFÀ}.
Kevin Cruijssen

@KevinCruijssen: Ah, güzel. Söylediğiniz gibi, çok yararlı değil.
Emigna


3

Oktav , 98 bayt

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

Çevrimiçi deneyin!


1
Diziler gerçekten eğlenceli midir? ; p
Kevin Cruijssen

Ve test vakalarını Octave formatında hazırladığınız için teşekkürler!
Luis Mendo

2
@KevinCruijssen Sadece diziler değil! Sizde de olabilir cellfunve mazoşist için structfunde. Octave'de, ya bir döngü ya da sahip olmak fun!
7'de Sanchises

Ve b-sx-fun unutma!
Luis Mendo

3

Haskell, 118111 bayt

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)

Çevrimiçi deneyin!

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

2

Kömür , 61 56 53 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. Açıklama:

F²

İleri ve geri çaprazlamalarda döngü; i=0ileri çaprazları i=1temsil ederken , ters çaprazlamaları temsil eder.

FLθ

Her satır dizini üzerinden döngü yapın. Bu, diyagonalin başlangıç ​​indeksini temsil eder.

FL§θ⁰«

Her sütun dizini üzerinde döngü yapın.

F⟦⁻κ×⊖⊗ιλ⟧

Bu sütun dizinindeki diyagonalin satır dizinini hesaplayın. Ben forbir atama aşağıdaki deyim ile bir bloğa sarmak zorunda kalmaz, böylece bir bayt kaydederek atama yerine tek elemanlı bir dizi üzerinde bir döngü kullanın .

⎇∧λ﹪⁺μιLθ

Bunun ilk sütun mu yoksa diyagonalin mi alttan üste mi sarılmak üzere olduğunu kontrol edin.

⊟υ

Değilse, listeler listesinden son listeyi açın.

⟦⟧

yeni bir boş liste başlatın.

⊞O...§§θμλ

Geçerli çapraz girişi bu listeye ekleyin.

⊞υ

Ve bu listeyi (geri) liste listesine itin.

ILΦυ⊙ι‹⌕ιλμ

Yinelenenleri içeren liste sayısını sayın.

Ne zaman i=0ve ne zaman bir örnek alalım k=1. Bu zaten iki köşegen topladığımız anlamına geliyor [[1,1,5,2],[9,4,3,5]]. İşte girdimiz:

 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

Sonra ' ldan' 0a dönüyoruz 7. Bu, her seferinde hem satırı hem de sütunu 1 artırır:

 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

Liste şimdi [[1,1,5,2],[9,4,3,5],[5,4,4]]. Ancak lolup 3, elimizdeki k+l=4, dizinin yüksekliğinin birkaç katı. Bu araçlar yeni bir liste başlatmak gerektiğini: [[1,1,5,2],[9,4,3,5],[5,4,4],[]]. Daha sonra diyagonal öğeleri toplamaya devam ediyoruz:

 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

Liste şimdi [[1,1,5,2],[9,4,3,5],[5,4,4],[2,7,2,1]]. Şimdi ne zaman lolduğunu 7, elimizdeki k+l=8, dizinin yüksekliğinin başka katını. Bu araçlar o diyagonal son eleman ile biter yeni bir liste başlatmak gerektiğini: [[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

Her satırın ilk öğesinden başlayarak kaydırma köşegenleri toplayarak, sonunda dizinin tüm köşegenlerini biriktiririz.


2

Wolfram Dili (Mathematica) , 99 98 96 94 83 bayt

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

Çevrimiçi deneyin!

  • Function[a,a~Diagonal~#&/@Range[t=-#~Total~2,-t]]tüm köşegenlerini alır a- ki bu işe yarar çünkü #~Total~2herhangi bir boyutundan daha büyüktür a.

1

APL + WIN, 69 bayt

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 formunun 2d matrisini ister

Bu şu sonuçları verir:

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

Çevrimiçi deneyin! Dyalog Classic'in izniyle

Açıklama:

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

Verim:

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

1

Perl 5, 89 82 bayt

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

TIO


1

TSQL, 140 128 bayt

12 karakter golf için bir yol buldu. Bu artık en uzun çözüm değil.

golfed:

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

Ungolfed:

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

Denemek

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.