Modularer Rundfunk

24

Diese Herausforderung steht im Zusammenhang mit einigen Funktionen der MATL-Sprache im Rahmen des Events Sprache des Monats im Mai 2018 .


Einführung

In MATL arbeiten viele Funktionen mit zwei Eingängen elementweise mit Broadcast . Dies bedeutet Folgendes:

  • Elementweise (oder vektorisiert ): Die Funktion nimmt zwei Arrays mit übereinstimmenden Größen als Eingaben. Die von der Funktion definierte Operation wird auf jedes Paar entsprechender Einträge angewendet. Verwenden Sie beispielsweise die Postfix-Notation:

    [2 4 6] [10 20 30] +
    

    gibt die Ausgabe

    [12 24 36]
    

    Dies funktioniert auch mit mehrdimensionalen Arrays. Die Notation [1 2 3; 4 5 6]repräsentiert das Array 2× 3(Matrix)

    1 2 3
    4 5 6
    

    die Größe 2entlang der ersten Dimension (vertikal) und 3entlang der zweiten Dimension (horizontal) hat. Also zum Beispiel

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

    gibt

    [20 80 180; 120 300 560]
    
  • Broadcasting oder ( Singleton-Erweiterung ): Die beiden Eingabearrays haben keine übereinstimmenden Größen, aber in jeder nicht übereinstimmenden Dimension hat eines der Arrays eine Größe 1. Dieses Array wird implizit entlang der anderen Dimensionen repliziert, damit die Größen übereinstimmen. und dann wird die Operation elementweise wie oben angewendet. Betrachten Sie beispielsweise zwei Eingabearrays mit den Größen 1× 2und 3× 1:

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

    Dank des Rundfunks ist dies gleichbedeutend mit

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

    und so gibt es

    [10 20; 5 10; 2 4]
    

    Ähnlich verhält es sich mit den Größen 3× 2und 3× 1(der Rundfunk wirkt jetzt nur noch in der zweiten Dimension).

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

    gibt

    [19 18; 27 26; 35 34]
    

    Die Anzahl der Dimensionen kann sogar unterschiedlich sein. Beispielsweise sind Eingänge mit den Größen 3 × 2 und 3 × 1 × 5 kompatibel und ergeben ein 3 × 2 × 5-Ergebnis. Tatsächlich ist Größe 3 × 2 dasselbe wie 3 × 2 × 1 (es gibt beliebig viele implizite nachgestellte Singleton-Dimensionen).

    Andererseits würde ein Paar von 2x- 2und 3x- 1Arrays einen Fehler ergeben, da die Größen entlang der ersten Dimension 2und sind 3: Sie sind nicht gleich und keine von ihnen ist 1.

Definition des modularen Rundfunks

Modularer Rundfunk ist eine Verallgemeinerung des Rundfunks, die auch dann funktioniert, wenn keine der nicht übereinstimmenden Größen vorliegt 1. Betrachten Sie zum Beispiel die folgenden 2× 2und 3× 1Arrays als Eingaben der Funktion +:

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

Die Regel lautet wie folgt: Für jede Dimension wird das Array, das entlang dieser Dimension kleiner ist, modular (zyklisch) repliziert , um der Größe des anderen Arrays zu entsprechen. Dies würde das obige Äquivalent zu machen

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

mit dem Ergebnis

[12 14; 26 28; 32 34]

Als zweites Beispiel

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

würde produzieren

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

Im Allgemeinen ergeben Eingaben mit den Größen a× bund c× dein Ergebnis der Größe max(a,b)× max(c,d).

Die Herausforderung

Implementiere Addition für zweidimensionale Arrays mit modularem Broadcasting wie oben definiert.

Die Arrays sind rechteckig (nicht zackig), enthalten nur nicht negative ganze Zahlen und haben mindestens1 in jeder Dimension eine Größe .

Zusätzliche Regeln:

Testfälle

Das Folgende wird ;als Zeilentrennzeichen verwendet (wie in den obigen Beispielen). Jeder Testfall zeigt die beiden Eingänge und dann den Ausgang.

