Matrice par ordre de «barre oblique»

23

Étant donné deux nombres positifs N >= 2et N <= 100créer une matrice qui suit les règles suivantes:

  • Le premier numéro commence à la position [0,0]
  • Le deuxième numéro commence à la position [0,1]
  • Le troisième chiffre descend sous le premier chiffre (position [1,0])
  • Les nombres suivants vont dans le sens d'une "barre oblique"
  • La plage de nombres utilisée est [1, N1 * N2]. Ainsi, les nombres vont du début 1 au résultat de la multiplication des deux entrées.

Contribution

  • Deux chiffres N >= 2et N <= 100. Le premier nombre est le nombre de lignes, le deuxième nombre le nombre de colonnes.

Sortie

  • Matrice. (Peut être sorti comme un tableau multidimensionnel ou une chaîne avec des sauts de ligne)

Exemple:

Nombre de 3 and 5sortie donné :

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

Chiffres donnés 2 and 2

1   2
3   4

Des nombres donnés 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

Le code le plus court en octets gagne.

Luis felipe De jesus Munoz
la source
2
Pouvons-nous utiliser l'indexation 0 pour l'un des nombres?
Jo King le
2
@JoKing No. Doit commencer à 1.
Luis felipe De jesus Munoz
5
Très proche .
AdmBorkBork
1
@LuisfelipeDejesusMunoz Peut-être un meilleur terme pour l'ordre est "diagonales"? Personnellement, je l'appellerais un "zig-zag", car cela me rappelle la preuve Zig-Zag de Cantor, mais cela pourrait prêter à confusion.
mbomb007
2
@LuisfelipeDejesusMunoz anti-diagonal est le terme pour l'autre diagonale.
qwr

Réponses:

21

Gelée , 6 5 octets

pSÞỤs

Essayez-le en ligne!

Comment ça marche

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
la source
Zut. Le mien fait plus de 200 octets. Pouvez-vous ajouter quelques explications pls?
Luis felipe De jesus Munoz
3
Bon sang, Dennis. Aussi, bon travail.
Nit
6
Wow, c'est trop "étroitement lié". C'est identique au premier lien dans la réponse des miles . Envisagez de voter pour les deux. :)
user202729
1
Je pense que cela pourrait être possible avec <atom><atom>¥þmais je ne trouve pas la bonne combinaison. oþ++þest proche mais n'y arrive pas tout à fait
dylnan
1
@akozi Jusqu'ici, tout va bien. Les indices du tableau trié sont [1, 2, 3, 4, 5, 6]. trie ce tableau, en utilisant la clé qui correspond 1à [1, 1], 2à [1, 2], 3à [2, 1], etc. Essentiellement, cela trouve l'index de chaque paire à partir du tableau trié par somme dans le tableau trié lexicographiquement
Dennis
8

Python 3 , 91 octets

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

Essayez-le en ligne!

Dennis
la source
7

R , 101 60 54 octets

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

Essayez-le en ligne!

Merci à @nwellnhof pour la suggestion de rank

Répond Jelly de Ports Dennis .

Ancienne réponse, 101 octets:

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

Essayez-le en ligne!

splitfait la plupart du travail ici; il y a peut-être un algorithme de golfeur, mais cela fonctionne certainement.

Explication:

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
}

Essayez-le en ligne! - vous pouvez utiliser un enroulement printautour de n'importe quel côté droit des affectations <-pour voir les résultats intermédiaires sans changer le résultat final, comme le printrenvoie son entrée.

Giuseppe
la source
1
Pouvez-vous ajouter quelques explications pls?
Luis felipe De jesus Munoz
1
@LuisfelipeDejesusMunoz ajouté. Si quelque chose n'est pas clair, faites-le moi savoir et je vais essayer de clarifier.
Giuseppe
1
rank(x,1,"f")est 2 octets plus court que order(order(x)).
nwellnhof
@nwellnhof oh, très bien, mais en utilisant rank(x,,"l"), vous vous en débarrasserez tégalement.
Giuseppe
6

Java 10, 121 120 109 105 octets

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 octets grâce à @ OlivierGrégoire .
-4 octets grâce à @ceilingcat .

