Модульное вещание

24

Эта проблема связана с некоторыми возможностями языка MATL в рамках мероприятия « Язык месяца», который состоится в мае 2018 года .


Введение

В MATL, многие две входные функции работают поэлементно с вещанием . Это означает следующее:

  • Поэлементный (или векторизованный ): функция принимает в качестве входных данных два массива с соответствующими размерами. Операция, определенная функцией, применяется к каждой паре соответствующих записей. Например, используя запись после исправления:

    [2 4 6] [10 20 30] +
    

    дает выход

    [12 24 36]
    

    Это также работает с многомерными массивами. Обозначение [1 2 3; 4 5 6]представляет массив 2× 3(матрица)

    1 2 3
    4 5 6
    

    который имеет размер 2вдоль первого измерения (по вертикали) и 3вдоль второго (по горизонтали). Так например

    [2 4 6; 3 5 7] [10 20 30; 40 60 80] *
    

    дает

    [20 80 180; 120 300 560]
    
  • Широковещание или ( одноэлементное расширение ): два входных массива не имеют совпадающих размеров, но в каждом несоответствующем измерении один из массивов имеет размер 1. Этот массив неявно реплицируется по другим измерениям для согласования размеров; и затем операция применяется поэлементно, как указано выше. Например, рассмотрим два входных массива с размерами 1× 2и 3× 1:

    [10 20] [1; 2; 5] /
    

    Благодаря вещанию это эквивалентно

    [10 20; 10 20; 10 20] [1 1; 2 2; 5 5] /
    

    и так это дает

    [10 20; 5 10; 2 4]
    

    Аналогично, с размерами 3× 2и 3× 1(вещание теперь действует только во втором измерении),

    [9 8; 7 6; 5 4] [10; 20; 30] +
    

    дает

    [19 18; 27 26; 35 34]
    

    Количество измерений может даже отличаться. Например, входные данные с размерами 3 × 2 и 3 × 1 × 5 являются совместимыми и дают результат 3 × 2 × 5. На самом деле, размер 3 × 2 такой же, как 3 × 2 × 1 (имеется произвольно много неявных конечных одноэлементных измерений).

    С другой стороны, пара массивов 2× 2и 3× 1выдаст ошибку, потому что размеры по первому измерению равны 2и 3: они не равны и ни один из них не равен 1.

Определение модульного вещания

Модульное вещание - это обобщение вещания, которое работает, даже если нет несоответствующих размеров 1. Рассмотрим, например, следующие массивы 2× 2и 3× в 1качестве входных данных функции +:

[2 4; 6 8] [10; 20; 30] +

Правило состоит в следующем: для каждого измерения массив, меньший по этому измерению, реплицируется модульно (циклически), чтобы соответствовать размеру другого массива. Это сделало бы вышеуказанный эквивалент

[2 4; 6 8; 2 4] [10 10; 20 20; 30 30] +

с результатом

[12 14; 26 28; 32 34]

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

[5 10; 15 20] [0 0 0 0; 1 2 3 4; 0 0 0 0; 5 6 7 8; 0 0 0 0] +

будет производить

[5 10 5 10; 16 22 18 24; 5 10 5 10; 20 26 22 28; 5 10 5 10]

Как правило, входные данные с размерами a× bи c× dдают результат размера max(a,b)× max(c,d).

Соревнование

Реализуйте дополнение для двумерных массивов с модульным вещанием, как определено выше.

Массивы будут прямоугольными (не рваными), будут содержать только неотрицательные целые числа и будут иметь размер как минимум1 в каждом измерении.

Дополнительные правила:

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

В ;качестве разделителя строк используется следующее (как в примерах выше). Каждый тестовый пример показывает два входа и затем выход.

[2 4; 6 8]
[10; 20; 30]
[12 14; 26 28; 32 34]

[5 10; 15 20]
[0 0 0 0; 1 2 3 4; 0 0 0 0; 5 6 7 8; 0 0 0 0]
[5 10 5 10; 16 22 18 24; 5 10 5 10; 20 26 22 28; 5 10 5 10]

[1]
[2]
[3]

[1; 2]
[10]
[11; 12]

[1 2 3 4 5]
[10 20 30]
[11 22 33 14 25]