[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]
Luis Mendo
quelle
"Addition für zweidimensionale Arrays implementieren" - es gibt eindimensionale Testfälle.
Jonathan Allan
Dürfen wir davon ausgehen, dass wir keine unregelmäßigen Arrays erhalten? (sieht so aus)
Jonathan Allan
1
@ JonathanAllan Entschuldigung, dass ich nicht klar bin. Ja, Sie können keine unregelmäßigen Arrays annehmen. Sie werden rechteckige Arrays sein. Die "eindimensionalen" sollten als zweidimensional mit der Größe 1× n(wie [1 2 3]) oder n× 1(wie [1; 2; 3]) betrachtet werden
Luis Mendo
Die von Ihnen beschriebene Sendung scheint begrenzter zu sein als MATLAB- oder NumPy-Sendungen. In Ihrer Beschreibung müssen die Eingaben dieselbe Anzahl von Dimensionen haben, eine Einschränkung, die in MATLAB oder NumPy nicht vorhanden ist. Handelt es sich um eine MATL-Einschränkung oder eine Vereinfachung für die Zwecke der Abfrage (da die Abfrage auf 2D-Eingabe beschränkt ist)?
user2357112 unterstützt Monica
@ user2357112 Ja, es war eine Vereinfachung in der Beschreibung. MATL sendet genauso wie MATLAB: Sie können 3 × 2 und 3 × 1 × 5 Eingänge haben und ein 3 × 2 × 5 Ergebnis erhalten. Tatsächlich entspricht 3 × 2 3 × 2 × 1 (implizite nachgestellte Dimensionen). Ich denke, es ist ähnlich in Numpy (aber mit führenden Dimensionen). Ich habe das in der Einleitung klargestellt
Luis Mendo

Antworten:

4

Gelee , 10 Bytes

ṁ€ZL$Z€Ɗ⁺S

Nimmt ein Matrixpaar (zwei Zeilenarrays) als Eingabe und gibt eine Matrix zurück.

Probieren Sie es online!

Wie es funktioniert

ṁ€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.
Dennis
quelle
1
Natürlich ... Ich sehe all diese Golf-Sprachen als einigermaßen kompatibel in Bezug auf die für eine Herausforderung erforderlichen Bytes (Jelly, 05AB1E, Pyth, APL usw.). Die meisten aktuellen Antworten sind ungefähr 20 Bytes, und hier kommt Wizard Dennis mit einer Antwort die Hälfte davon ..;) Ziemlich lustig, wenn Meme und Wahrheit ein und dasselbe sind: " Niemand übertrifft Dennis! .. "
Kevin Cruijssen
1
@ KevinCruijssen APL ist keine Golfsprache.
Adám
1
@Adám Ich weiß, ich weiß. Aber es ist immer noch sehr kurz (obwohl es in den 1960ern zum ersten Mal entwickelt wurde). Vielleicht hätte ich kurze Sprachen sagen sollen, anstatt Golf zu spielen. Ah well ..
Kevin Cruijssen
5

Kohle , 25 23 Bytes

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Nimmt Eingaben als dreidimensionales Array an. Erläuterung:

Aθ

Gib alles ein.

    θ                   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
Neil
quelle
: P (es ist zwar länger> _>)
ASCII
5

MATL , 25 24 Bytes

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

Probieren Sie es online!

Endlich! Es dauerte nur eine Woche, bis die von der Sprache des Monats inspirierte Herausforderung von der Sprache des Monats beantwortet wurde !

Ich vermute, dass es nicht ganz so kurz wie möglich ist, aber ich bin glücklich genug, weil meine ursprüngliche Version über 40 Bytes betrug. edit: Ich hatte recht, Luis hat ein weiteres Byte gefunden, um es herauszudrücken!

,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
quelle
Wartet darauf, dass Luis Mendo 5 weitere Bytes Golf spielt ;-)
Giuseppe,
:-D Mein Programm für die Testfälle hatte 26 Bytes, gut gemacht! Nette Verwendung :mit Vektoreingabe
Luis Mendo
4

Python 3 , 127 126 125 Bytes

hat ein Byte golfen, indem er sum(m)zu geändert hatm+n

Noch ein Byte danke an 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))))

