Отрежьте матрицу, чтобы получить желаемую сумму


21

Определение

Учитывая матрицу M неотрицательных целых чисел и неотрицательное целое число k , мы определяем Fk как функцию «отбивки», которая удаляет все строки и все столбцы в которые содержат k .Mk

Пример:

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

Твое задание

Учитывая и целевая сумма , ваша задача состоит в том, чтобы найти все возможные значения таким образом, что сумма остальных элементов в равна .MSkFk(M)S

Пример:

Учитывая приведенные выше матрицы и :MS=9

  • k=5 является решением, потому что иF5(M)=(1260)1+2+6+0=9
  • k=1 - единственное возможное решение: иF1(M)=(54)5+4=9

Таким образом, ожидаемый результат будет .{1,5}

Разъяснения и правила

  • На входе гарантированно допускается хотя бы одно решение.
  • Сумма элементов в исходной матрице гарантированно будет больше , чем .S
  • Вы можете предположить, что . Это означает, что пустая матрица никогда не приведет к решению.S>0
  • Значения могут быть напечатаны или возвращены в любом порядке и в любом разумном, однозначном формате.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],[]]для первого контрольного примера) будет допустимым средством вывода?
Лохматый

@ Шэгги Да. Это выглядит разумно.
Арно

Ответы:


10

К (нгн / к) , 39 байт

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

Попробуйте онлайн!

спасибо @ Adám за это объяснение :

{... }функция, xявляется M и yявляется S

,/x сгладить М (это k кандидатов)

a: назначить на a

x{}/: Применить следующую функцию к каждому, используя M в качестве фиксированного левого аргумента ( x):

  x=y Булева матрица, указывающая, где элементы M равны текущему k кандидату

  ~ отрицать это

  b: назначить это b

  &/ И сокращение (находит столбцы без этого k )

  (... )&\: И это с каждым из следующего:

   &/'b И сокращение каждого (находит строки без этого k )

  x* умножить М на это

  +// общая сумма

y= список логических значений, указывающих, где S равно этим суммам

& индексы истин

a@ используйте это, чтобы индексировать в элементы ( k кандидатов)


Не стесняйтесь исправить объяснение.
августа

Опасности объяснения копирования-вставки ...
Адам

6

APL (Dyalog Unicode) , 35 33 28 байт SBCS

-7 благодаря нгн.

Анонимный инфикс лямбда. Принимает S в качестве левого аргумента и M в качестве правого аргумента.

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

Попробуйте онлайн!

{} «Dfn», и это левый и правый аргументы ( S и M ) соответственно:

⍵[] Индекс М со следующими координатами:

  ⊂⍵ заключить M, чтобы рассматривать его как единый элемент

  ⍵= сравнить каждый элемент (т. е. k кандидатов) из M со всем этим M

  ( Применить следующую молчаливую функцию к каждому:

   ∧⌿ вертикальное И сокращение (находит столбцы без этого k кандидата)

∘.∧ Декартово булево произведение с:

    ∧/ горизонтальное сокращение И (находит строки без этого k кандидата)

   ⍵× умножить М с этой маской

   +/∘, суммировать сплюснутую матрицу

  ⍺= Логическое указание, где S равно этим суммам

   индексы, где это правда


1
{M[⍸⍺={+/,(∧⌿d)/M⌿⍨∧/d←M≠⍵}¨M←⍵]}
августа

@ngn Спасибо. Однако я не буду использовать глобальную переменную, так как это приводит к путанице в оценке: - Как можно индексировать, Mкогда она еще не создана?
августа

прохождение как во внутреннем dfn одинаково смущает меня
ngn

{⍵[⍸⍺=+/¨(,⍵×∧/∘.∧∧⌿)¨⍵≠⊂⍵]}
августа

@ngn Да, я хотел сделать что-то подобное. Благодарность!
августа


5

Желе , 20 19 17 15 14 байт

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

Это монадическая ссылка, которая принимает M в качестве аргумента и читает S из STDIN.

Попробуйте онлайн!

Как это устроено

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

Haskell , 88 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 Действительно, так и должно быть, но я изменил его на «функционировать!» сэкономить 2 байта благодаря 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, поэтому мне придется вернуться к этому и посмотреть, что еще я могу сделать. С помощью текущего кода невозможно написать набор тестов, но я сам проверил все тестовые примеры и результаты верны.

Алгоритм обрезки

Кзнак равно5

Mзнак равно(615128985604)

К

(001000001000)

MрМаксимум(р)р

(112000112000)

MС(Максимум(С)-1) || с  сС (где ||является побитовое ИЛИ 05AB1E в - дополнение должно работать тоже, так что заменить ~с , +если вы хотите проверить , что тоже), что приводит к:

(113001113001)

Наконец, это карты 0 в 1 и все остальные целые 0 и выполняет поэлементное умножение с M:

(000110000110)(000120000600)

После чего вычисляется сумма полученной матрицы.


1
Хороший ответ! Я знал, что мой будет в гольф наверняка. Я был уже достаточно счастлив, чтобы это работало, в том числе надоедливый случай, [[1,1,0,1],[2,0,0,2],[2,0,1,0]]когда меня подставили для номера 1(который удаляет каждый столбец ...) У меня действительно было чуть меньше 20 в моей голове, а также возможность. Жаль, что встроенных матриц практически нет, несмотря на добавленные в последнее время продукты. Что касается 1|2( 1 2~в 05AB1E synthax), приводящего к 3, то это потому, что logical ORдействует как a, binary ORкогда участвуют числа, отличные от 0/ 1(я думаю / предполагаю).
Кевин Круйссен

@KevinCruijssen Oh you are right! Then, the docs should write bitwise OR, not logical OR. I am going to have to correct that soon. Anyway, bitwise OR should work as well I think. It can be replaced by + anyway I guess, so I hope there will be no issues with it :)
г-н Xcoder

2

05AB1E (legacy), 27 26 bytes

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

Does not sort nor uniquify the result.
Only works in the legacy (for now), because sum-each seems to be doing some odd things when part of the inner lists are integers and other are lists..

Try it online or verify all test cases.

Explanation:

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

Charcoal, 33 bytes

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

Try it online! Link is to verbose version of code and includes deduplication. Explanation:

FθFι⊞υκ

Flatten the first input array q into the predefined list 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

For each element of the list, sum the array, but if the row contains the element then use 0 instead of its sum, and when summing rows that don't contain the element, if the column contains the element then use 0 instead of the column's value. This is very slightly golfier than filtering the elements out as Charcoal can't sum an empty list.


1

Clean, 92 bytes

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]

Try it online!

Explained:

$ 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 bytes

(Corrected and) Compacted:

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

And in a fully developped version:

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

Thanks to the comments to highlight my initial mistake. Note that this version does not de-duplicate the output.

It is possible to deduplicate the output with 5 more bytes:

% 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 could be any element of the matrix.
Dennis

@ Денис, упс, все верно ... Плохо, я исправлю это позже сегодня. Спасибо за указание на это.
Хоки

1
@Arnauld. Sorry I was on holidays, that it fixed now.
Hoki
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.