Matriz em ordem "barra"


23

Dados dois números positivos N >= 2e N <= 100crie uma matriz que siga as seguintes regras:

  • O primeiro número começa na posição [0,0]
  • O segundo número começa na posição [0,1]
  • O terceiro número fica abaixo do Primeiro Número (posição [1,0])
  • Os números a seguir seguem na direção "barra"
  • O intervalo de números usado é [1, N1 * N2]. Portanto, os números vão do início 1 ao resultado da multiplicação de ambas as entradas.

Entrada

  • Dois números N >= 2e N <= 100. Primeiro número é a quantidade de linhas, Segundo número, a quantidade de colunas.

Saída

  • Matriz. (Pode ser gerado como um array multidimensional ou uma string com quebras de linha)

Exemplo:

Dados 3 and 5fornecidos:

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

O código mais curto em bytes vence.


2
Podemos usar a indexação 0 para qualquer um dos números?
Jo rei

2
@JoKing No. Deve começar em 1. #
Luis felipe De jesus Munoz


1
@LuisfelipeDejesusMunoz Talvez um termo melhor para a ordem seja "diagonais"? Pessoalmente, eu chamaria isso de "zig-zag", porque me lembra a prova de Zig-Zag de Cantor, mas isso pode ser confuso.
mbomb007

2
@LuisfelipeDejesusMunoz anti-diagonal é o termo para a outra diagonal.
QWR

Respostas:


21

Gelatina , 6 5 bytes

pSÞỤs

Experimente online!

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

Droga. O meu tem mais de 200 bytes. Você pode adicionar alguma explicação pls?
Luis felipe De jesus Munoz

3
Deus, Dennis. Além disso, bom trabalho.
Nit

6
Uau, é muito "intimamente relacionado". É idêntico ao primeiro link na resposta das milhas . Considere votar em ambos. :)
user202729

1
Eu acho que pode ser possível fazer isso, <atom><atom>¥þmas não consigo encontrar a combinação certa. oþ++þestá perto, mas não chega lá
dylnan 24/04

1
@akozi Até agora, tudo bem. Os índices da matriz classificada são [1, 2, 3, 4, 5, 6]. ordena essa matriz, utilizando a chave que mapas 1a [1, 1], 2a [1, 2], 3a [2, 1], etc. Essencialmente, isto encontra o índice de cada par a partir da matriz classificada-por-somas na classificados-lexicograficamente matriz
Dennis


7

R , 101 60 54 bytes

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

Experimente online!

Obrigado a @nwellnhof pela sugestão de rank

Portos Dennis 'Jelly resposta .

Resposta antiga, 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)

Experimente online!

splitestá fazendo a maior parte do trabalho aqui; possivelmente existe um algoritmo de golfe, mas isso definitivamente funciona.

Explicação:

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
}

Experimente online! - você pode usar um printdos lados direito das atribuições <-para ver os resultados intermediários sem alterar o resultado final, pois printretorna sua entrada.


1
Você pode adicionar alguma explicação pls?
Luis felipe De jesus Munoz

1
@LuisfelipeDejesusMunoz adicionou. Se houver algo incerto, informe-me e tentarei esclarecer.
Giuseppe

1
rank(x,1,"f")é 2 bytes menor que order(order(x)).
Nwellnhof 25/04/19

@nwellnhof oh, muito bom, mas usando rank(x,,"l")vai se livrar do tbem.
27418 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 graças a @ OlivierGrégoire .
-4 bytes graças a @ceilingcat .

Experimente online.

Explicação:

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

Percebi que isso leva primeiro as colunas e depois as linhas.
Luis felipe De jesus Munoz

@Luis Eu acho que é convenção de tomar coordenadas como x,y/width,height
Jo rei


5

J , 15 bytes

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

-4 bytes a mais para esta solução por milhas. Obrigado!

Experimente online!

J , 22 19 bytes

-3 bytes graças ao FrownyFrog!

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

Experimente online!

Uma implementação da fantástica solução Jelly de Dennis em J.

Explicação:

Verbo diádico, leva o argumento esquerdo e direito (mfn)

+/&i. cria listas 0..m-1 e 0..n-1 e cria uma tabela de adição para elas:

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

[:>:@/:@/:@, nivela a tabela e classifica a lista duas vezes e adiciona 1 a ela:

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

,$ remodela a lista novamente na tabela mxn:

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

1
-@],\,$para -3 bytes.
precisa

@FrownyFrog - Claro, me sinto estúpido, é tão óbvio agora. Obrigado!
Galen Ivanov

1
15 bytes $1(+/:@;)</.@i.com entrada como uma matriz[r, c]
milha

@miles: Muito legal, obrigado! Eu tentei /., mas could't alcançar o resultado :)
Galen Ivanov

4

APL + WIN, 38 ou 22 bytes

Solicita a coluna de entrada inteira e a linha:

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

ou:

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

