Macierz w kolejności „ukośnik”

23

Biorąc pod uwagę dwie liczby dodatnie N >= 2i N <= 100stwórz macierz zgodnie z następującymi zasadami:

  • Pierwszy numer zaczyna się od pozycji [0,0]
  • Drugi numer zaczyna się od pozycji [0,1]
  • Trzeci numer znajduje się poniżej pierwszego numeru (pozycji [1,0])
  • Kolejne liczby idą w kierunku „ukośnika”
  • Zakres użytych liczb to [1, N1 * N2]. Tak więc liczby zaczynają się od 1 do wyniku pomnożenia obu danych wejściowych.

Wkład

  • Dwie liczby N >= 2i N <= 100. Pierwsza liczba to liczba wierszy, druga liczba to liczba kolumn.

Wydajność

  • Matryca. (Może być wyprowadzany jako tablica wielowymiarowa lub ciąg znaków z podziałem linii)

Przykład:

Podane liczby 3 and 5wyjściowe:

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

Podane liczby 2 and 2

1   2
3   4

Podane liczby 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

Najkrótszy kod w bajtach wygrywa.

Luis Felipe De Jesus Munoz
źródło
2
Czy możemy użyć indeksowania 0 dla dowolnej liczby?
Jo King
2
@JoKing Nie. Musi zaczynać się o 1.
Luis Felipe De Jesus Munoz
5
Bardzo blisko spokrewniony .
AdmBorkBork
1
@LuisfelipeDejesusMunoz Być może lepszym określeniem zamówienia jest „przekątna”? Osobiście nazwałbym to „zygzakiem”, ponieważ przypomina mi dowód Zygzaka Cantora, ale może to być mylące.
mbomb007
2
@LuisfelipeDejesusMunoz anty-przekątna to termin oznaczający drugą przekątną.
qwr

Odpowiedzi:

21

Galaretka , 6 5 bajtów

pSÞỤs

Wypróbuj online!

Jak to działa

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
źródło
Cholerny. Mój ma ponad 200 bajtów. Czy możesz dodać jakieś wyjaśnienie?
Luis felipe De jesus Munoz
3
Cholera jasna, Dennis. Dobra robota.
Nit
6
Wow, to jest zbyt „ściśle powiązane”. To jest identyczne z pierwszym linkiem w odpowiedzi mil . Zastanów się nad poparciem obu. :)
user202729
1
Myślę, że można to zrobić, <atom><atom>¥þale nie mogę znaleźć odpowiedniej kombinacji. oþ++þjest blisko, ale do końca go nie
dotrze
1
@akozi Jak dotąd, tak dobrze. Indeksy posortowanej tablicy to [1, 2, 3, 4, 5, 6]. sortuje tej tablicy, używając przycisku, że mapy 1do [1, 1], 2do [1, 2], 3do [2, 1], itd. Zasadniczo to znaleziska indeks każdej pary z tablicy sortowane-by-sum w sortowane-leksykograficznie tablicę
Dennis
8

Python 3 , 91 bajtów

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

Wypróbuj online!

Dennis
źródło
7

R , 101 60 54 bajtów

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

Wypróbuj online!

Dzięki @nwellnhof za sugestię rank

Galaretka Portsa Dennisa .

Stara odpowiedź, 101 bajtów:

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

Wypróbuj online!

splitwykonuje większość pracy tutaj; być może istnieje algorytm golfisty, ale to na pewno działa.

Wyjaśnienie:

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
}

Wypróbuj online! - możesz użyć zawinięcia printwokół dowolnej z prawej strony przypisań, <-aby zobaczyć wyniki pośrednie bez zmiany wyniku końcowego, ponieważ printzwraca on swoje dane wejściowe.

Giuseppe
źródło
1
Czy możesz dodać jakieś wyjaśnienie?
Luis felipe De jesus Munoz
1
Dodano @LuisfelipeDejesusMunoz. Jeśli coś jest niejasne, daj mi znać, a postaram się wyjaśnić.
Giuseppe,
1
rank(x,1,"f")jest o 2 bajty krótszy niż order(order(x)).
nwellnhof,
@nwellnhof oh, bardzo fajnie, ale korzystanie też rank(x,,"l")się pozbędzie t.
Giuseppe,
6

Java 10, 121 120 109 105 bajtów

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 bajtów dzięki @ OlivierGrégoire .
-4 bajty dzięki @ceilingcat .

Wypróbuj online.

Wyjaśnienie:

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
źródło
Uświadomiłem sobie, że najpierw zajmuje kolumny, a potem wiersze.
Luis felipe De jesus Munoz
@Luis Myślę, że konwencją jest przyjmowanie współrzędnych jako x,y/width,height
Jo King
2
109 bajtów
Olivier Grégoire
5