Essayez-le en ligne.

Explication:

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
la source
J'ai réalisé que cela prend d'abord les colonnes, puis les lignes.
Luis felipe De jesus Munoz
@Luis Je pense que c'est la convention de prendre les coordonnées en tant que x,y/width,height
Jo King
2
109 octets
Olivier Grégoire
5

J , 15 octets

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

-4 octets de plus pour cette solution par miles. Merci!

Essayez-le en ligne!

J , 22 19 octets

-3 octets grâce à FrownyFrog!

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

Essayez-le en ligne!

Une implémentation de la fantastique solution Jelly de Dennis en J.

Explication:

Verbe dyadique, prend l'argument gauche et droit (mfn)

+/&i. crée des listes 0..m-1 et 0..n-1 et leur crée un tableau d'addition:

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

[:>:@/:@/:@, aplatit le tableau et note la liste deux fois et y ajoute 1:

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

,$ remodèle la liste dans la table mxn:

   3 (-@],\[:>:@/:@/:@,+/&i.) 5
1 2  4  7 10
3 5  8 11 13
6 9 12 14 15
Galen Ivanov
la source
1
-@],\,$pour −3 octets.
FrownyFrog
@FrownyFrog - Bien sûr, je me sens stupide, c'est tellement évident maintenant. Merci!
Galen Ivanov
1
15 octets $1(+/:@;)</.@i.avec entrée en tant que tableau[r, c]
miles
@miles: Très cool, merci! J'ai essayé /.mais je n'ai pas pu obtenir votre résultat :)
Galen Ivanov
4

APL + WIN, 38 ou 22 octets

Demande la colonne d'entrée entière puis la ligne:

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

ou:

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

basé sur la double application de Dennis de grade up. Manqué que :(

Graham
la source
1
Désolé pour la question, mais y a-t-il un endroit où je peux le tester?
Luis felipe De jesus Munoz
@Luis felipe De jesus Munoz Pas de problème. APL + WIN n'est pas disponible en ligne mais vous pouvez le tester sur le site Dyalog à tryapl.org si vous remplacez les caractères ⎕ par les entiers de votre choix.
Graham
4

Wolfram Language (Mathematica) , 73 67 octets

Comptez les éléments dans les rangées ci-dessus: Min[j+k,#2]~Sum~{k,i-1}

Compter les éléments sur la ligne actuelle et en dessous: Max[j-k+i-1,0]~Sum~{k,i,#}

Mettez dans un tableau et ajoutez 1. Voila:

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

Mise à jour: j'ai réalisé qu'il existe un moyen plus court de compter toutes les positions avant une position normalement spécifiée dans la matrice avec une seule somme sur deux dimensions:

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

Essayez-le en ligne!

Essayez-le en ligne!

Kelly Lowder
la source
4

APL (Dyalog Unicode) , 14 12 octets

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

Essayez-le en ligne!

-2 grâce à ngn , grâce à son utilisation intelligente de ↑⍳.

Basé sur la solution Jelly de 5 octets de Dennis.

Erik le Outgolfer
la source
∘.+⌿⍳¨⍵->+/↑⍳⍵
ngn
@ngn Wow, c'est une utilisation intelligente de combiné avec .
Erik the Outgolfer
2

Python 3 , 164 octets

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

Essayez-le en ligne!

Ce n'est certainement pas la solution la plus courte, mais je pensais que c'était une solution amusante.

maxb
la source
from numpy import*et laisser tomber les deux n.est légèrement plus court. En outre, vous pouvez déposer l'espace à ) for. Et passer à Python 2 vous permet de passer return aà print a(en Python 3, ce serait le même nombre d'octets print(a)).
Kevin Cruijssen
Merci! J'aurais dû y penser import*. Je ne
battrai
2

Python 2 , 93 octets

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

Essayez-le en ligne!

Version semi-non golfée:

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
Barre
la source
2

Japt , 25 24 octets

À peine élégant, mais fait le travail. Travailler avec des données 2D dans Japt est délicat.

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

J'ai ajouté le -Qdrapeau dans TIO pour une visualisation plus facile des résultats, cela n'affecte pas la solution.
Mordu un octet grâce à Oliver .

Essayez-le en ligne!

Lente
la source
En parlant de ×ça, vous pouvez remplacer *V par .
Oliver
1
@Oliver Et j'étais là, pensant que le raccourci est pratique, mais pas un cas d'utilisation courant. Merci beaucoup!
Nit
2

TI-Basic, 76 octets

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]

Demande l'entrée utilisateur, renvoie la matrice Anset l'imprime.

TI-Basic est un langage à jetons ; tous les jetons utilisés ici sont d'un octet, autre que [A]2 octets.

Remarque: TI-Basic (au moins sur la TI-84 Plus CE) ne prend en charge que les matrices jusqu'à 99x99, tout comme ce programme.

Explication:

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
la source
2

Java (JDK 10) , 142 131 octets

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

Essayez-le en ligne!

Explication:

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
}

