行列を切り取り、目的の合計を取得します


21

定義

非負整数の行列と非負整数与えられた場合、を含むすべての行と列を削除する「チョップオフ」関数としてを定義します。k F k M kMkFkMk

例:

M=(615128985604)F5(M)=(1260)

あなたのタスク

Mとターゲットの合計Sが与えられた場合S、タスクは、F_k(M)の残りの要素の合計がSと等しくなるように、kのすべての可能な値を見つけることです。kFk(M)S

例:

上記の行列MS = 9が与えられた場合S=9

  • F = 5 (M)= \ pmatrix {1&2 \\ 6&0}および1 + 2 + 6 + 0 = 9k=5であるため、k = 5は解です。F5(M)=(1260)1+2+6+0=9
  • k=1は、他の唯一の可能なソリューションです:F1(M)=(54)および5+4=9

したがって、期待される出力は{1,5}ます。

明確化と規則

  • 入力は、少なくとも1つのソリューションを受け入れることが保証されています。
  • 元の行列の要素の合計は、Sより大きいことが保証されていますS
  • S> 0と仮定できますS>0。これは、空の行列が解につながらないことを意味します。
  • kの値はk、任意の順序で、合理的で明確な形式で印刷または返されます。
  • 出力を重複排除しないようにすることができます(たとえば、またはは上記の例の有効な回答と見なされます)。[ 1 5 1 5 ][1,1,5,5][1,5,1,5]
  • これはです。

テストケース

M = [[6,1,5],[1,2,8],[9,8,5],[6,0,4]]
S = 9
Solution = {1,5}

M = [[7,2],[1,4]]
S = 7
Solution = {4}

M = [[12,5,2,3],[17,11,18,8]]
S = 43
Solution = {5}

M = [[7,12],[10,5],[0,13]]
S = 17
Solution = {0,13}

M = [[1,1,0,1],[2,0,0,2],[2,0,1,0]]
S = 1
Solution = {2}

M = [[57,8,33,84],[84,78,19,14],[43,14,81,30]]
S = 236
Solution = {19,43,57}

M = [[2,5,8],[3,5,8],[10,8,5],[10,6,7],[10,6,4]]
S = 49
Solution = {2,3,4,7}

M = [[5,4,0],[3,0,4],[8,2,2]]
S = 8
Solution = {0,2,3,4,5,8}

入力配列の元の構造を保持すること(たとえば、[[1,5],[1],[5],[]]最初のテストケースの場合)は、出力の有効な手段になりますか?
シャギー

@Shaggyはい。それは合理的に見えます。
アーナルド

回答:


10

K(ngn / k)、39バイト