J , 15 bajtów

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

-4 dodatkowe bajty dla tego rozwiązania o mile. Dzięki!

Wypróbuj online!

J , 22 19 bajtów

-3 bajty dzięki FrownyFrog!

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

Wypróbuj online!

Wdrożenie fantastycznego rozwiązania Dennis Jelly w J.

Wyjaśnienie:

Czasownik dyadyczny, przyjmuje argument lewy i prawy (MFN)

+/&i. tworzy listy 0..m-1 i 0..n-1 i tworzy dla nich tabelę dodatków:

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

[:>:@/:@/:@, spłaszcza tabelę i dwukrotnie ocenia listę i dodaje 1:

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

,$ przekształca listę z powrotem w tabelę mxn:

   3 (-@],\[:>:@/:@/:@,+/&i.) 5
1 2  4  7 10
3 5  8 11 13
6 9 12 14 15
Galen Iwanow
źródło
1
-@],\,$dla −3 bajtów.
FrownyFrog
@FrownyFrog - Oczywiście czuję się głupio, teraz jest tak obsesyjnie. Dziękuję Ci!
Galen Iwanow
1
15 bajtów $1(+/:@;)</.@i.z wejściem jako tablicą[r, c]
mile
@miles: Bardzo fajnie, dzięki! Próbowałem, /.ale nie udało mi się osiągnąć twojego wyniku :)
Galen Iwanow
4

APL + WIN, 38 lub 22 bajtów

Monity o kolumnę wprowadzania liczb całkowitych, a następnie wiersz:

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

lub:

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

na podstawie podwójnego zastosowania oceny Dennisa. Brakowało tego :(

Graham
źródło
1
Przepraszam za pytanie, ale czy mogę go przetestować?
Luis felipe De jesus Munoz
@Luis felipe De jesus Munoz Bez problemu. APL + WIN nie jest dostępny on-line, ale możesz go przetestować na stronie internetowej Dyalog pod adresem tryapl.org, jeśli zamienisz znaki ⎕ na liczby całkowite do wyboru.
Graham
4

Wolfram Language (Mathematica) , 73 67 bajtów

Policz elementy w rzędach powyżej: Min[j+k,#2]~Sum~{k,i-1}

Policz elementy w bieżącym wierszu i poniżej: Max[j-k+i-1,0]~Sum~{k,i,#}

Umieść w tabeli i dodaj 1. Voila:

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

Aktualizacja: Zdałem sobie sprawę, że istnieje krótszy sposób na policzenie wszystkich pozycji przed normalnie określoną pozycją w macierzy za pomocą tylko jednej sumy na dwa wymiary:

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

Wypróbuj online!

Wypróbuj online!

Kelly Lowder
źródło
4

APL (Dyalog Unicode) , 14 12 bajtów

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

Wypróbuj online!

-2 dzięki ngn , ze względu na jego sprytne użycie ↑⍳.

Oparty na 5-bajtowym rozwiązaniu Dennis Jelly.

Erik the Outgolfer
źródło
∘.+⌿⍳¨⍵->+/↑⍳⍵
ngn
@ngn Wow, to sprytne użycie w połączeniu z .
Erik the Outgolfer
2

Python 3 , 164 bajty

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

Wypróbuj online!

To zdecydowanie nie jest najkrótsze rozwiązanie, ale pomyślałem, że to było fajne.

maxb
źródło
from numpy import*i upuszczenie obu n.jest nieco krótsze. Możesz także upuścić miejsce na ) for. A przejście na Python 2 pozwala na zmianęreturn a na print a(w Python 3 będzie to ta sama liczba bajtów print(a)).
Kevin Cruijssen
Dzięki! Powinienem był pomyśleć import*. Nigdy nie pokonam odpowiedzi Dennisa, więc pozostanę przy Pythonie 3.
maks.
2

Python 2 , 93 bajty

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

Wypróbuj online!

Wersja częściowo nie golfowa:

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
Pręt
źródło
2

Japt , 25 24 bajtów

Niezbyt elegancki, ale spełnia swoje zadanie. Praca z danymi 2D w Japt jest trudna.

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

Dodałem -Qflagę w TIO dla łatwiejszej wizualizacji wyników, nie wpływa to na rozwiązanie.
Oderwał jeden bajt dzięki Oliverowi .

Wypróbuj online!

Gnida
źródło
A propos ×, można zastąpić *V z .
Oliver,
1
@Oliver I oto byłem, myśląc, że skrót jest przydatny, ale nie jest częstym przypadkiem użycia. Wielkie dzięki!
Nit
2

TI-Basic, 76 bajtów

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]

Monituje o dane wprowadzone przez użytkownika i zwraca macierz Ans i drukuje ją.

TI-Basic to tokenizowany język ; wszystkie użyte tutaj tokeny mają jeden bajt, inny niż [A]2 bajty.

Uwaga: TI-Basic (przynajmniej w TI-84 Plus CE) obsługuje tylko matryce do 99x99, podobnie jak ten program.

Wyjaśnienie:

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
pizzapanty184
źródło
2

Java (JDK 10) , 142 131 bajtów

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

Wypróbuj online!

Wyjaśnienie:

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
}

