Matriz en orden de "barra"

23

Dados dos números positivos N >= 2y N <= 100crear una matriz que sigue las siguientes reglas:

  • El primer número comienza en la posición [0,0]
  • El segundo número comienza en la posición [0,1]
  • El tercer número va debajo del primer número (posición [1,0])
  • Los siguientes números van en dirección de "corte"
  • Rango de números utilizados es [1, N1 * N2]. Entonces, los números van desde el inicio 1 hasta el resultado de la multiplicación de ambas entradas.

Entrada

  • Dos números N >= 2y N <= 100. El primer número es la cantidad de filas, el segundo número es la cantidad de columnas.

Salida

  • Matriz. (Se puede generar como una matriz multidimensional o una cadena con saltos de línea)

Ejemplo:

3 and 5Salida de números dados :

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

Números dados 2 and 2

1   2
3   4

Números dados 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

El código más corto en bytes gana.

Luis felipe De jesus Munoz
fuente
2
¿Podemos usar la indexación 0 para cualquiera de los números?
Jo King el
2
@JoKing No. Debe comenzar a las 1.
Luis felipe De jesus Munoz
1
@LuisfelipeDejesusMunoz ¿Quizás un término mejor para el pedido sea "diagonales"? Personalmente, lo llamaría un "zig-zag", porque me recuerda a la prueba de Zig-Zag de Cantor, pero eso puede ser confuso.
mbomb007
2
@LuisfelipeDejesusMunoz anti-diagonal es el término para la otra diagonal.
qwr

Respuestas:

21

Jalea , 6 5 bytes

pSÞỤs

Pruébalo en línea!

Cómo funciona

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
fuente
Maldita sea. El mío es de más de 200 bytes. ¿Puedes agregar alguna explicación por favor?
Luis felipe De jesus Munoz
3
Maldita sea, Dennis. Además, buen trabajo.
Nit
66
Wow, está demasiado "estrechamente relacionado". Eso es idéntico al primer enlace en la respuesta de millas . Considera votar a ambos. :)
user202729
1
Creo que podría ser posible hacer esto, <atom><atom>¥þpero no puedo encontrar la combinación correcta. oþ++þestá cerca pero no llega allí
dylnan
1
@akozi Hasta ahora, todo bien. Los índices de la matriz ordenada son [1, 2, 3, 4, 5, 6]. clasifica esta matriz, utilizando la clave que se asigna 1a [1, 1], 2a [1, 2], 3a [2, 1], etc. Esencialmente, esto encuentra el índice de cada par de la matriz ordenada por sumas en la matriz ordenado-lexicográficamente
Dennis
7

R , 101 60 54 bytes

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

Pruébalo en línea!

Gracias a @nwellnhof por la sugerencia de rank

Ports Dennis 'Jelly responde .

Respuesta anterior, 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)

Pruébalo en línea!

splitestá haciendo la mayor parte del trabajo aquí; posiblemente haya un algoritmo de golfista pero esto definitivamente funciona.

Explicación:

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
}

Pruébalo en línea! - puede usar una envoltura printalrededor de cualquiera de los lados derechos de las tareas <-para ver los resultados intermedios sin cambiar el resultado final, ya que printdevuelve su entrada.

Giuseppe
fuente
1
¿Puedes agregar alguna explicación por favor?
Luis felipe De jesus Munoz
1
@LuisfelipeDejesusMunoz agregado. Si hay algo que no está claro, avíseme e intentaré aclararlo.
Giuseppe
1
rank(x,1,"f")es 2 bytes más corto que order(order(x)).
nwellnhof
@nwellnhof oh, muy bien, pero el uso también rank(x,,"l")lo eliminará 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 gracias a @ OlivierGrégoire .
-4 bytes gracias a @ceilingcat .

Pruébalo en línea.

Explicación:

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
fuente
Me di cuenta de que esto toma columnas primero y luego filas.
Luis felipe De jesus Munoz
@ Luis Creo que es una convención tomar coordenadas como x,y/width,height
Jo King
2
109 bytes
Olivier Grégoire
5