com base na dupla aplicação de Dennis de classificação. Perdeu que :(


1
Desculpe a pergunta, mas existe algum lugar em que eu possa testá-la?
Luis felipe De jesus Munoz

@Luis felipe De jesus Munoz Sem problemas. O APL + WIN não está disponível on-line, mas você pode testá-lo no site da Dyalog em tryapl.org se substituir os caracteres with pelos números inteiros de sua escolha.
Graham

4

Wolfram Language (Mathematica) , 73 67 bytes

Contar elementos nas linhas acima: Min[j+k,#2]~Sum~{k,i-1}

Contar elementos na linha atual e abaixo: Max[j-k+i-1,0]~Sum~{k,i,#}

Coloque em uma mesa e adicione 1. Voila:

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

Atualização: percebi que há uma maneira mais curta de contar todas as posições à frente de uma posição normalmente especificada na matriz com apenas uma soma em duas dimensões:

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

Experimente online!

Experimente online!




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

Experimente online!

Definitivamente, essa não é a solução mais curta, mas achei divertido.


from numpy import*e largar os dois n.é um pouco mais curto. Além disso, você pode deixar o espaço em ) for. E mudar para Python 2 permite que você mude return apara print a(no Python 3 seria a mesma contagem de bytes print(a)).
Kevin Cruijssen

Obrigado! Eu deveria ter pensado import*. Eu nunca vou bater resposta Dennis', então eu vou ficar com 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

Experimente online!

Versão Semi-Ungolfed:

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

2

Japonês , 25 24 bytes

Dificilmente elegante, mas faz o trabalho. Trabalhar com dados 2D no Japt é 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.

Eu adicionei a -Qflag no TIO para facilitar a visualização dos resultados, não afeta a solução.
Mordeu um byte graças a Oliver .

Experimente online!


Falando nisso ×, você pode substituir *V por .
25418 Oliver

1
@ Oliver E aqui estava eu, pensando que o atalho é útil, mas não um caso de uso comum. Muito obrigado!
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 a entrada do usuário e retorna a matriz Anse a imprime.

TI-Basic é uma linguagem tokenizada ; todos os tokens usados ​​aqui são de um byte, exceto[A] 2 bytes.

Nota: O TI-Basic (pelo menos na TI-84 Plus CE) suporta apenas matrizes de até 99x99, assim como este programa.

Explicação:

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


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

Experimente online!

Explicação:

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
}

Muito obrigado a Kevin Cruijssen porque não sabia como executar meu código no tio .
Alguns códigos como o cabeçalho e rodapé são roubados dele. -> Sua resposta




1

PHP, 115 bytes

uma abordagem bastante preguiçosa; provavelmente não é o mais curto possível.

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

função anônima, assume largura e altura como parâmetros, retorna matriz 2D

experimente online



1

Anexo , 45 bytes

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

Experimente online!

Lambda anônimo, onde os parâmetros são alternados. Isso pode ser corrigido para +1 byte, acrescentando~ ao programa. A suíte de testes já faz isso.

Explicação

Essa abordagem é semelhante à resposta J e à resposta Jelly .

A primeira ideia é gerar uma tabela de valores:

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

Isso gera uma tabela de adição usando intervalos de ambos os parâmetros de entrada. Para entrada [5, 3], isso fornece:

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

Em seguida, aplainamos isso com Flat!:

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

Usando a abordagem na resposta J, podemos classificar a matriz (ou seja, retornar índices de valores classificados) duas vezes, com 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]

Então, precisamos cortar os valores corretamente, como na resposta da geléia. Podemos cortar todos os _elementos para fazer isso:

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

Então, basta compensar a indexação 0 do Attache com +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

E assim temos o resultado.


1

Python 3 , 259 bytes

Então eu fiz isso de uma maneira estranha. Percebi que havia dois padrões na forma como a matriz se forma.

O primeiro é como o padrão das linhas superiores tem a diferença entre cada termo, aumentando de 1 -> h, onde h é a altura e l é o comprimento. Então eu construo a linha superior com base nesse padrão

Para uma matriz de dim (3,4) dando a, max RoC = 3vamos ver a linha superior do formulário

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

Suponha, em vez disso, que o dim (3,9), dando um max RoC = 3, verá uma linha 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

O segundo padrão é como as linhas mudam uma da outra. Se considerarmos a 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

e subtrair cada linha da linha abaixo (ignorando a linha extra), obtemos

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

Ao ver essa matriz, podemos notar que essa matriz é a sequência em 2 3 4 5 5 4 3 2que, para cada linha, 5 termos desse padrão são deslocados por 1 para cada linha. Veja abaixo o 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|

Portanto, para obter a matriz final, pegamos nossa primeira linha que criamos e produzimos essa linha adicionada com os 5 termos necessários desse padrão.

Esse padrão sempre terá as características do início 2-> max valuee do fim, max value -> 2onde max value = min(h+1, l)o número de vezes que o valor máximo aparecerá é o appearances of max = h + l -2*c -2localc = min(h+1, l) - 2

Então, em todo o meu método de criação de novas linhas parece

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 abaixo. Não acabou sendo curto, mas ainda gosto do 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)

Experimente online!


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.