{a@&y=x{+//x*(&/'b)&\:&/b:~x=y}/:a:,/x}

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

この説明をありがとう@Adám

{... }機能は、xあるMyあるS

,/xMを  フラット化します(これらはk個の候補です)

a: 割りあてる a

x{Mを固定左引数()として}/: 使用しながら、それぞれに次の関数を適用します。x

  x=yMの  要素が現在のk候補と等しい場所を示すブール行列

  ~ それを否定する

  b: それに割り当てる b

  &/ AND削減(そのkのない列を検索)

  ()&\: そして、以下のそれぞれについて:

   &/'b ANDの削減(そのkなしで行を検索)

  x* それにMを掛ける

  +// 総計

y=Sがそれらの合計に等しい 場所を示すブール値のリスト

& 真のインデックス

a@ それを使用して要素にインデックスを付けます(k個の候補)


説明を修正してください。
アダム

コピーペーストの説明の危険性…
アダム

6

APL(Dyalog Unicode)35 33 28 バイトSBCS

-7 ngnに感謝します。

匿名中置ラムダ。Sを左引数、Mを右引数として取ります。

{⍵[⍸⍺=(+/∘,⍵×∧/∘.∧∧⌿)¨⍵≠⊂⍵]}

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

{} "dfn"、およびそれぞれ左および右の引数(SおよびM):

⍵[… 次の座標を持つ] インデックスM

  ⊂⍵Mを 囲んで単一の要素として扱う

  ⍵=Mの  各要素(すなわちk候補)をそのM全体と比較する

  ( 次の暗黙関数をそれぞれに適用します。

   ∧⌿ 垂直AND削減(そのk候補のない列を検索)

∘.∧ デカルトブール積:

    ∧/ 水平AND縮小(そのk候補のない行を見つけます)

   ⍵×Mにそのマスクを 掛ける

   +/∘, 平坦化された行列の合計

  ⍺=Sがそれらの合計に等しい 場所を示すブール

   それが当てはまるインデックス


1
{M[⍸⍺={+/,(∧⌿d)/M⌿⍨∧/d←M≠⍵}¨M←⍵]}
ngn

@ngnありがとう。ただし、評価の順序が混乱するため、グローバルは使用しません。—まだ作成されていないときにインデックスをM作成するにはどうすればよいですか?
アダム

内側のdfnのように渡すことは、私にとっても同様に混乱します
-ngn

{⍵[⍸⍺=+/¨(,⍵×∧/∘.∧∧⌿)¨⍵≠⊂⍵]}
ngn

@ngnうん、私はそのようなことをしたかった。ありがとう!
アダム


5

ゼリー20 19 17 15 14バイト

pZnⱮFȦ€€ḋFẹƓịF

これは、引数としてMを取り、STDINからSを読み取るモナドリンクです。

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

使い方

pZnⱮFȦ€€ḋFẹƓịF  Main link. Argument: M

 Z              Zip; transpose the rows and columns of M.
p               Take the Cartesian product of M and its transpose, yielding all pairs
                (r, c) of rows and columns of M.
    F           Flatten; yield the elements of M.
  nⱮ            Not equal map; for each element e of M, compare the elements of the
                pairs (r, c) with e.
     Ȧ€€        All each each; for each array of Booleans corresponding to an (r, c)
                pair, test if all of them are true.
         F      Flatten; yield the elements of M.
        ḋ       Take the dot product of each list of resulting Booleans and the
                elements of M.
           Ɠ    Read an integer S from STDIN.
          ẹ     Find all indices of S in the dot products.
             F  Flatten; yield the elements of M.
            ị   Retrieve the elements of the right at the indices from the left.


5

Haskell88 86 84 77バイト

m!s=[k|k<-m>>=id,s==sum[x|r<-m,all(/=k)r,(i,x)<-zip[0..]r,all((/=k).(!!i))m]]

すべてのテストケースを検証します

説明

m ! s =                                         -- function !, taking m and s as input
    [k |                                        -- the list of all k's such that
        k <- m >>= id,                          -- * k is an entry of m
        s == sum                                -- * s equals the sum of
            [x |                                --     the list of x's such that
                r <- m,                         --     * r is a row of m
                all (/= k) r,                   --     * r does not contain k
                (i, x) <- zip [0 ..] r,         --     * i is a valid column index; also let x = r[i]
                all ((/= k) . (!! i)) m         --     * none of the rows contain k at index i
            ]
    ]

それは「関数f」と言うべきですか?
Quintec

1
@Quintec確かにあるはずですが、「関数!」に変更しました BWOの
-Delfad0r

5

Pyth 27 23 22 21  20バイト

fqvzss.DRsxLTQ-I#TQs

テストスイート!

重複排除しません。

使い方?

fqvzss.DRsxLTQ-I#TQs     Full program.
f                  s     Flatten M and keep only those elements T which satisfy:
 qvzss.DRsxLTQ-I#TQ      The filtering function. Breakdown:
              -I#TQ      Discard the rows that contain T. More elaborate explanation:
                # Q         |-> In M, keep only those elements that are...
               I            |-> Invariant under (equal to themselves after...)
              -  T          |-> Removing T.
                         Let's call the result of this expression CR (chopped rows).
          xLTQ           Map over the rows M and retrieve all indices of T.
         s               Collect indices in 1D list (flatten). Call this I.
      .DR                For each row left in CR, remove the elements at indices in I.
    ss                   Sum all the elements of this matrix flattened.
 qvz                     And then finally check whether they equal S.


4

Perl 6の80の 74バイト

->\m,\s{grep {s==sum m[m.$_;[[Z](m).$_]]}o{*.grep(:k,!*.grep($_))},m[*;*]}

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

説明

->\m,\s{...}  # Anonymous block taking arguments m and s
  grep {...}o{...},m[*;*]   # Filter matrix elements
                            # with combination of two functions
    *.grep(:k,!*.grep($_))  # (1) Whatever code returning matching rows
    s==sum m[               # (2) s equals sum of elements
      m.$_;                 #     in matched rows
      [                     #     (array supporting multiple iterations)
       [Z](m).$_            #     and matched columns (matched rows
                            #     of m transposed with [Z])
      ]
    ]

3

05AB1E、21バイト

²˜ʒQεZ+}øεZ<~}ø_*OO¹Q

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

この答えを書いて初めて、ケビンのを見ました。これはかなり異なると思うので、個別に投稿しています。私の直感では、最適なバイトカウントは約18であるため、これを再確認し、他に何ができるかを確認する必要があります。現在のコードでは、テストスイートを作成することはできませんが、すべてのテストケースを自分で検証し、結果は正しいです。

切り抜きアルゴリズム

使用されている手法をわかりやすく説明するために、をトリミングする要素を使用して例を示します。k=5

M=(615128985604)

最初にと等しい行列を生成します:k

(001000001000)

その後、それが通過すると各行のための、それは追加の各要素に依然として探索要素の水平方向の位置の一意性を維持しながら、必要な行をハイライト:R max R RMRmax(R)R

(112000112000)

次に、の転置を行い、列ごとに、操作ここでは05AB1Eのビット単位のORです。加算も機能するはずです。したがって、それもテストする場合は置き換えてください。C max C 1 | | C C CMC(max(C)1) || c  cC||~+

(113001113001)

最後に、を、他のすべての整数をにマッピングし、要素ごとの乗算を実行します。1 0 M010M

(000110000110)(000120000600)

その後、結果のマトリックスの合計が計算されます。


1
いい答えだ!私は私のゴルフが確かにゴルフに適していることを知っていました。私はの迷惑な場合も含め、すでにそれが働いて持って幸せ十分だった[[1,1,0,1],[2,0,0,2],[2,0,1,0]]数のために私をねじ込みている1(すべての列を削除します。)私は確かに可能性だけでなく、私の頭の中でわずか20の下に持っていました。残念なことに、最近追加された製品にもかかわらず、マトリックスの組み込みはほとんどありません。1|21 2~05AB1E synthaxに)3で得、これは、であるlogical ORように作用binary OR以外番号場合0/ 1関与しているが(私が考える/仮定する)。
ケビンクルーッセン