J , 15 bytes

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

-4 bytes más para esta solución por millas. ¡Gracias!

Pruébalo en línea!

J , 22 19 bytes

-3 bytes gracias a FrownyFrog!

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

Pruébalo en línea!

Una implementación de la fantástica solución Jelly de Dennis en J.

Explicación:

Verbo diádico, toma argumento izquierdo y derecho (mfn)

+/&i. crea listas 0..m-1 y 0..n-1 y crea una tabla de suma para ellos:

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

[:>:@/:@/:@, aplana la tabla y califica la lista dos veces y agrega 1:

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

,$ vuelve a dar forma a la lista en la tabla mxn:

   3 (-@],\[:>:@/:@/:@,+/&i.) 5
1 2  4  7 10
3 5  8 11 13
6 9 12 14 15
Galen Ivanov
fuente
1
-@],\,$para −3 bytes.
FrownyFrog
@FrownyFrog - Por supuesto, me siento estúpido, es tan obvio ahora. ¡Gracias!
Galen Ivanov
1
15 bytes $1(+/:@;)</.@i.con entrada como una matriz[r, c]
millas
@miles: ¡Muy bien, gracias! Lo intenté /.pero no pude lograr tu resultado :)
Galen Ivanov
4

APL + WIN, 38 o 22 bytes

Solicita la columna de entrada de enteros y luego la fila:

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

o:

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

basado en la doble aplicación de Dennis de subir de grado. Te perdiste eso :(

Graham
fuente
1
Perdón por la pregunta, pero ¿hay algún lugar donde pueda probarlo?
Luis felipe De jesus Munoz
@Luis felipe De jesus Munoz No hay problema. APL + WIN no está disponible en línea, pero puede probarlo en el sitio web de Dyalog en tryapl.org si reemplaza los caracteres ⎕ con los enteros de su elección.
Graham
4

Wolfram Language (Mathematica) , 73 67 bytes

Cuente elementos en las filas de arriba: Min[j+k,#2]~Sum~{k,i-1}

Cuente elementos en la fila actual y debajo: Max[j-k+i-1,0]~Sum~{k,i,#}

Poner en una tabla y agregar 1. Voila:

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

Actualización: me di cuenta de que hay una forma más corta de contar todas las posiciones por delante de una posición normalmente especificada en la matriz con solo una suma en dos dimensiones:

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

Pruébalo en línea!

Pruébalo en línea!

Kelly Lowder
fuente
4

APL (Dyalog Unicode) , 14 12 bytes

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

Pruébalo en línea!

-2 gracias a ngn , debido a su uso inteligente de ↑⍳.

Basado en la solución Jelly de 5 bytes de Dennis.

Erik el Outgolfer
fuente
∘.+⌿⍳¨⍵->+/↑⍳⍵
ngn
@ngn Wow, ese es un uso inteligente de combinado con .
Erik the 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

Pruébalo en línea!

Definitivamente esta no es la solución más corta, pero pensé que era divertida.

maxb
fuente
from numpy import*y soltar ambos n.es un poco más corto. Además, puede soltar el espacio en ) for. Y cambiar a Python 2 le permite cambiar return aa print a(en Python 3 sería el mismo número de bytes print(a)).
Kevin Cruijssen
¡Gracias! Debería haberlo pensado import*. Nunca superaré la respuesta de Dennis, así que me quedaré con Python 3.
maxb
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

Pruébalo en línea!

Versión semi-sin golf:

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
Barra
fuente
2

Japt , 25 24 bytes

Apenas elegante, pero hace el trabajo. Trabajar con datos 2D en Japt es complicado.

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

Agregué la -Qbandera en TIO para una visualización más fácil de los resultados, no afecta la solución.
Mordió un byte gracias a Oliver .

Pruébalo en línea!

Liendre
fuente
Hablando de ×eso, puedes reemplazarlo *V con .
Oliver
1
@ Oliver Y aquí estaba, pensando que el atajo es útil, pero no es un caso de uso común. ¡Muchas gracias!
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]

Solicita la entrada del usuario y devuelve la matriz en Ans y la imprime.

TI-Basic es un lenguaje tokenizado ; Todos los tokens utilizados aquí son un byte, [A]que no sea 2 bytes.

Nota: TI-Basic (al menos en TI-84 Plus CE) solo admite matrices de hasta 99x99, y este programa también.

Explicación:

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

Perl 6 , 61 59 bytes

{($!={sort($_ Z=>1..*)>>.{*}})($!([X+] ^<<$_)).rotor(.[1])}

Pruébalo en línea!

Otro puerto de la solución Jelly de Dennis.

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

Pruébalo en línea!

Explicación:

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
}