Ogromne podziękowania dla Kevina Cruijssena, ponieważ nie wiedziałem, jak uruchomić mój kod na tio .
Niektóre kody, takie jak nagłówek i stopka, zostały mu skradzione. -> Jego odpowiedź

Hille
źródło
1
119 bajtów: tio.run/…
of Ignorance
1
107 bajtów
ceilingcat
1

PHP, 115 bajtów

dość leniwe podejście; prawdopodobnie nie najkrótszy możliwy.

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

funkcja anonimowa, przyjmuje szerokość i wysokość jako parametry, zwraca macierz 2d

spróbuj online

Tytus
źródło
1

JavaScript (Node.js) , 108 105 101 100 bajtów

n=>(l=>{for(r=[];i<n*n;n*~-n/2+2>i?l++:l--*y++)for(T=y,t=l;t--;)r[T]=[...r[T++]||[],++i]})(y=i=0)||r

Wypróbuj online!

DanielIndie
źródło
1

Attache , 45 bajtów

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

Wypróbuj online!

Anonimowa lambda, w której przełączane są parametry. Można to naprawić dla bajtu +1, przygotowując ~się do programu. Zestaw testowy już to robi.

Wyjaśnienie

To podejście jest podobne do odpowiedzi J i odpowiedzi Jelly .

Pierwszym pomysłem jest wygenerowanie tabeli wartości:

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

To generuje tabelę dodatków, wykorzystując zakresy obu parametrów wejściowych. W przypadku danych wejściowych [5, 3]daje to:

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

Następnie spłaszczamy to za pomocą Flat!:

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

Stosując podejście z odpowiedzi J, możemy dwukrotnie ocenić tablicę (to znaczy zwrócić indeksy posortowanych wartości), przy pomocy 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]

Następnie musimy poprawnie pokroić wartości, jak w odpowiedzi Jelly. Możemy wyciąć wszystkie _elementy, aby to zrobić:

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

Następnie musimy tylko zrekompensować indeksowanie 0 Attache za pomocą +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

I tak mamy wynik.

Conor O'Brien
źródło
1

Python 3 , 259 bajtów

Więc zrobiłem to w dziwny sposób. Zauważyłem, że istnieją dwa wzorce w sposobie tworzenia tablicy.

Pierwszy jest to, jak wzór górnych rzędów ma różnicę między każdym terminem, zwiększając się z 1 -> h, gdzie h jest wysokością, a l jest długością. Więc konstruuję górny rząd na podstawie tego wzorca

Dla matrycy dim (3,4) podającej max RoC = 3Widzimy górny wiersz formularza

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

Załóżmy zamiast tego, że dim (3,9) dający max RoC = 3nam zamiast tego zobaczysz górny rząd

`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

Drugi wzór to zmiana rzędów między sobą. Jeśli weźmiemy pod uwagę macierz:

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

i odejmujemy każdy wiersz od wiersza poniżej (ignorując dodatkowy wiersz), który otrzymujemy

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

Po zobaczeniu tej macierzy możemy zauważyć, że ta macierz jest sekwencją, w 2 3 4 5 5 4 3 2której w każdym rzędzie 5 składników tego wzoru jest przesuniętych o 1 dla każdego rzędu. Zobacz poniżej dla wizualnego.

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

Aby uzyskać ostateczną macierz, bierzemy pierwszy utworzony przez nas wiersz i wyprowadzamy ten wiersz z dodanymi 5 potrzebnymi warunkami tego wzorca.

Ten wzór zawsze będzie miał cechy początku 2-> max valuei końca, max value -> 2gdzie max value = min(h+1, l)i ile razy pojawi się maksymalna wartość, appearances of max = h + l -2*c -2gdziec = min(h+1, l) - 2

Tak więc w całości wygląda moja metoda tworzenia nowych wierszy

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

Odpowiedni kod poniżej. Nie było to krótkie, ale nadal podoba mi się ta metoda.

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)

Wypróbuj online!

akozi
źródło