Un grand merci à Kevin Cruijssen car je ne savais pas comment exécuter mon code sur tio .
Certains codes comme l'en-tête et le pied de page lui sont volés. -> Sa réponse

Hille
la source
1
119 octets: tio.run/…
Incarnation de l'ignorance
1
107 octets
plafondcat
1

PHP, 115 octets

une approche assez paresseuse; probablement pas le plus court possible.

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

fonction anonyme, prend la largeur et la hauteur comme paramètres, retourne la matrice 2d

essayez-le en ligne

Titus
la source
1

Attaché , 45 octets

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

Essayez-le en ligne!

Lambda anonyme, où les paramètres sont commutés. Cela peut être corrigé pour +1 octet, en ajoutant ~au programme. La suite de tests le fait déjà.

Explication

Cette approche est similaire à la réponse J et à la réponse Jelly .

La première idée est de générer une table de valeurs:

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

Cela génère un tableau d'addition utilisant des plages des deux paramètres d'entrée. Pour l'entrée [5, 3], cela donne:

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

Ensuite, nous aplatissons cela avec Flat!:

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

En utilisant l'approche de la réponse J, nous pouvons classer le tableau (c'est-à-dire renvoyer les indices des valeurs triées) deux fois, avec 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]

Ensuite, nous devons hacher les valeurs correctement, comme dans la réponse Jelly. Nous pouvons couper tous les _éléments pour ce faire:

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

Ensuite, il suffit de compenser l'indexation 0 d'Attache avec +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

Et donc nous avons le résultat.

Conor O'Brien
la source
1

Python 3 , 259 octets

J'ai donc fait ça de façon bizarre. J'ai remarqué qu'il y avait deux modèles dans la forme du tableau.

La première est la façon dont le motif des rangées supérieures a la différence entre chaque terme passant de 1 -> h où h est la hauteur et l est la longueur. Je construis donc la rangée du haut en fonction de ce modèle

Pour une matrice de dim (3,4) donnant un max RoC = 3On verra la ligne du haut du formulaire

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

Supposons plutôt que le dim (3,9) donnant un max RoC = 3nous verrons plutôt une rangée supérieure de

`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

Le deuxième modèle est la façon dont les lignes changent les unes des autres. Si nous considérons la matrice:

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

et soustrayez chaque ligne de la ligne ci-dessous (en ignorant la ligne supplémentaire), nous obtenons

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

En voyant cette matrice, nous pouvons remarquer que cette matrice est la séquence 2 3 4 5 5 4 3 2où, par chaque ligne, 5 termes de ce modèle sont décalés de 1 pour chaque ligne. Voir ci-dessous pour le visuel.

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

Donc, pour obtenir la matrice finale, nous prenons notre première ligne que nous avons créée et sortie cette ligne ajoutée avec les 5 termes nécessaires de ce modèle.

Ce modèle aura toujours les caractéristiques de début 2-> max valueet de fin max value -> 2où le max value = min(h+1, l)et le nombre de fois que la valeur maximale apparaîtra est appearances of max = h + l -2*c -2c = min(h+1, l) - 2

Donc, dans l'ensemble, ma méthode de création de nouvelles lignes ressemble

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

Code pertinent ci-dessous. Ça n'a pas été court mais j'aime toujours la méthode.

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)

Essayez-le en ligne!

akozi
la source