Übernimmt die Eingabe als Liste von zwei zweidimensionalen Arrays.

  • Das ZLambda nimmt zwei Arrays als Eingabe und gibt einen Iterator zurück, der einen Index und zusammengeführte Werte aus beiden Arrays ergibt, bis der Index die Länge des größten Arrays erreicht. Die Indexvariable ist mir nicht sinnvoll und kostet ich Bytes, aber ich weiß nicht , wie ohne es zu tun ... ( bezogen )
  • Das Haupt-Lambda nimmt nur die Eingabearrays und ruft Zdie äußeren und inneren Arrays auf. Die innersten Werte werden addiert.

Probieren Sie es online!

Verwenden itertools.cyclefühlt sich ein bisschen wie Schummeln an, aber ich denke, ich bin genug mit der bloßen Länge der Import-Anweisung bestraft worden :)

Ich bin mir sicher, dass dies noch weiter verbessert werden könnte, insbesondere durch die Iterationsmethode, die diese nutzlosen iund jvariablen Elemente überlässt . Für Tipps zum Golfen wäre ich dankbar, mir fehlt wahrscheinlich etwas Offensichtliches.

Eten
quelle
Könnten Sie die zipArgumente austauschen f, die Zuordnung des Verständnisses umkehren und so ein Leerzeichen entfernen ( for i,*l-> for*l,i)? ( 125 Bytes )?
Jonathan Frech
Noch ein Byte, danke! Ich werde meinen Beitrag aktualisieren.
Etene
3

JavaScript (ES6), 131 Byte

Nicht das richtige Werkzeug für den Job und wahrscheinlich auch nicht der richtige Ansatz. Na ja ... ¯ \ _ (ツ) _ / ¯

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

Probieren Sie es online!

Wie?

Die Hilfsfunktion g () erzeugt ein Array, das so groß ist wie das größte Eingabearray ( a oder b ) und ruft darüber die Rückruffunktion c auf:

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

Die Hilfsfunktion h () liest das 2D-Array a bei (x, y) mit modularem Broadcasting:

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

Der Hauptcode lautet jetzt einfach:

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

Rekursive Version, 134 Bytes

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)

Probieren Sie es online!

Arnauld
quelle
3

05AB1E , 15 Bytes

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

Probieren Sie es online!


Alte Version, 25 Bytes

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

Probieren Sie es online!

Erläuterung

15 Byte:

2FεIζg∍ø] øεø¨} O - Volles Programm. Übernimmt die Eingabe als 3D-Liste [A, B] von STDIN.
2F - Zweimal anwenden:
  ε - Für jedes in [A, B]:
   Iζ - Transponiere die Eingabe (fülle Lücken mit Leerzeichen).
     g - Länge (Anzahl der Zeilen abrufen).
      ∍ - Erweitern Sie das aktuelle Element (A oder B) auf die erforderliche Länge.
       ø - Transponieren.
        ] - Alle Schleifen schließen.
         ø - Wieder transponieren.
          ε - Für jede Zeile in ^ (Spalte des Schleifenergebnisses):
           ø - Vertauschen Sie die Säule.
            ¨} - Entferne das letzte Element und schließe die Map-Schleife.
              O - Summe.

25 Byte:

é`DŠg∍) Σнg} `DŠнgδ∍ € ˜) ø € øO - Volles Programm. Übernimmt die Eingabe als 3D-Liste von STDIN.
é - Liste nach Länge sortieren.
 `D - Dump Inhalt separat auf den Stapel, duplizieren Sie die ToS.
   Š - Führen Sie einen dreifachen Tausch durch. a, b, c -> c, a, b.
    g - Ermitteln Sie die Länge des ToS.
     ∍ - Erweitern Sie die kürzere Liste (in der Höhe) entsprechend.
      ) Σ} - Wickle den gesamten Stapel in eine Liste und sortiere ihn nach:
        íg - Die Länge des ersten Elements.
           `DŠ - Wie oben.
              íg - Die Länge des ersten Elements.
                δ∍ € ˜ - Erweitern Sie die kürzere Liste (in der Breite) entsprechend. 
                    ) ø - Wickeln Sie den Stapel in eine Liste und transponieren Sie ihn (zip).
                      € ø - Dann zip jede Liste.
                        O - Vektorisierte Summation anwenden.