@KevinCruijssenおっしゃるとおりです!その後、ドキュメントは書くべきビットORない、OR論理。すぐに修正する必要があります。とにかく、ビット単位のORでもうまくいくと思います。+とにかくそれで置き換えることができるので、問題がないことを願っています:)
Mr. Xcoder

2

05AB1E(レガシー)27 26 バイト

˜ʒ©¹ε®å_}¹ζʒ®å_}ζ‚ζ€€OPOIQ

結果を並べ替えたり、一意化したりしません。
内側のリストの一部が整数で、他のリストがリストである場合、sum-eachが奇妙なことをしているように見えるので、(現在のところ)レガシーでのみ機能します。

オンラインそれを試してみたり、すべてのテストケースを確認してください

説明:

˜              # Flatten the (implicit) matrix-input
               #  i.e. [[6,1,5],[1,2,8],[9,8,5],[6,0,4]] → [6,1,5,1,2,8,9,8,5,6,0,4]
 ʒ             # Filter this list by:
  ©            #  Store the current value in a register-variable
   ¹           #  Take the matrix-input
    ε   }      #  Map it to:
     ®å_       #   0 if the current number is in this row, 1 if not
               #    i.e. [[6,1,5],[1,2,8],[9,8,5],[6,0,4]] and 6 → [0,1,1,0]
   ¹           #  Take the matrix-input again
    ζ          #  Swap its rows and columns
               #   i.e. [[6,1,5],[1,2,8],[9,8,5],[6,0,4]] → [[6,1,9,6],[1,2,8,0],[5,8,5,4]]
     ʒ   }     #  Filter it by:
      ®å_      #   Only keep the inner lists that does not contain the current number
               #    i.e. [[6,1,9,6],[1,2,8,0],[5,8,5,4]] and 6 → [[1,2,8,0],[5,8,5,4]]
               #    i.e. [[1,2,2],[1,0,0],[0,0,1],[1,2,0]] and 1 → []
          ζ    #  After filtering, swap it's rows and columns back again
               #   i.e. [[1,2,8,0],[5,8,5,4]] → [[1,5],[2,8],[8,5],[0,4]]
   ‚ζ          #  Pair both lists together and zip them
               #   i.e. [0,1,1,0] and [[1,5],[2,8],[8,5],[0,4]]
               #    → [[0,[1,5]],[1,[2,8]],[1,[8,5]],[0,[0,4]]]
               #   i.e. [0,1,0] and [] → [[0,' '],[1,' '],[0,' ']]
              #  Map each inner list / value to:
      O       #   Sum each
               #    i.e. [[0,[1,5]],[1,[2,8]],[1,[8,5]],[0,[0,4]]]
               #     → [[0,6],[1,10],[1,13],[0,4]]
               #    i.e. [[0,' '],[1,' '],[0,' ']]
               #     → [[0,0],[1,0],[0,0]]
               #  (NOTE: For most test cases just `O` instead of `€€O` would be enough,
               #   but not if we removed ALL zipped inner lists for a number, like the 
               #   second example above with input [[1,1,0,1],[2,0,0,2],[2,0,1,0]] and 1)
        P      #  Now take the product of each inner list
               #   i.e. [[0,6],[1,10],[1,13],[0,4]] → [0,10,13,0]
         O     #  Then take the sum of those
               #   i.e. [0,10,13,0] → 23
          IQ   #  And only keep those that are equal to the number-input
               #   i.e. 23 and 9 → 0 (falsey), so it's removed from the flattened input


