Matrix in der Reihenfolge "Schrägstrich"

23

Geben Sie zwei positive Zahlen ein N >= 2und N <= 100erstellen Sie eine Matrix, die den folgenden Regeln folgt:

  • Die erste Nummer beginnt an der Position [0,0]
  • Die zweite Zahl beginnt an der Position [0,1]
  • Dritte Nummer geht unter Erste Nummer (Position [1,0])
  • Die folgenden Zahlen gehen in "Schrägstrich" -Richtung
  • Verwendeter Zahlenbereich ist [1, N1 * N2]. Die Zahlen gehen also von 1 bis zum Ergebnis der Multiplikation beider Eingänge.

Eingang

  • Zwei Zahlen N >= 2und N <= 100. Erste Zahl ist die Anzahl der Zeilen, zweite Zahl die Anzahl der Spalten.

Ausgabe

  • Matrix. (Kann als mehrdimensionales Array oder als Zeichenfolge mit Zeilenumbrüchen ausgegeben werden.)

Beispiel:

Ausgegebene Zahlen 3 and 5:

1   2   4   7   10
3   5   8   11  13
6   9   12  14  15

Gegebene Zahlen 2 and 2

1   2
3   4

Gegebene Zahlen 5 and 5

1   2   4   7   11
3   5   8   12  16
6   9   13  17  20
10  14  18  21  23
15  19  22  24  25

Der kürzeste Code in Bytes gewinnt.

Luis Felipe De Jesus Munoz
quelle
2
Können wir für eine der Zahlen die Indexierung 0 verwenden?
Jo King
2
@JoKing No. Muss um 1 beginnen.
Luis Felipe De Jesus Munoz
5
Sehr eng verwandt .
AdmBorkBork
1
@ LuisfelipeDejesusMunoz Vielleicht ist ein besserer Begriff für die Reihenfolge "Diagonalen"? Persönlich würde ich es ein "Zick-Zack" nennen, weil es mich an Cantors Zick-Zack-Beweis erinnert, aber das könnte verwirrend sein.
mbomb007
2
@ LuisfelipeDejesusMunoz Anti-Diagonale ist der Begriff für die andere Diagonale.
Qwr

Antworten:

21

Gelee , 6 5 Bytes

pSÞỤs

Probieren Sie es online!

Wie es funktioniert

pSÞỤs  Main link. Left argument: n. Right argument: k

p      Take the Cartesian product of [1, ..., n] and [1, ..., k], yielding
       [[1, 1], [1, 2], ..., [n, k-1], [n, k]].
 SÞ    Sort the pairs by their sums.
       Note that index sums are constant on antidiagonals.
   Ụ   Grade up, sorting the indices of the sorted array of pairs by their values.
    s  Split the result into chunks of length k.
Dennis
quelle
Verdammt. Meins ist mehr als 200 Bytes. Können Sie einige Erklärungen hinzufügen?
Luis Felipe De Jesus Munoz
3
Verdammt noch mal, Dennis. Auch gute Arbeit.
Nit
6
Wow, es ist zu "eng verwandt". Das ist identisch mit dem ersten Link in der Antwort von miles . Erwägen Sie, beide zu unterstützen. :)
user202729
1
Ich denke, es könnte möglich sein, dies zu tun, <atom><atom>¥þaber ich kann nicht die richtige Kombination finden. oþ++þist in der Nähe, aber nicht ganz da
dylnan
1
@akozi So weit, so gut. Die Indizes des sortierten Arrays sind [1, 2, 3, 4, 5, 6]. sortiert dieses Array unter Verwendung des Schlüssels, der 1auf [1, 1], 2auf [1, 2], 3auf [2, 1]usw. abgebildet ist. Im Wesentlichen wird der Index jedes Paares aus dem Array "
Dennis,
8

Python 3 , 91 Bytes