[9 12 5; 5 4 2]
[4 2; 7 3; 15 6; 4 0; 3 3]
[13 14 9;12 7 9;24 18 20;9 4 6;12 15 8]

[9 12 5; 5 4 2]
[4 2 6 7; 7 3 7 3; 15 6 0 1; 4 0 1 16; 3 3 3 8]
[13 14 11 16; 12 7 9 8; 24 18 5 10; 9 4 3 21; 12 15 8 17]

[6 7 9]
[4 2 5]
[10 9 14]
Луис Мендо
источник
«Реализовать сложение для двумерных массивов» - есть одномерные тестовые случаи.
Джонатан Аллан
Можем ли мы предположить, что мы не получаем входных данных рваных массивов? (похоже на это)
Джонатан Аллан
1
@JonathanAllan Извините, что не ясно. Да, вы можете предположить, что нет рваных массивов. Они будут прямоугольными массивами. «Одномерные» следует рассматривать как двумерные с размером 1× n(например [1 2 3]) или n× 1(например [1; 2; 3])
Луис Мендо
Вещание, которое вы описываете, кажется более ограниченным, чем вещание MATLAB или NumPy; в вашем описании входы должны иметь одинаковое количество измерений, ограничение не присутствует в MATLAB или NumPy. Является ли это ограничением MATL или упрощением для целей задачи (поскольку задача ограничена входом 2D)?
user2357112 поддерживает Monica
@ user2357112 Да, это было упрощение в описании. Вещание MATL такое же, как и в MATLAB: вы можете иметь входы 3 × 2 и 3 × 1 × 5 и получить результат 3 × 2 × 5. На самом деле, 3 × 2 эквивалентно 3 × 2 × 1 (неявные конечные измерения). Я думаю, что это похоже на Numpy (но с ведущими размерами). Я уточнил, что во введении
Луис Мендо

Ответы:

4

Желе , 10 байт

ṁ€ZL$Z€Ɗ⁺S

Принимает матричную пару (два массива строк) в качестве входных данных и возвращает матрицу.

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

Как это работает

ṁ€ZL$Z€Ɗ⁺S  Main link. Argument: [M, N] (matrix pair)

  Z $       Zip M with N (i.e., transpose the matrix of arrays [M, N], ...
   L            then take the length (number of rows) of the result.
ṁ€          Mold M and N like the indices, cyclically repeating their rows as many
            times as needed to reach the length to the right.
     Z€     Zip each; transpose both M and N.
       Ɗ⁺   Combine the three links to the left into a chain and duplicate it.
            The first run enlarges the columns, the second run the rows.
         S  Take the sum of the modified matrices.
Деннис
источник
1
Конечно ... Я вижу все эти языки игры в гольф как несколько совместимые с точки зрения байтов, необходимых для испытания (Jelly, 05AB1E, Pyth, APL и т. Д.). Большинство текущих ответов составляют около 20 байтов, и вот идет Волшебник Деннис вместе ответом наполовину на это ..;) Довольно забавно, когда мемы и истина - это одно и то же: « Никто не превосходит Денниса! .. »
Кевин Круйссен
1
@KevinCruijssen APL не является языком игры в гольф.
Адам
1
@ Адам, я знаю, я знаю. Но он все еще очень короткий (несмотря на то, что был впервые разработан в 1960-х годах). Возможно, я должен был сказать короткие языки вместо языков игры в гольф. Ах, хорошо ..
Кевин Круйссен
5

Древесный уголь , 25 23 байта

AθIE⌈EθLιE⌈EθL§λ⁰ΣE觧νιλ

Попробуйте онлайн! Ссылка на подробную версию кода. Принимает ввод как трехмерный массив. Объяснение:

Aθ

Введите все.

    θ                   Input
   E                    Map over arrays
      ι                 Current array
     L                  Length
  ⌈                     Maximum
 E                      Map over implicit range
          θ             Input
         E              Map over arrays
             λ          Current array
            § ⁰         First element
           L            Length
        ⌈               Maximum
       E                Map over implicit range
                 θ      Input
                E       Map over arrays
                    ν   Current array
                   § ι  Cyclically index using outer loop index
                  §   λ Cyclically index using inner loop index
               Σ        Sum
I                       Cast to string
                        Implicitly print on separate lines and paragraphs
Нил
источник
: P (хотя это длиннее> _>)
только ASCII
5

