重複した値を持つすべての(反)対角線を見つける


17

チャレンジ:

行列入力が与えられた場合、重複する数値で対角線と対角線の量を決定します。
したがって、次のようなマトリックスがある場合:

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

すべての対角線と反対角線は次のようになります。

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

例:

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

すべての対角線と反対角線は次のようになります。

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

一意の数字のみを含むすべての対角線と対角線を削除します。

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

したがって、出力は、重複した数値を含む対角線と対角線の量です。

6

チャレンジルール:

  • 入力行列が空の場合、1つの数値のみを含む場合、または行列全体で一意の数値のみを含む場合、出力は常に0です。
  • 入力には、正の数字のみが含まれることが保証されます[1,9](完全に空でない限り)。
  • マトリックスは常に長方形です(つまり、すべての行は同じ長さです)。
  • I / Oは柔軟です。入力は、整数のリストのリスト、整数の2D配列、または文字列などのマトリックスオブジェクトなどとして取得できます。また、追加の入力としてマトリックスの1つまたは両方の次元を使用することもできます。選択した言語でバイトを節約する場合。

一般的なルール:

  • これはであるため、バイト単位の最短回答が優先されます。
    コードゴルフ言語では、非コードゴルフ言語で回答を投稿しないようにしてください。「任意の」プログラミング言語の可能な限り短い答えを考えてみてください。
  • デフォルトのI / Oルールを使用した回答には標準ルールが適用されるため、STDIN / STDOUT、関数/メソッド、適切なパラメーターおよび戻り値型、完全なプログラムを使用できます。あなたの電話。
  • デフォルトの抜け穴は禁止されています。
  • 可能であれば、コードのテスト(TIOなど)へのリンクを追加してください。
  • また、回答の説明を追加することを強くお勧めします。

テストケース:

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

回答:



10

R92 86 82 78バイト

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

オンラインでお試しください!

説明

最初に、行インデックスと列インデックスをそれぞれ表す追加の変数 とを宣言します。それから、対角線と反対角線の差と合計をとることにより、対角線と対角線を描くことができます。たとえば、4x4マトリックスの場合: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

次にsplit(m, x-y)split(m, x+y)対角線と対角線の実際のリストを作成し、それらを結合します。

最後に、重複が存在する結果リストのエントリをカウントします。

バイトを保存してくれてありがとう:

-4 by CriminallyVulgar
-4 by digEmAll


1
私は追加することができます推測rowし、col「極めて状況機能」の私のリストに。本当に賢い解決策。
CriminallyVulgar

1
c(m|x-y,m|x+y)sapplyコールにまっすぐ移動して、パーツを削除できると思いますl=。失敗したテストは表示されません。オンラインでお試しください!
CriminallyVulgar

ええ、それは正しいlです。最初のゴルフの後、インスタンスが1つしか残っていないことを知りました。
キリルL.

1
聞いたことがないので、彼らは今朝Rにrowand column関数を追加したに違いありません。
ngm

5

J21 20バイト

ジョナのおかげで-1バイト!

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

オンラインでお試しください!

説明:

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で「一致しないユニークなアイテム」のが、私はあまりにも、この何度も遭遇してきたし、私はあなたが...私たちが持つことができるとは思わない=し、~:1に、手、そして-:そして<this is missing>
ジョナ

実際には、もう1バイト削ることができました:1#.|.,&((~:&#~.)/.)]オンラインでお試しください!
ジョナ

@Jonah:のクールな使用&、ありがとう!
ガレンイワノフ

5

Japt、31バイト

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

すべてのテストケースを試す

説明:

Ë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

Kirill L.のHaskellの回答に基づいたバージョンも試しましが、「XインデックスとYインデックスの関数でグループ化する」良い方法を見つけることができませんでした。



4

JavaScriptの(ES6)、 107の105 101  98バイト

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

オンラインでお試しください!

注意

このコードのゴルフ方法では、唯一の左下のセルで構成される対角線はテストされません。重複した値を含めることはできないため、これは問題ありません。

コメント済み

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バイト

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

オンラインでお試しください! またはテストスイートとして

説明

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