def f(n,k):M=[(t//k+t%k,t)for t in range(n*k)];return zip(*k*[map([M,*sorted(M)].index,M)])

Probieren Sie es online!

Dennis
quelle
7

R , 101 60 54 Byte

function(M,N)matrix(rank(outer(1:M,1:N,"+"),,"l"),M,N)

Probieren Sie es online!

Vielen Dank an @nwellnhof für den Vorschlag von rank

Ports Dennis 'Jelly Antwort .

Alte Antwort, 101 Bytes:

function(M,N)matrix(unsplit(lapply(split(1:(M*N),unlist(split(x,x))),rev),x<-outer(1:M,1:N,"+")),M,N)

Probieren Sie es online!

spliterledigt hier den größten Teil der Arbeit; Möglicherweise gibt es einen Golf-Algorithmus, aber das funktioniert definitiv.

Erläuterung:

function(M,N){
x <- outer(1:M,1:N,"+")			# create matrix with distinct indices for the antidiagonals
idx <- split(x,x)			# split into factor groups
items <- split(1:(M*N),unlist(idx))	# now split 1:(M*N) into factor groups using the groupings from idx
items <- lapply(items,rev)		# except that the factor groups are
					# $`2`:1, $`3`:2,3, (etc.) but we need
                                        # $`2`:1, $`3`:3,2, so we reverse each sublist
matrix(unsplit(items,x),M,N)		# now unsplit to rearrange the vector to the right order
					# and construct a matrix, returning the value
}

Probieren Sie es online! - Sie können einen Umbruch printum eine der rechten Seiten der Zuweisungen verwenden <-, um die Zwischenergebnisse anzuzeigen, ohne das Endergebnis zu ändern, da printdie Eingabe zurückgegeben wird.

Giuseppe
quelle
1
Können Sie einige Erklärungen hinzufügen?
Luis Felipe De Jesus Munoz
1
@LuisfelipeDejesusMunoz hinzugefügt. Wenn etwas unklar ist, lass es mich wissen und ich versuche es zu klären.
Giuseppe
1
rank(x,1,"f")ist 2 Bytes kürzer als order(order(x)).
Nwellnhof
@nwellnhof oh, sehr schön, aber mit rank(x,,"l")wird das auch los t.
Giuseppe
6

Java 10, 121 120 109 105 Bytes

m->n->{var R=new int[m][n];for(int i=0,j,v=0;i<m+n;)for(j=++i<n?0:i-n;j<i&j<m;)R[j][i-++j]=++v;return R;}

-11 Bytes dank @ OlivierGrégoire .
-4 Bytes dank @ceilingcat .

Probieren Sie es online aus.

Erläuterung:

m->n->{                // Method with two integer parameters and integer-matrix return-type
  var R=new int[m][n]; //  Result-matrix of size `m` by `n`
  for(int i=0,j,       //  Index integers, starting at 0
          v=0;         //  Count integer, starting at 0
      i<m+n;)          //  Loop as long as `i` is smaller than `m+n`
    for(j=++i<n?0      //   Set `j` to 0 if `i+1` is smaller than `n`
               :i-n;   //   or to the difference between `i` and `n` otherwise
        j<i&j<m;)      //   Inner loop `j` until it's equal to either `i` or `m`,
                       //   so basically check if it's still within bounds:
      R[j][i-++j]=++v; //    Add the current number to cell `j, i-(j+1)`
  return R;}           //  Return the result-matrix
Kevin Cruijssen
quelle
Ich erkannte, dass dies zuerst Spalten und dann Zeilen dauert.
Luis Felipe De Jesus Munoz
@ Luis Ich denke, es ist Konvention, Koordinaten als x,y/width,height
Jo King
2
109 Bytes
Olivier Grégoire
5

J , 15 Bytes

$1(+/:@;)</.@i.

-4 weitere Bytes für diese Lösung um Meilen. Vielen Dank!

Probieren Sie es online!

J , 22 19 Bytes

-3 Bytes dank FrownyFrog!

,$[:>:@/:@/:@,+/&i.

Probieren Sie es online!

Eine Implementierung von Dennis 'fantastischer Jelly-Lösung in J.

Erläuterung:

Dyadisches Verb, nimmt linkes und rechtes Argument (mfn)

+/&i. erstellt Listen 0..m-1 und 0..n-1 und erstellt eine Additionstabelle für diese:

   3 +/&i. 5
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6

[:>:@/:@/:@, Reduziert die Tabelle, bewertet die Liste zweimal und fügt 1 hinzu:

   3 ([:>:@/:@/:@,+/&i.) 5
1 2 4 7 10 3 5 8 11 13 6 9 12 14 15

,$ formt die Liste zurück in die MxN-Tabelle:

   3 (-@],\[:>:@/:@/:@,+/&i.) 5
1 2  4  7 10
3 5  8 11 13
6 9 12 14 15
Galen Ivanov
quelle
1
-@],\,$für −3 Bytes.
FrownyFrog
@FrownyFrog - Natürlich fühle ich mich dumm, es ist jetzt so offensichtlich. Vielen Dank!
Galen Ivanov
1
15 Bytes $1(+/:@;)</.@i.mit Eingabe als Array[r, c]
Meilen
@miles: Sehr cool, danke! Ich habe versucht, /.aber konnte Ihr Ergebnis nicht erreichen :)
Galen Ivanov
4

APL + WIN, 38 oder 22 Bytes

Fordert zur Eingabe einer Ganzzahlspalte und einer Zeile auf:

m[⍋+⌿1+(r,c)⊤m-1]←m←⍳(c←⎕)×r←⎕⋄(r,c)⍴m

oder:

(r,c)⍴⍋⍋,(⍳r←⎕)∘.+⍳c←⎕

basierend auf Dennis 'doppelter Bewertung. Verpasst das :(

Graham
quelle
1
Entschuldigung für die Frage, aber kann ich sie irgendwo testen?
Luis Felipe De Jesus Munoz
@ Luis Felipe De Jesus Munoz Kein Problem. APL + WIN ist nicht online verfügbar, aber Sie können es auf der Dyalog-Website unter tryapl.org testen, wenn Sie die Zeichen ⎕ durch Ganzzahlen Ihrer Wahl ersetzen.
Graham
4

Wolfram Language (Mathematica) , 73 67 Bytes

Zählen Sie die Elemente in den obigen Zeilen: Min[j+k,#2]~Sum~{k,i-1}

Zählen Sie die Elemente in der aktuellen Zeile und darunter: Max[j-k+i-1,0]~Sum~{k,i,#}

In einen Tisch legen und 1. Voila hinzufügen:

1+Table[Min[j+k,#2]~Sum~{k,i-1}+Max[j-k+i-1,0]~Sum~{k,i,#},{i,#},{j,#2}]&

Update: Ich habe festgestellt, dass es einen kürzeren Weg gibt, um alle Positionen vor einer normalerweise festgelegten Position in der Matrix mit nur einer Summe über zwei Dimensionen zu zählen:

Table[1+Sum[Boole[s-i<j-t||s-i==j-t<0],{s,#},{t,#2}],{i,#},{j,#2}]&

Probieren Sie es online!

Probieren Sie es online!

Kelly Lowder
quelle
4

APL (Dyalog Unicode) , 14 12 Bytes

{⍵⍴⍋⍋∊+/↑⍳⍵}

Probieren Sie es online!

-2 danke an ngn , aufgrund seiner geschickten Verwendung von ↑⍳.

Basierend auf Dennis '5-Byte-Jelly-Lösung.

Erik der Outgolfer
quelle
∘.+⌿⍳¨⍵->+/↑⍳⍵
ngn
@ngn Wow, das ist eine clevere Verwendung von kombiniert mit .
Erik der Outgolfer
2

Python 3 , 164 Bytes

from numpy import*
r=range
def h(x,y):
 a,i,k,j=-array([i//y+i%y for i in r(x*y)]),1,2,0
 while j<x+y:a[a==-j],i,k,j=r(i,k),k,k+sum(a==~j),j+1
 a.shape=x,y;return a

Probieren Sie es online!

Dies ist definitiv nicht die kürzeste Lösung, aber ich fand, dass es Spaß gemacht hat.

maxb
quelle
from numpy import*und beide fallen zu lassen n.ist etwas kürzer. Sie können das Leerzeichen auch bei ablegen ) for. Und Python Ändern 2 können Sie ändern , return aum print a(3 in Python wäre es der gleiche Byte-count sein print(a)).
Kevin Cruijssen
Vielen Dank! Ich hätte darüber nachdenken sollen import*. Ich werde Dennis 'Antwort niemals
verraten
2

Python 2 , 93 Bytes

def f(b,a):i=1;o=[];exec"if b:o+=[],;b-=1\nfor l in o:k=len(l)<a;l+=[i]*k;i+=k\n"*a*b;print o

Probieren Sie es online!

Semi-Ungolfed-Version:

def f(b,a):
    i=1
    o=[]
    for _ in range(a*b)
        if b:
            o+=[[]]
            b-=1

        for l in o:
            if len(l)<a:
                l+=[i]
                i+=1
    print o
Stange
quelle
2

Japt , 25 24 Bytes

Kaum elegant, aber erledigt den Job. Das Arbeiten mit 2D-Daten in Japt ist schwierig.

;N×Ç<U©Ap[] A®Ê<V©Zp°T
A

;                      // Set alternative default vars where A is an empty array.
 N×Ç                   // Multiply the inputs and map the range [0..U*V).
    <U                 // If the current item is less than the second input,
      ©Ap[]            // add a new empty subarray into A.
            A®         // Then, for each item in A,
              Ê<V      // if its length is less than the first input,
                 ©Zp°T // Add the next number in the sequence to it.
A                      // Output the results, stored in A.

Ich habe das -QFlag in TIO hinzugefügt, um die Visualisierung der Ergebnisse zu vereinfachen. Es hat keinen Einfluss auf die Lösung.
Dank Oliver ein Byte weggebissen .

Probieren Sie es online!

Nit
quelle
Apropos ×, können Sie ersetzen *V mit .
Oliver
1
@Oliver Und hier war ich und dachte, dass die Verknüpfung praktisch ist, aber kein gewöhnlicher Anwendungsfall. Vielen Dank!
Nit
2

TI-Basic, 76 Bytes

Prompt A,B
{A,B🡒dim([A]
1🡒X
For(E,1,B+A
For(D,1,E
If D≤A and E-D<B
Then
X🡒[A](D,E-D+1
X+1🡒X
End
End
End
[A]

Fordert zur Eingabe durch den Benutzer auf und gibt die Matrix in zurück Ans und druckt sie aus.

TI-Basic ist eine Token-Sprache . Alle hier verwendeten Token sind ein Byte, außer [A]2 Byte.

Hinweis: TI-Basic (zumindest beim TI-84 Plus CE) unterstützt nur Matrizen bis zu 99x99 und dieses Programm auch.

Erläuterung:

Prompt A,B        # 5 bytes, prompt for user input
{A,B🡒dim([A]      # 9 bytes, make the matrix the right size
1🡒X               # 4 bytes, counter variable starts at 1
For(E,1,B+A       # 9 bytes, Diagonal counter, 1 to A+B-1, but we can over-estimate since we have to check later anyway.
For(D,1,E         # 7 bytes, Row counter, 1 to diagonal count
If D≤A and E-D<B  # 10 bytes, Check if we are currently on a valid point in the matrix
Then              # 2 bytes, If so,
X🡒[A](D,E-D+1     # 13 bytes, Store the current number in the current point in the matrix
X+1🡒X             # 6 bytes, Increment counter
End               # 2 bytes, End dimension check if statement
End               # 2 bytes, End row for loop
End               # 2 bytes, End dimension for loop
[A]               # 2 bytes, Implicitly return the matrix in Ans and print it
Pizzapants184
quelle
2

Java (JDK 10) , 142 131 Bytes

X->Y->{var A=new int[X][Y];int E=1;for(int y=0;y<Y+X-1;y++)for(int x=0;x<X;x++){if(y-x<0|y-x>Y-1)continue;A[x][y-x]=E++;}return A;}

Probieren Sie es online!

Erläuterung:

X->Y->{                            // Method with two integer parameters and integer-matrix return-type
    var A=new int[X][Y];           // The Matrix with the size of X and Y
    int E=1;                       // It's a counter
        for(int y=0;y<Y+X-1;y++)   // For each column plus the number of rows minus one so it will run as long as the bottom right corner will be reached
            for(int x=0;x<X;x++){  // For each row
                if(y-x<0|y-x>Y-1)  // If the cell does not exist becouse it's out of range
                    continue;      // Skip this loop cycle
                A[x][y-x]=E++;     // Set the cell to the counter plus 1
            }
    return A;                      // Return the filled Array
}

Ein großes Dankeschön an Kevin Cruijssen, weil ich nicht wusste, wie ich meinen Code auf tio ausführen soll .
Einige Codes wie die Kopf- und Fußzeile werden ihm gestohlen. -> Seine Antwort

Hille
quelle
1
119 Bytes: tio.run/…
Ausführungsform der Ignoranz
1
107 Bytes
Ceilingcat
1

PHP, 115 Bytes

ein ziemlich fauler Ansatz; wahrscheinlich nicht die kürzest mögliche.

function($w,$h){for(;$i++<$h*$w;$r[+$y][+$x]=$i,$x--&&++$y<$h||$x=++$d+$y=0)while($x>=$w|$y<0)$y+=!!$x--;return$r;}

anonyme Funktion, verwendet Breite und Höhe als Parameter, gibt 2D-Matrix zurück

versuche es online

Titus
quelle
1

Attache , 45 Bytes

{Chop[Grade//2<|Flat!Table[`+,1:_2,1:_],_]+1}

Probieren Sie es online!

Anonymes Lambda, bei dem die Parameter gewechselt werden. Dies kann für +1 Byte festgelegt werden, indem Sie ~dem Programm voranstellen . Die Testsuite macht das schon.

Erläuterung

Dieser Ansatz ähnelt der J-Antwort und der Jelly-Antwort .

Die erste Idee ist, eine Wertetabelle zu generieren:

Table[`+,1:_2,1:_]

Dies erzeugt eine Additionstabelle unter Verwendung der Bereiche beider Eingabeparameter. Für die Eingabe [5, 3]gibt dies:

A> Table[`+,1:3,1:5]
 2 3 4 5 6
 3 4 5 6 7
 4 5 6 7 8

Dann reduzieren wir dies mit Flat!:

A> Flat!Table[`+,1:3,1:5]
[2, 3, 4, 5, 6, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8]

Unter Verwendung des Ansatzes in der J-Antwort können wir das Array zweimal bewerten (dh Indizes sortierter Werte zurückgeben), mit Grade//2:

A> Grade//2<|Flat!Table[`+,1:3,1:5]
[0, 1, 3, 6, 9, 2, 4, 7, 10, 12, 5, 8, 11, 13, 14]

Dann müssen wir die Werte richtig aufteilen, wie in der Jelly-Antwort. Wir können alle _Elemente schneiden , um dies zu tun:

A> Chop[Grade//2<|Flat!Table[`+,1:3,1:5],5]
 0 1  3  6  9
 2 4  7 10 12
 5 8 11 13 14

Dann müssen wir nur noch die 0-Indizierung von Attache ausgleichen mit +1:

A> Chop[Grade//2<|Flat!Table[`+,1:3,1:5],5]+1
 1 2  4  7 10
 3 5  8 11 13
 6 9 12 14 15

Und so haben wir das Ergebnis.

Conor O'Brien
quelle
1

Python 3 , 259 Bytes

Also habe ich das auf seltsame Weise gemacht. Mir ist aufgefallen, dass das Array zwei Muster aufweist.

Das erste ist, wie das Muster der oberen Reihen den Unterschied zwischen jedem Term hat, der von 1 -> h zunimmt, wobei h die Höhe und l die Länge ist. Also konstruiere ich die oberste Reihe basierend auf diesem Muster

Für eine Matrix von dim (3,4), die a ergibt, sehen max RoC = 3wir die oberste Zeile des Formulars

1, (1+1), (2+2), (4+3) = 1, 2, 4, 7

Nehmen wir stattdessen an, dass das dim (3,9), das a max RoC = 3ergibt, stattdessen eine obere Reihe von ergibt

`1, (1+1), (2+2), (4+3), (7+3), (10+3), (13+3), (16+3), (19+3) = 1, 2, 4, 7, 10, 13, 16, 19, 22

Das zweite Muster ist, wie sich die Zeilen voneinander ändern. Wenn wir die Matrix betrachten:

1   2   4   7   11
3   5   8   12  16
6   9   13  17  20
10  14  18  21  23
15  19  22  24  25

und subtrahiere jede Zeile von der darunter liegenden Zeile (ignoriere die zusätzliche Zeile), die wir erhalten

2 3 4 5 5
3 4 5 5 4
4 5 5 4 3
5 5 4 3 2

Wenn wir diese Matrix sehen, können wir feststellen, dass diese Matrix die Sequenz ist, 2 3 4 5 5 4 3 2bei der um jede Zeile 5 Terme dieses Musters für jede Zeile um 1 verschoben sind. Siehe unten für visuelle.

         |2 3 4 5 5| 4 3 2
       2 |3 4 5 5 4| 3 2
     2 3 |4 5 5 4 3| 2
   2 3 4 |5 5 4 3 2|

Um die endgültige Matrix zu erhalten, nehmen wir unsere erste Zeile und geben die Zeile aus, die mit den 5 benötigten Begriffen dieses Musters hinzugefügt wurde.

Dieses Muster wird immer die Eigenschaften der Anfang 2-> max valueund das Ende , max value -> 2wo die max value = min(h+1, l)und die Anzahl der Male , dass der maximale Wert angezeigt ist , appearances of max = h + l -2*c -2woc = min(h+1, l) - 2

Insgesamt sieht meine Methode zum Erstellen neuer Zeilen also so aus

1  2  3  7  11 +      |2 3 4 5 5|4 3 2  = 3  5  8  12 16

3  5  8  12 16 +     2|3 4 5 5 4|3 4 2  = 6  9  13 17 20

6  9  13 17 20 +   2 3|4 5 5 4 3|4 2    = 10 14 18 21 23

10 14 18 21 23 + 2 3 4|5 5 4 3 2|       = 15 19 22 24 25

Relevanter Code unten. Es war zwar nicht kurz, aber ich mag die Methode trotzdem.

o,r=len,range
def m(l,h):
 a,t=[1+sum(([0]+[x for x in r(1,h)]+[h]*(l-h))[:x+1]) for x in r(l)],min(l,h+1);s,c=[x for x in r(2,t)],[a[:]]
 for i in r(h-1):
  for j in r(o(a)):
   a[j]+=(s+[t]*(l+h-2*(t-2)-2)+s[::-1])[0+i:l+i][j]
  c+=[a[:]]
 for l in c:print(l)

Probieren Sie es online!

akozi
quelle