Mr. Xcoder
quelle
3

R , 136 104 103 95 93 Bytes

Golfed nach unten einem satten 33 35 Bytes im Anschluss an Giuseppe Rat ab . Verwaltet, um unter 100 Bytes zu erhalten, indem ein Operator als Funktionsname verwendet wird. Weitere Informationen zu lesbarem Code finden Sie im Verlauf.

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)

Probieren Sie es online!

JayCe
quelle
Nett! Ich habe das auf 104 Bytes heruntergespielt, aber ich habe darüber nachgedacht, applyund rep.lenes zu verwenden, obwohl ich nicht dazu gekommen war, es selbst zu codieren.
Giuseppe
@ Giuseppe Danke! Die 104-Version liefert jedoch nicht die erwartete Ausgabe.
JayCe
1
Ugh, ich führe dich in die Irre! Dieser sollte funktionieren
Giuseppe
1
@ Giuseppe Liebe die Verwendung von dim, viel sauberer und öffnet die Tür zu einer mehrdimensionalen Verallgemeinerung mit rekursiven Aufrufen zur
JayCe
Ich habe versucht zu verwenden, outer(x,y,"+")die alle richtigen Summen enthält, und in einem klaren Muster. Ich kann nicht herausfinden, wie ich sie effizient extrahieren kann.
ngm
2

05AB1E , 18 Bytes

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

Probieren Sie es online!

Erläuterung

é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
quelle
2

Pyth, 24 Bytes

KeSmlhdQmm+Fm@@bdkQKeSlM

Probieren Sie es hier aus

Erläuterung

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.

quelle
2

Java 8, 172 Bytes

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;}

Probieren Sie es online aus.

Erläuterung:

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
Kevin Cruijssen
quelle
2

Python 2 , 124 116 Bytes

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

Probieren Sie es online!

Erläuterung:

Nimmt die Liste von zwei 2D-Listen als Eingabe.

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
Totes Opossum
quelle
Ich nahm Ideen von unseren beiden Lösungen und kam auf 105 Bytes . Ich musste allerdings Python 2 verwenden, und ich habe den Multiplikationstrick aus Ihrem Code erhalten, sodass es nicht richtig erscheint, meine Antwort zu aktualisieren :)
etene
1
@etene Du solltest es posten, es ist eine gute Lösung!
Dead Possum
Verdammt, ziemlich dumme Fehler von meiner Seite, danke (nochmal)!
Etene
1
@etene Gerade bemerkt, diese Lösung hatte Probleme mit 2 und 6 Testfällen. Müssen kopierte Referenzen entfernen
Dead Possum
1
@etene Zurück zu 105 Bytes : C
Dead Possum
2

Python 2 , 101 97 105 Bytes

Edit: Nochmals vielen Dank an Dead Possum für das Speichern von 4 Bytes

Edit 2: 8 Bytes verloren, einige Testfälle wurden nicht bestanden

Eine Mischung aus Dead Possums früherer Lösung (dank ihm!) Und meiner eigenen Python 3-Lösung .

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

Probieren Sie es online!

Gleiche Eingabe wie meine Python 3-Lösung (ein Paar zweidimensionaler Listen).

Kommentierter Code:

# 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
Eten
quelle
1

Julia 0,6 , 85 83 Bytes

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

Probieren Sie es online!

(Ersetzen mit \Dank an Jo King )

Wiederholen Sie jede Matrix horizontal und vertikal, sodass beide dieselbe Größe haben (Produkt der Zeilengrößen x Produkt der Spaltengrößen), addieren Sie diese und extrahieren Sie den richtigen Bereich daraus. (Zeilenvektoreingaben oder Spaltenvektoreingaben erfordern einen reshapeAufruf, der als zweidimensionale Arrays umgewandelt werden soll. Ich gehe davon aus, dass dies in Ordnung ist, da die Frage "Addition für zweidimensionale Arrays implementieren" und "Eingabe und Ausgabe können von jedem übernommen werden." Angibt vernünftige Mittel. Ihr Format ist wie gewohnt flexibel. ")

Sundar - Setzen Sie Monica wieder ein
quelle