Модульне мовлення


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 чи спрощення для цілей виклику (оскільки виклик обмежений двовимірним введенням)?
user2357112 підтримує Моніку

@ 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
@ Adám Я знаю, я знаю. Але вона все ще дуже коротка (незважаючи на те, що вона була вперше розроблена в 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

чекає, коли Луїс Мендо відправиться на гольф ще на 5 байт ;-)
Джузеппе

:-D Моя програма для тестових випадків мала 26 байтів, молодець! Хороше використання :з векторним введенням
Луїс Мендо

4

Пітон 3 , 127 126 125 байт

гольф на байті, змінивши sum(m)наm+n

Ще один байт завдяки @Jonathan Frech

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

Вводиться в якості списку двох двовимірних масивів.

  • ZЛямбда приймає два масиви в якості вхідних даних і повертає ітератор отримують індекс і злиті значення з обох масивів, до тих пір , поки індекс не досягне довжини найбільшого масиву. Змінна індексу для мене не корисна і коштує мені байтів, але я не знаю, як без неї ... ( пов'язано )
  • Основна лямбда просто приймає вхідні масиви та викликає Zзовнішній та внутрішній масиви. Найпотаємніші значення додаються разом.

Спробуйте в Інтернеті!

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

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


Чи можете ви поміняти місцями свої zipаргументи, змінити fзавдання для розуміння і таким чином видалити один пробіл ( for i,*l-> for*l,i)? ( 125 байт )?
Джонатан Фрех

Ще один байт, дякую! Я оновлю свою посаду.
etene

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 в (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)

Спробуйте в Інтернеті!


3

05AB1E , 15 байт

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

Спробуйте в Інтернеті!


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

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

Спробуйте в Інтернеті!

Пояснення

15-байт:

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

25 байт:

é`DŠg∍) Σng} `DŠngδ∍ € ˜) ø € øO - Повна програма. Приймає дані як тривимірний список від STDIN.
é - Сортування списку за довжиною.
 `D - скидайте вміст окремо на стек, дублюйте ToS.
   Š - Зробіть потрійний своп. a, b, c -> c, a, b.
    g - Отримайте довжину ToS.
     ∍ - Розширити відповідно коротший список (по висоті).
      ) Σ} - загортайте весь стек до списку та сортуйте його за:
        ng - довжина першого пункту.
           `DŠ - Те саме, що вище.
              ng - Довжина першого елемента.
                δ∍ € ˜ - відповідно розширте коротший список (по ширині). 
                    ) ø - Загорніть стек у список і перемістіть (zip) його.
                      € ø - Потім поштовуйте кожен список.
                        O - Застосувати векторизовану сумування.

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)

Спробуйте в Інтернеті!


Приємно! Я гольфував це до 104 байтів, але використовую, applyі rep.lenце те, що я вважав, хоча сам не мав можливості кодувати це.
Джузеппе

@Giuseppe Дякую! 104 версія не дає очікуваного результату.
JayCe

1
Тьфу, я продовжую вас обманювати! це має спрацювати
Джузеппе

1
@Giuseppe Любить використання dim, набагато чистіше і відкриває двері для багатовимірного узагальнення з рекурсивними дзвінками доr
JayCe

Я намагався використовувати, outer(x,y,"+")який містить усі потрібні суми, і чітко. Неможливо зрозуміти, як їх ефективно витягти.
ngm


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

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 тестовими випадками. Потрібно видалити скопійовані посилання
Dead Possum

1
@etene Повернутися до 105 байт : C
Dead Possum

2

Python 2 , 101 97 105 байт

Редагувати: Спасибі (знову!) Dead Possum за збереження 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

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

Спробуйте в Інтернеті!

(Замінити з \завдяки Джо Кінг )

Працює, повторюючи кожну матрицю по горизонталі та вертикалі, так що обидва вони мають однаковий розмір (добуток розмірів рядків x добуток розмірів стовпців), додаючи ці вгору та витягуючи з цього правильну область. (Вхідні векторні ряди або вхідні векторні стовпці потребують reshapeвиклику, щоб передати його як двовимірні масиви. Я вважаю, що це нормально, оскільки в питанні вказано "Додавання впровадження для двовимірних масивів" та "Введення та вихід можна приймати будь-якими розумні засоби. Їх формат є гнучким, як зазвичай. ")

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.