Суммируйте дельты моей матрицы


17

Фон

Дельты массива целых чисел - это массив, сформированный путем получения различий последовательных элементов. Например, [1, 2, 4, 7, 3, 9, 6]имеют следующие дельты: [1, 2, 3, -4, 6, -3].

Теперь мы определим дельты матрицы целых чисел как дельты каждой строки и каждого столбца, который она содержит.

В качестве примера:

Row deltas:

1 2 3 4 │ => [1, 1, 1]
4 5 6 7 │ => [1, 1, 1]
7 1 8 2 │ => [-6, 7, -6]

Column deltas (the matrix' columns have been rotated into rows for simplicity):

1 4 7 │ => [3, 3] 
2 5 1 │ => [3, -4]
3 6 8 │ => [3, 2]
4 7 2 │ => [3, -5]

Что дает нам следующий список матричных дельт:

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

И поскольку мы не хотим, чтобы они были вложенными, мы сглаживаем этот список:

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

задача

Ваша задача - суммировать все дельты матрицы, заданной в качестве входных данных. Обратите внимание, что матрица будет состоять только из неотрицательных целых чисел.

правила

  • Все стандартные правила применяются.

  • Можно предположить, что матрица содержит как минимум два значения в каждой строке и столбце, поэтому минимальный размер будет 2x2 .

  • Вы можете взять матрицу в любом разумном формате, если вы укажете ее.

  • Вы не можете предполагать, что матрица квадратная.

  • Если это может помочь вам уменьшить количество байтов, вы также можете принять количество строк и количество столбцов в качестве входных данных (глядя на вас C!).

  • Это код-гольф, поэтому выигрывает самый короткий код (в байтах) на каждом языке !

Тестовые случаи

Вход => Выход

[[1, 2], [1, 2]] => 2
[[8, 7, 1], [4, 1, 3], [5, 5, 5]] => -9
[[1, 2, 3], [4, 5, 6], [7, 8, 9]] => 24
[[9, 9, 9, 9, 9], [9, 9, 9, 9, 9]] => 0
[[1, 3, 14], [56, 89, 20], [99, 99, 99]] => 256
[[1, 2, 3, 4], [4, 5, 6, 7], [7, 1, 8, 2]] => 9
[[13, 19, 478], [0, 12, 4], [45, 3, 6], [1, 2, 3]] => -72

Ответы:


12

Python 2 , 42 байта

lambda m:sum(r[-1]-r[0]for r in m+zip(*m))

Безымянная функция, принимающая список списков, m и возвращает полученное число.

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

Как?

Сумма дельт списка - это последний элемент минус первый, все остальное просто отменяется:
(r [n] -r [n-1]) + (r [n-1] -r [n-2]) + ... + (r [2] -r [1]) = r [n] -r [1]

В zip(*m)использует распаковку ( *) из mпередавать строки в mвиде отдельных аргументов zip(чередование) и , следовательно , переставляет матрицу. В Python 2 это дает список (из кортежей, но это нормально), поэтому мы можем добавить (объединить) его в (с) m, пройти по всем нашим строкам и столбцам r, выполнить вышеуказанный трюк для каждого и просто сложить результаты ( sum(...)).


8

R , 34 байта

function(m)sum(diff(m),diff(t(m)))

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

Анонимная функция. Первоначально я использовал apply(m,1,diff)для получения разностных разностей (а 2не 1для столбцов), но, глядя на ответ Стью Гриффин, я попробовал его просто, diffи это сработало.


8

Октава , 33 байта

@(x)sum([diff(x)(:);diff(x')(:)])

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

Объяснение:

Это анонимная функция, принимающая в xкачестве входных данных. Он берет разницу между всеми столбцами и объединяет ее с разницей между столбцами транспонированного x. Затем он суммирует этот вектор по второму измерению.



5

JavaScript (ES6), 68 67 байт

m=>m.map(r=>s+=[...l=r].pop()-r[0],s=0)|m[0].map(v=>s+=l.pop()-v)|s

Отформатировано и прокомментировано

m =>                              // given a matrix m
  m.map(r =>                      // for each row r of m
    s += [...l = r].pop() - r[0], //   add to s: last value of r - first value of r
    s = 0                         //   starting with s = 0
  ) |                             //
  m[0].map(v =>                   // for each value v in the first row of m:
    s += l.pop() - v              //   add to s: last value of last row of m - v
  ) |                             //
  s                               // return s

Поскольку минимальный размер входной матрицы составляет 2x2, m.map(...)|m[0].map(...)гарантированно будет приведен к 0. Вот почему безопасно возвращать конечный результат с|s .

Контрольные примеры


5

MATL , 7 байт

dG!dhss

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

Объяснение:

Предположим, что вход

[8 7 1; 4 1 3; 5 5 5]

d        % Difference between rows of input
         % Stack:
         % [-4 -6  2; 1  4  2]
 G       % Grab the input again. Stack:
         % [-4 -6  2; 1  4  2]
         % [8 7 1; 4 1 3; 5 5 5]]
  !      % Transpose the bottom element. Stack:
         % [-4 -6  2; 1  4  2]
         % [8 4 5; 7 1 5; 1 3 5]
   d     % Difference between rows. Stack:
         % [-4 -6  2; 1  4  2]
         % [-1 -3  0; -6  2  0]
    h    % Concatenate horizontally. Stack:
         % [-4 -6  2 -1 -3  0; 1  4  2 -6  2  0]
     ss  % Sum each column, then sum all column sums. Stack:
         % -9



3

Шелуха , 7 байт

ΣṁẊ-S+T

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

-1 спасибо мистеру Xcoder, который отвел мое внимание от Sи ¤и к m(что должно было быть ).
-1 благодаря злоупотреблению ЗгарбомS .

Объяснение:

ΣṁẊ-S+T 3-function composition
    S   (x -> y -> z) (f) -> (x -> y) (g) -> x (x) (implicit): f x g x
     +    f: [x] (x) -> [x] (y) -> [x]: concatenate two lists
      T   g: [[x]] (x) -> [[x]]: transpose x
 ṁ      (x -> [y]) (f) -> [x] (x) -> [y]: map f on x and concatenate
  Ẋ       f: (x -> y -> z) (f) -> [x] (x) -> [z]: map f on splat overlapping pairs of x
   -        f: TNum (x) -> TNum (y) -> TNum: y - x
Σ       [TNum] (x) -> TNum: sum x

Да, 8 байтов , используя .
г-н Xcoder

8 байтов тоже, используя вместо этого ваш подход.
г-н Xcoder

@ Mr.Xcoder вау забыл об этом
Эрик Outgolfer


3

Haskell , 60 байт

e=[]:e
z=zipWith
f s=sum$(z(-)=<<tail)=<<(s++foldr(z(:))e s)

Попробуйте онлайн! Использует более короткие транспонирования я нашел некоторое время назад.

объяснение

eпредставляет собой бесконечный список пустых списков и используется для транспонирования. zявляется сокращением для zipWithфункции, потому что она используется дважды.

f s=                                        -- input s is a list of lists
                            foldr(z(:))e s  -- transpose s
                         s++                -- append the result to the original list s
                     =<<(                 ) -- map the following function over the list and concatenate the results
        (z(-)=<<tail)                       -- compute the delta of each list by element-wise subtracting its tail
    sum$                                    -- compute the sum of the resulting list

3

Брахилог , 13 байт

изначально основанный на дизайне @ sundar

⟨≡⟨t-h⟩ᵐ²\⟩c+ 

объяснение

⟨≡      \⟩          #   Take the original matrix and it's transpose 
      ᵐ             #       and execute the following on both
       ²            #           map for each row (this is now a double map "ᵐ²")
  ⟨t h⟩             #               take head and tail
   -                #               and subtract them from each other (sum of deltas in a row)
         c+         #       and add all the values 
                    #           (we have two arrays of arrays so we concat them and sum them)

⟨⟩будут баловаться форматирования, извините

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


2

Pyth, 7 байт

ss.+M+C

Попробуй это здесь.

Мой первый ответ на языке игры в гольф! Благодаря @EriktheOutgolfer за -1 байт!

объяснение

ss.+M+C    ~ This is a full program with implicit input (used twice, in fact)

      C    ~ Matrix transpose. Push all the columns;
     +     ~ Concatenate with the rows;
  .+M      ~ For each list;
  .+       ~ Get the deltas;
 s         ~ Flatten the list of deltas;
s          ~ Get the sum;
           ~ Print Implicitly;

.tможно Cза -1.
Эрик Outgolfer

@EriktheOutgolfer Ого, спасибо!

2

Брахилог , 22 16 байт

⟨≡{s₂ᶠc+ᵐ-}ᵐ\⟩+ṅ

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

(-6 байт, вдохновленные предложениями @ Kroppeb.)

?⟨≡{s₂ᶠc+ᵐ-}ᵐ\⟩+ṅ.       Full code (? and . are implicit input and output)
?⟨≡{       }ᵐ\⟩          Apply this on both the input and its transpose:
    s₂ᶠ                  Get pairs of successive rows, [[row1, row2], [row2, row3], ...]
       c                 Flatten that: [row1, row2, row2, row3, row3, row4, ...]
        +ᵐ               Sum the elements within each row [sum1, sum2, sum2, sum3, ...]
          -              Get the difference between even-indexed elements (starting index 0)
                         and odd-indexed elements, i.e. sum1+sum2+sum3+... - (sum2+sum3+sum4+...)
                         This gets the negative of the usual difference i.e. a-b instead of b-a
                         for each pair of rows
               +         Add the results for the input and its transpose
                ṅ        Negate that to get the sign correct
                 .       That is the output

Сумма дельт равна последнему элементу - первый ⟨t-h⟩делает свое дело. В результате {⟨t-h⟩ᵐ+}R&\↰₁;R+чего на 5 байт короче. Попробуйте онлайн!
Kroppeb

использование ⟨≡{...}ᵐ\⟩+вместо {...}R&\↰₁;R+сохранения 2 байта. В результате ⟨≡{⟨t-h⟩ᵐ+}ᵐ\⟩+ попробуйте онлайн!
Кроппеб

Изменение отображения карты в двойную карту, объединение и соминг в и удаляет дополнительные 2 байта ⟨≡⟨t-h⟩ᵐ²\⟩c+. Попробуйте онлайн!
Kroppeb

@Kroppeb Это достаточно другое и достаточно большое улучшение, поэтому вы должны опубликовать его как новый ответ самостоятельно. Увидев ваши предложения, я получил представление о 16-байтовом решении с использованием другого метода. ⟨≡{s₂ᶠc+ᵐ-}ᵐ\⟩+ṅ Попробуйте онлайн! , поэтому я обновлю этот ответ вместо этой версии.
sundar - Восстановить Монику


1

SOGL V0.12 , 9 байтов

:⌡-≤H⌡-¹∑

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

Объяснение:

:          duplicate ToS
 ⌡         for each do
  -          get deltas
   ≤       get the duplicate ontop
    H      rotate it anti-clockwise
     ⌡     for each do
      -      get deltas
       ¹   wrap all of that in an array
        ∑  sum

1
добавил, потому что это принимает входные данные в стеке - я давно хотел спросить это: автоматически ли ввод вводится в стек? Если это не так, и ожидается, что входные данные уже присутствуют в стеке, разве вы не должны добавить в свой счетчик байтов? Не уверен, как эти ситуации обрабатываются. Или это как функция?
г-н Xcoder

@ Mr.Xcoder хм .. я подумал , что было разрешено входами по умолчанию, но я предполагаю , что есть только это для функции .. Опять же , я мог бы назвать эту безымянную функцию , используемой в этом (в SOGL с «функцией» ы определения functionNameSingleChar\n)
Дзайма

О хорошо Это совершенно верно тогда.
г-н Xcoder

1

Mathematica, 45 байт

Tr@Flatten[Differences/@#&/@{#,Transpose@#}]&

вход

[{{13, 19, 478}, {0, 12, 4}, {45, 3, 6}, {1, 2, 3}}]


Будет ли короче вычесть первое из последнего для каждого массива в {#,Transpose@#} (как мой ответ на Python)?
Джонатан Аллан

Total[Differences/@{#,Thread@#},3]&
alephalpha

1

CJam , 19 байтов

0q~_z+2few:::-:+:+-

Ввод представляет собой список списков чисел. Попробуйте онлайн!

объяснение

0       e# Push 0
q~      e# Evaluated input. 
_       e# Duplicate
z       e# Zip (transpose)
+       e# Concatenate. This gives a lists of lists of numbers, where the
        e# inner lists are the original rows and the columns
2few    e# Replace each inner list of numbers by a list of overlapping
        e# slices of size 2. We not have three-level list nesting
:::-    e# Compute difference for each of those size-two slices. We now
        e# have the deltas for each row and column
:+      e# Concatenate all second-level lists (de-nest one level)
:+      e# Sum all values
-       e# Subtract from 0, to change sign. Implicitly display

4
Этот ответ требует больше двоеточий. Есть 2fewдвоеточия.
Esolanging Fruit

0

МОЙ, 9 байт

ωΔω⍉Δ ḟΣ↵

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

Так как я не могу пропинговать Денниса в чате, чтобы вытащить MY (из-за приостановки), это в настоящее время не будет работать. (Δ ранее не vecify при вычитании) Благодаря тому, кто заставил Денниса вытащить МОЕГО!

Как?

  • ωΔ, приращения первого аргумента командной строки
  • ω⍉Δ, приращения транспонирования первого аргумента командной строки
  • в одном списке
  • сплющить
  • Σ, сумма
  • , выход


0

Пыть , 11 байт

Đ⊤ʁ-⇹ʁ-áƑƩ~

Объяснение:

          Implicit input (as a matrix)
Đ         Duplicate the matrix
⊤         Transpose the matrix
ʁ-        Get row deltas of transposed matrix
⇹         Swap top two elements on the stack
ʁ-        Get row deltas of original matrix
á         Push the stack into an array
Ƒ         Flatten the array
Ʃ         Sum the array
~         Flip the sign (because the deltas are negative, as subtraction was performed to obtain them)
          Implicit output
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.