Muchas gracias a Kevin Cruijssen porque no sabía cómo ejecutar mi código en tio .
Se le roban algunos códigos como el encabezado y el pie de página. -> Su respuesta

Hille
fuente
1
119 bytes: tio.run/…
Encarnación de la ignorancia
1
107 bytes
techo
1

PHP, 115 bytes

un enfoque bastante vago; Probablemente no sea lo más corto posible.

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

función anónima, toma ancho y alto como parámetros, devuelve matriz 2d

pruébalo en línea

Titus
fuente
1

Adjunto , 45 bytes

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

Pruébalo en línea!

Lambda anónima, donde se cambian los parámetros. Esto se puede arreglar para +1 byte, anteponiendo~ al programa. El conjunto de pruebas ya hace esto.

Explicación

Este enfoque es similar a la respuesta J y la respuesta Jelly .

La primera idea es generar una tabla de valores:

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

Esto genera una tabla de suma usando rangos de ambos parámetros de entrada. Para la entrada [5, 3], esto da:

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

Luego, aplanamos esto con Flat!:

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

Usando el enfoque en la respuesta J, podemos calificar la matriz (es decir, devolver índices de valores ordenados) dos veces, con 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]

Entonces, necesitamos cortar los valores correctamente, como en la respuesta de Jelly. Podemos cortar todos los _elementos para hacer esto:

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

Entonces, solo necesitamos compensar la indexación 0 de Attache con +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

Y así tenemos el resultado.

Conor O'Brien
fuente
1

Python 3 , 259 bytes

Así que hice esto de una manera extraña. Noté que había dos patrones en la forma en que se forma la matriz.

El primero es cómo el patrón de las filas superiores tiene la diferencia entre cada término que aumenta de 1 -> h donde h es la altura y l es la longitud. Así que construyo la fila superior en función de ese patrón

Para una matriz de dim (3,4) dando un max RoC = 3Veremos la fila superior del formulario

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

Supongamos, en cambio, que el dim (3,9) que da un max RoC = 3a veremos una fila superior 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

El segundo patrón es cómo cambian las filas entre sí. Si consideramos la matriz:

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

y restamos cada fila de la fila de abajo (ignorando la fila adicional) obtenemos

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

Al ver esta matriz, podemos notar que esta matriz es la secuencia 2 3 4 5 5 4 3 2donde por cada fila hay 5 términos de este patrón desplazados por 1 para cada fila. Ver abajo para visual.

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

Entonces, para obtener la matriz final, tomamos nuestra primera fila que creamos y sacamos esa fila agregada con los 5 términos necesarios de este patrón.

Este patrón siempre tendrá las características de principio 2-> max valuey fin max value -> 2donde max value = min(h+1, l)el número máximo de veces que aparecerá el valor máximo es appearances of max = h + l -2*c -2dondec = min(h+1, l) - 2

Entonces, en general, mi método de crear nuevas filas se ve como

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

Código relevante a continuación. No terminó siendo corto pero todavía me gusta el método.

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)

Pruébalo en línea!

akozi
fuente