MATL , 25 24 байта

,iZy]vX>XKx,@GK:KP:3$)]+

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

В заключение! Потребовалась всего неделя, чтобы «Язык месяца» ответил на вопрос « Язык месяца»!

Я предполагаю, что он не настолько короткий, насколько это возможно, но я достаточно счастлив, потому что моя первоначальная версия была более 40 байтов. редактировать: я был прав, Луис нашел еще один байт, чтобы выжать!

,iZy]	# do twice: read input and find the size of each dimension
vX>	# find the maximum along each dimension
XKx	# save this into clipboard K and delete from stack. Stack is now empty.
,	# do twice:
 @G	# push the input at index i where i=0,1.
	# MATL indexes modularly, so 0 corresponds to the second input
 K:	# push the range 1...K[1]
 KP:	# push the range 1...K[2]
 3$)	# use 3-input ) function, which uses modular indexing
	# to expand the rows and columns to the appropriate broadcasted size
]	# end of loop
+	# sum the now appropriately-sized matrices and implicitly display
Giuseppe
источник
ждет, когда Луис Мендо откатит в гольф еще 5 байтов ;-)
Джузеппе
:-D Моя программа для тестовых случаев имела 26 байтов, молодец! Хорошее использование :с векторным вводом
Луис Мендо
4

Python 3 , 127 126 125 байт

golfed байт путем изменения sum(m)вm+n

Еще один байт благодаря Джонатану Фреху

lambda y:[[m+n for n,m,j in Z(l)]for*l,i in Z(y)]
from itertools import*
Z=lambda y:zip(*map(cycle,y),range(max(map(len,y))))

Вводит в виде списка двух 2-мерных массивов.

  • ZЛямбда принимает два массива в качестве входных данных и возвращает итератор получают индекс и слиты значения из обоих массивов, до тех пор , пока индекс не достигнет длины крупнейшего массива. Переменная index бесполезна для меня и стоит мне байты, но я не знаю, как обойтись без нее ... ( связано )
  • Основная лямбда просто принимает входные массивы и вызывает Zвнешние и внутренние массивы. Самые внутренние значения складываются вместе.

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

Использование itertools.cycleнемного похоже на читерство, но я думаю, что я был достаточно наказан по чистой длине оператора импорта :)

Я уверен, что это может быть использовано еще, особенно метод итераций, который оставляет эти бесполезными iи jпеременные. Я был бы благодарен за любые советы о том, как играть в гольф, я, вероятно, упускаю что-то очевидное.

etene
источник
Не могли бы вы поменять zipаргументы, поменять fпонимание и, таким образом, удалить один пробел ( for i,*l-> for*l,i)? ( 125 байт )?
Джонатан Фрех
Еще один байт, спасибо! Я обновлю свой пост.
сентября
3

JavaScript (ES6), 131 байт

Не правильный инструмент для работы, и, вероятно, не правильный подход. Ну да ладно ... ¯ \ _ (ツ) _ / ¯

a=>b=>(g=(a,b,c)=>[...Array((a[b[L='length']]?a:b)[L])].map(c))(a,b,(_,y)=>g(a[0],b[0],(_,x)=>(h=a=>a[y%a[L]][x%a[0][L]])(a)+h(b)))

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

Как?

Вспомогательная функция g () создает массив размером с самый большой входной массив ( a или b ) и вызывает над ним функцию обратного вызова c :

g = (a, b, c) =>
  [...Array(
    (a[b[L = 'length']] ? a : b)[L]
  )].map(c)

Вспомогательная функция h () считывает 2D-массив a at (x, y) с модульной трансляцией:

h = a => a[y % a[L]][x % a[0][L]]

Основной код теперь просто читается как:

a => b =>
  g(a, b, (_, y) =>
    g(a[0], b[0], (_, x) =>
      h(a) + h(b)
    )
  )

Рекурсивная версия, 134 байта

a=>b=>(R=[],g=x=>a[y]||b[y]?a[0][x]+1|b[0][x]+1?g(x+1,(R[y]=R[y]||[])[x]=(h=a=>a[y%a.length][x%a[0].length])(a)+h(b)):g(+!++y):R)(y=0)

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

Arnauld
источник
3

05AB1E , 15 байтов