ここで何かを見逃したような気がします。
これをもっと後で試す必要があります。


1
まったく助けにはなりませんrotate N leftが、N._今はそうでしょう。だからí‚εεygÅ0«N._]また動作します。:もかかわらず...この新しい変化にまだバイトの節約を平らに削除することはできませんí‚vyεygÅ0«N._}ø}«ʒ0KDÙÊ}g
マジックタコ壺

1
@MagicOctopusUrn:興味深い。私はそのコマンドを逃していました。ただ左。それは変だ。
エミグナ

1
@Emigna N(._私は推測できますNFÁ}が、あなたは同じ長さで、この場合]はループとマップを同時に閉じるため、さらに短くなります。全体的に、の使用は._、に比べて1バイトを節約するために残っている場合にのみ役立ちNFÀ}ます。
ケビンクルーッセン

@KevinCruijssen:ああ、かっこいい。あなたが言うように、非常に有用ではありません。
エミグナ


3

オクターブ、98バイト

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

オンラインでお試しください!


1
配列は本当に楽しいですか?; p
ケビンクルーイッセン

そして、オクターブ形式でテストケースを準備してくれてありがとう!
ルイスメンドー

2
@KevinCruijssen配列だけではありません!あなたも持つことができcellfunます、そして、自虐的にstructfunも。Octaveでは、for-loopまたはhavingのいずれかfunです!
Sanchises

そして、b-sx-funを忘れないでください!
ルイスメンドー

3

Haskell、118 112バイト

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)

オンラインでお試しください!

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

61 56 53バイト

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

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

F²

対角線を順方向および逆方向にループします。i=0は前方の対角線をi=1表し、逆の対角線を表します。

FLθ

各行インデックスをループします。これは、対角線の開始のインデックスを表します。

FL§θ⁰«

各列インデックスをループします。

F⟦⁻κ×⊖⊗ιλ⟧

この列インデックスで対角線の行インデックスを計算します。for割り当ての代わりに単一要素配列でループを使用します。これにより、次のステートメントで割り当てをブロックにラップする必要がなくなり、バイトを節約できます。

⎇∧λ﹪⁺μιLθ

これが最初の列か、対角線が下と上の間で折り返されようとしているかどうかを確認します。

⊟υ

そうでない場合は、リストのリストから最後のリストをポップします。

⟦⟧

その場合は、新しい空のリストを開始します。

⊞O...§§θμλ

現在の対角エントリをそのリストに追加します。

⊞υ

そして、そのリストをリストのリストに(戻る)プッシュします。

ILΦυ⊙ι‹⌕ιλμ

重複を含むリストの数を数えます。

i=0との例を見てみましょうk=1。これは、2つの対角線を既に収集したことを意味し[[1,1,5,2],[9,4,3,5]]ます。入力は次のとおりです。

 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

次にlから0にループし7ます。これにより、行と列の両方が毎回1ずつ進みます。

 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

リストは今[[1,1,5,2],[9,4,3,5],[5,4,4]]です。しかしlである3、我々はk+l=4、配列の高さの倍数を。これは、新しいリストを開始する必要があることを意味します[[1,1,5,2],[9,4,3,5],[5,4,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

リストは今[[1,1,5,2],[9,4,3,5],[5,4,4],[2,7,2,1]]です。今ときlである7、我々はk+l=8、配列の高さの別の複数を。これは、新しいリストを開始する必要があることを意味し、そのリストはその対角線の最後の要素で終わります[[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

各行の最初の要素から始まる折り返しの対角線を収集することにより、最終的に配列のすべての対角線を蓄積します。



1

APL + WIN、69バイト

46⍴12 1 2 1 2 1 2 3 4 5 6 6 5 4 3 2 1 2 1 2 1 2 1の形式の2D行列のプロンプト

これにより以下が得られます。

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

オンラインでお試しください!Dyalog Classic提供

説明:

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

利回り:

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

TSQL、140 128バイト

12人のキャラクターをゴルフする方法を見つけました。これはもはや最長のソリューションではありません。

ゴルフ:

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

ゴルフをしていない:

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

やってみよう

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.