1

、33バイト

FθFι⊞υκIΦυ⁼ηΣEθ∧¬№λιΣEλ∧¬№Eθ§πξιν

オンラインでお試しください!リンクはコードの詳細バージョンへのものであり、重複排除が含まれています。説明:

FθFι⊞υκ

最初の入力配列qを定義済みリストにフラット化しますu

  υ                          Flattened array
 Φ                           Filter elements
       θ                     Input array
      E                      Map over rows
            ι                Current element
           λ                 Current row
          №                  Count matching elements
         ¬                   Logical Not
        ∧                    Logical And
               λ             Current row
              E              Map over columns
                    θ        Input array
                   E         Map over rows
                      π      Inner row
                       ξ     Column index
                     §       Inner element
                        ι    Current element
                  №          Count matching elements
                 ¬           Logical Not
                ∧            Logical And
                         ν   Current element
             Σ               Sum
     Σ                       Sum
    η                        Second input
   ⁼                         Equals
I                            Cast to string
                             Implicitly print each result on its own line

リストの各要素について、配列を合計しますが、行に要素が含まれている場合0はその合計の代わりに使用し、要素を含まない行を合計する場合、列に要素が含まれている場合0は列の値の代わりに使用します。これは、Charcoalが空のリストを合計できないため、要素をフィルタリングするよりもわずかにゴルファーです。


1

クリーン、92バイト

import StdEnv
$m s=[c\\r<-m,c<-r|sum[b\\a<-m|all((<>)c)a,b<-a&x<-[0..]|all(\u=u!!x<>c)m]==s]

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

説明:

$ m s                       // the function $ of `m` and `s`
 = [                        // is equal to
  c                         // the value `c`
  \\ r <- m                 // for every row `r` in `m`
  , c <- r                  // for every value `c` in `r`
  | sum [                   // where the sum of
   b                        // the value `b`
   \\ a <- m                // for every row `a` in `m`
   | all ((<>)c) a          // where `c` isn't in `a`
   , b <- a                 // for every value `b` in `a`
   & x <- [0..]             // with every column index `x` from zero
   | all (\u = u!!x <> c) m // where `c` isn't in column `x`
  ] == s                    // equals `s`
 ]

1

MATLAB-80バイト

修正および)コンパクト化:

function f(M,s);for k=M(:)';if sum(sum(M(~sum(M==k,2),~sum(M==k))))==s;k,end;end

そして、完全に開発されたバージョンでは:

function getthesum(M,s)

for k=M(:)'                         % For each element of M
    x = M==k ;                      % Index elements equal to "k"
    N = M( ~sum(x,2) , ~sum(x) ) ;  % New matrix with only the appropriate rows/columns
    if sum(sum(N))==s               % sum rows and columns and compare to "s"
        k                           % display "k" in console if "k" is valid
    end
end

最初の間違いを強調するコメントに感謝します。このバージョンは出力の重複を排除しないことに注意してください。

さらに5バイトで出力を重複排除できます。

% This will only cycle through the unique elements of 'M' (85 bytes):

function f(M,s);for k=unique(M)';if sum(sum(M(~sum(M==k,2),~sum(M==k))))==s;k,end;end

1
kは行列の任意の要素です。
デニス

@Dennis、おっとそうです...残念です、今日は修正します。それを指摘してくれてありがとう。
ホキ

1
@アーナウルド。休暇中だったので申し訳ありません。
ホキ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.