2FεIζg∍ø]øεø¨}O

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


Старая версия, 25 байт

é`DŠg∍)Σнg}`DŠнgδ∍€˜)ø€øO

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

объяснение

15-byter:

2FεIζg∍ø] øεø¨} O - Полная программа. Принимает ввод как 3D [A, B] список из STDIN.
2F - применить дважды:
  ε - Для каждого в [A, B]:
   Iζ - транспонировать ввод (заполнение пробелов пробелами).
     g - длина (получить количество строк).
      ∍ - Расширить текущий элемент (A или B) до необходимой длины.
       Ш - Транспонирование.
        ] - Закройте все петли.
         Ш - Транспонировать снова.
          ε - Для каждой строки в ^ (столбец результата циклов):
           Ш - Транспонировать колонку.
            Remove} - Удалить последний элемент и закрыть цикл карты.
              О - Сумма

25-byter:

é`DŠg∍) Σнg} `DŠngδ∍ € ˜) ø € øO - Полная программа. Принимает ввод как 3D-список из STDIN.
é - отсортировать список по длине.
 `D - Дамп содержимого отдельно в стек, дублировать ToS.
   Š - выполнить тройной обмен. a, b, c -> c, a, b.
    g - получить длину ToS.
     ∍ - Расширить более короткий список (по высоте) соответственно.
      ) Σ} - обернуть весь стек в список и отсортировать его по:
        нг - длина его первого элемента.
           `DŠ - То же, что и выше.
              нг - длина первого элемента.
                δ∍ € ˜ - соответственно расширить более короткий список (по ширине). 
                    ) ø - обернуть стопку в список и транспонировать (сжать).
                      € ø - тогда застегните каждый список.
                        O - применить векторизованное суммирование.
Мистер Xcoder
источник
3

R , 136 104 103 95 93 байт

Следуя советам Джузеппе, набрал колоссальные 33 35 байтов. Удалось получить менее 100 байт, используя оператор в качестве имени функции. Смотрите историю для более разборчивого кода.

function(x,y,d=pmax(dim(x),dim(y)))y/d[2]/d[1]+x/d[2]/d[1]
"/"=function(x,j)apply(x,1,rep,,j)

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

Jayce
источник
Ницца! Я довел это до 104 байтов, но использовал applyи rep.lenэто то, что я рассмотрел, хотя сам не удосужился его кодировать.
Джузеппе
@ Giuseppe Спасибо! Версия 104 не дает ожидаемого выхода, хотя.
JayCe
1
Тьфу, я продолжаю вводить тебя в заблуждение! этот должен работать
Джузеппе
1
@Giuseppe Люблю использование dim, намного чище и открывает двери для многомерного обобщения с рекурсивными призывами кr
JayCe
Я пытался использовать, outer(x,y,"+")который содержит все правильные суммы, и в четкой схеме. Не могу понять, как извлечь их эффективно.
НГМ
2

05AB1E , 18 байт

éR`UvXNèy‚é`©g∍®+ˆ

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

объяснение

éR                  # sort by length, descending
  `U                # store the shorter list in X
    v               # for each list y, index N in the longer list
     XNè            # get the nth element of the shorter list
        y‚é         # pair with y and sort by length
           `©g∍     # repeat the shorter list to the same length as the longer
               ®+   # elementwise addition of the lists
                 ˆ  # add to global list
                    # implicitly print global list
Emigna
источник
2

Pyth, 24 байта

KeSmlhdQmm+Fm@@bdkQKeSlM

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

объяснение

KeSmlhdQmm+Fm@@bdkQKeSlM
                    eSlMQ  Get the maximum length of (implicit) input...
KeSmlhdQ           K       ... and the maximum row length.
        mm                 For each 2d index ...
          +Fm@@bdkQ        ... get the sum of the appropriate elements.

источник
2

Java 8, 172 байта

A->B->{int m=A.length,o=A[0].length,d=B.length,u=B[0].length,l=m>d?m:d,a=o>u?o:u,r[][]=new int[l][a],$;for(;l-->0;)for($=a;$-->0;)r[l][$]=A[l%m][$%o]+B[l%d][$%u];return r;}

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

Объяснение:

A->B->{                   // Method with integer-matrix as both parameters and return-type
  int m=A.length,         //  Rows of `A`                        (we got an     M)
      o=A[0].length,      //  Columns of `A`                     (we got an     O)
      d=B.length,         //  Rows of `B`                        (we got a      D)
      u=B[0].length,      //  Columns of `B`                     (we got a      U)
      l=m>d?m:d,          //  Maximum of both rows               (we got an     L)
      a=o>u?o:u,          //  Maximum of both columns            (we got an     A)
      r[][]=new int[l][a],//  Result-matrix of size `l` by `a`   (and we got an R)
      $;                  //  Temp integer                       (which $pells? ;P)
  for(;l-->0;)            //  Loop over the rows
    for($=a;$-->0;)       //   Inner loop over the columns
      r[l][$]=            //    Set the current cell in the result-matrix to:
        A[l%m][$%o]       //     The value at {`l` modulo-`m`, `$` modulo-`o`} in `A`
        +B[l%d][$%u];     //     Plus the value at {`l` modulo-`d`, `$` modulo-`u`} in `B`
  return r;}              //  Return the result matrix
Кевин Круйссен
источник
2

Python 2 , 124 116 байт

l=len
A,B=sorted(input(),key=l)
A*=l(B)
for i in eval(`zip(A,B)`):a,b=sorted(i,key=l);a*=l(b);print map(sum,zip(*i))

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

Объяснение:

Принимает список двух двумерных списков в качестве входных данных.

l=len
A,B=sorted(input(),key=l)         # Sort inputed lists by length
A*=l(B)                           # Extend shorter list
for i in eval(`zip(A,B)`):        # Zip and remove copied references
  a,b=sorted(i,key=l)             # Sort lists in each pair (keep references)
  a*=l(b)                         # Extend shorter list
  print map(sum,zip(*i))          # Zip and sum
Мертвый Опоссум
источник
Я взял идеи из обоих наших решений и получил 105 байтов . Я должен был использовать Python 2, хотя, и я получил трюк умножения из вашего кода, так что было бы неправильно обновлять мой ответ :)
etene
1
@etene Вы должны опубликовать это, это хорошее решение!
Мертвый Опоссум
Блин, довольно глупые ошибки с моей стороны, спасибо (еще раз)!
сентября
1
@etene Только что заметил, у этого решения были проблемы с 2 и 6 тестами. Нужно удалить скопированные ссылки
Мертвый опоссум
1
@etene Вернуться к 105 байтам : C
Мертвый опоссум
2

Python 2 , 101 97 105 байт

Редактировать: Спасибо (снова!) Мертвому Опоссуму за сохранение 4 байта

Редактировать 2: потеряно 8 байт, некоторые тесты не проходили

Смесь между более ранним решением Dead Possum (спасибо ему!) И моим собственным решением Python 3 .

lambda y:[map(sum,P(i))for i in P(y)]
def P(y):y=sorted(y,key=len);y[0]*=len(y[1]);return eval(`zip(*y)`)

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

Тот же вход, что и в моем решении Python 3 (пара двумерных списков).

Код комментария:

# Iterate over the nested lists, resized & joined by P(),
# and sum the inner joined items
lambda y:[map(sum,P(i))for i in P(y)]
def P(y):
 y=sorted(y,key=len)  # Sort the two input lists by length
 y[0]*=len(y[1])      # Multiply the smallest one by the biggest one's length
                      # (The smallest list is now the previously largest one)
 return eval(`zip(*y)`)  # Return paired list elements up to the smallest list's length
etene
источник
1

Юлия 0,6 , 85 83 байта

M\N=(((r,c),(s,d))=size.((M,N));repmat(M,s,d)+repmat(N,r,c))[1:max(r,s),1:max(c,d)]

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

(Заменить с \благодаря Джо Кинг )

Работает, повторяя каждую матрицу по горизонтали и вертикали, чтобы они оба имели одинаковый размер (произведение размеров строк на произведение размеров столбцов), суммируя их и извлекая из них правильную область. (Для входных векторов строк или векторных входов столбцов требуется reshapeвызов в виде 2-мерных массивов, что, как я полагаю, нормально, так как в этом вопросе указано «Реализация сложения для двумерных массивов» и «Ввод и вывод могут быть приняты любым разумные средства. Их формат, как обычно, гибкий. ")

sundar - Восстановить Монику
источник