Como imprimir o formato abaixo no menor número de bytes?


20

Esse desafio é inspirado nessa pergunta agora excluída.


Pegue um número inteiro positivo N como entrada e produza uma matriz com os números 1 .. N 2 que segue o padrão abaixo:

Preencha a primeira linha com 1 .. N, em seguida, preencha a última linha (número da linha N ) com (N + 1) .. 2N , preencha a segunda linha com (2N + 1) .. 3N e continue até preencher todas as linhas.

O formato de saída é flexível, portanto a lista de listas etc. é aceita.

N = 1
1

N = 2
1  2
3  4

N = 3
1  2  3
7  8  9
4  5  6

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

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

Aplicam-se regras padrão. A resposta mais curta em bytes em cada idioma vence. As explicações são incentivadas como sempre.


As entradas podem terminar com um erro, desde que esse erro não seja impresso em STDOUT?
Sok

@ Ok, sim, isso é permitido por padrão.
Martin Ender

1
Eu acho que o título é retirado da pergunta excluída, mas como não é muito pesquisável (para encontrar o dupe etc.), você pode mudar para um melhor?
user202729

1
Como "o formato de saída é flexível", posso gerar uma matriz unidimensional com os números ordenados de linha para linha? (ex 1 2 3 7 8 9 4 5 6:) O formato de saída é flexível?
Olivier Grégoire

4
A solução APL é provavelmente um único caractere cuneiforme persa antigo.
Mark

Respostas:


7

05AB1E , 13 8 bytes

Economizou 5 bytes graças a Rod

nLô«āÉÏ

Experimente online!

Explicação

n           # push input^2
 L          # push range [1 ... input^2]
  ô         # split into pieces each the size of the input
   «       # append the reverse of this 2D-list
     ā      # push range [1 ... len(list)]
      É     # check each element for oddness
       Ï    # keep only the elements in the 2D list which are true in this list

5

Ruby , 53 bytes

->n{r=*1..n*n;n.times{|x|p r.slice!(r[x*=n]?x:-n,n)}}

Explicação:

Coloque todos os números em uma única matriz primeiro e, em seguida, corte a matriz pulando uma linha para cada iteração. Após as primeiras iterações (n / 2 + n% 2), não há mais nada a ser ignorado e, em seguida, volte todas as linhas restantes.

Experimente online!



4

JavaScript, 68 bytes

Edite 3 bytes salvos, ativado por @ user71546

Primeira tentativa, seguindo a rota óbvia: conte de 1 e preencha o array de ambos os lados, do externo para o interno

n=>(v=0,q=[...Array(n)]).map((_,i)=>q[i&1?--n:i/2]=q.map(_=>++v))&&q

Teste

var F=
n=>(v=0,q=[...Array(n)]).map((_,i)=>q[i&1?--n:i/2]=q.map(_=>++v))&&q

function test() {
  var n=+N.value;
  O.innerHTML = '<tr><td>'
  +F(n).map(r=>r.join('</td><td>')).join('</td></tr><tr><td>')
  +'</td></tr>'
}

test()
#O { margin: 1em }
td { text-align: right }
<input id=N type=number min=1 value=5 oninput='test()'>
<table id=O>



1
@ user71546 now 68
edc65

3

Haskell , 62 bytes

(0#)
m#n|m>=n^2=[]|k<-m+n=[m+1..k]:(k+n)#n++[[k+1..k+n]|k<n^2]

Experimente online! Saída é uma lista de listas, por exemplo, (0#) 3rendimentos [[1,2,3],[7,8,9],[4,5,6]].


3

> <> , 51 + 3 = 54 47 bytes

:&v
?!\1-:&:&*}}r:
 ~\
!~>1+::n&:&%:a84*@@?$~o?

Experimente online!

A entrada é esperada no topo da pilha no início do programa usando o -vsinalizador. A saída consiste em números não alinhados, separados por espaços únicos, e cada linha é separada por uma única nova linha. Exemplo de saída para N=5:

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

... seguido por uma única nova linha. O programa termina com um erro (something smells fishy... ), mas está no STDERR e não no STDOUT.

Explicação:

A primeira linha simplesmente armazena uma cópia do N no registro.

A segunda linha constrói o deslocamento para cada linha de saída subtraindo 1 de N, multiplicando isso N, girando-o para o fundo da pilha e depois revertendo a pilha inteira. Quando o número no topo da pilha chegar a 0, a pilha deverá ficar assim (o exemplo usa N=5):

5 15 20 10 0 0

A terceira linha descarta a duplicata 0 da parte superior da pilha.

A quarta linha incrementa a parte superior da pilha e gera uma cópia dela. Isso é modificado Ne usado para decidir se um espaço ou nova linha deve ser impressa e se a parte superior da pilha deve ser descartada - se o último número impresso for x, x mod N == 0indica que o fim dessa linha de saída foi atingido . A execução termina quando1+ é executada em uma pilha vazia, gerando o erro de finalização.

Versão anterior

Isso checou explicitamente a existência de uma pilha vazia para finalizar a execução, e eu também estava incluindo 3 bytes para o -vuso do sinalizador.

:&v
?!\1-:&:&*}}r:
 ~\
!;>1+::n&:&%:a84*@@?$~o?!~l?

Experimente online!


De acordo com essa meta , não adicionamos mais sinalizadores à contagem de bytes, portanto basta especificar que o sinalizador será usado.
Emigna

@Emigna O_O, graças a Deus por isso! Obrigado pela
atenção


2

Java (OpenJDK 9) , 101 bytes

n->{int x[][]=new int[n][n],i=0,j;for(;i<n;i++)for(j=0;j<n;)x[i%2<1?i/2:n+~i/2][j]=++j+i*n;return x;}

Experimente online!

Créditos


1
Você pode salvar três bytes, alterando a posição do j++: 102 bytes
Kevin Cruijssen

1
E outro byte mudando n-i/2-1para n+~i/2 101 bytes
Kevin Cruijssen

@KevinCruijssen Thanks! De alguma forma, publiquei a versão bruta, não a totalmente adaptada. Meu erro, a primeira questão foi abordada, mas não a segunda. Mas você escreveu-los, para créditos para você ;-)
Olivier Grégoire

Nota: se, de alguma forma, matrizes unidimensionais forem aceitas,n->{int i=n*n,x[]=new int[i],r;for(;i-->0;x[(r%2<1?r/2:n+~r/2)*n+i%n]=i+1)r=i/n;return x;}
Olivier Grégoire

2

JavaScript (ES6), 69 68 bytes

n=>[...Array(n)].map((_,i,a,j=((i*=2)<n?i:n+n+~i)*n)=>a.map(_=>++j))

Bem, foi derrotado antes que eu pudesse publicá-lo, mas aqui está mesmo assim. Edit: Salvo 1 byte graças a @KevinCruijssen.


n+n-i-1pode ser n+n+~ide -1 byte, então você está de igual para igual com a outra resposta JavaScript novamente. :)
Kevin Cruijssen

@KevinCruijssen Brilliant thanks!
Neil

2

Gelatina , 10 bytes

²ss2Ṛj@/Fs

Experimente online!

Como funciona

²ss2Ṛj@/Fs  Main link. Argument: n

²           Square; yield n².
 s          Split; promote n² to [1, ..., n²] and split it into chuks of length n.
  s2        Split 2; generate all non-overlapping pairs of chunks.
            If n is odd, this leaves a singleton array at the end.
    Ṛ       Reverse the order.
     j@/    Reduce by join with reversed arguments.
            In each step, this places the first and second element of the next pair
            at the top and bottom of the accumulator.
        Fs  Flatten and split to restore the matrix shape.

2

Stax , 10 bytes

│æ╘▐⌡r▌═∟Y

Execute e depure on-line

A representação ascii correspondente do mesmo programa é de 12 caracteres.

JRx/r{]+rFmJ

Aqui está como isso funciona.

JR              range [1 .. x^2] where x=input
  x/            split into subarrays of size x
    r           reverse
     {   F      for each subarray, execute block
      ]+r       concat array, and reverse result
          m     for each row, output ...
           J        each subarray joined by spaces



1

Python 2 , 72 68 63 bytes

-4 bytes graças a Neil

def f(n):w=zip(*[iter(range(1,n*n+1))]*n);print(w+w[::-1])[::2]

Experimente online!


Presumo que você pode salvar 4 bytes, eliminando a xvariável intermediária ?
Neil

1

Oitava , 102 bytes

n=input('');A=B=vec2mat(1:n*n,n);i=j=0;do
B(++i,:)=A(++j,:);if++j<n
B(n-i+1,:)=A(j,:);end;until j>=n
B

Experimente online!


Agradável! Eu não sabia que o Octave tinha um untilcomando. E eu não sabia sobre vec2mat:( Infelizmente, o mesmo comprimento: A=B=vec2mat(1:(n=input(''))*n,n):(
Stewie Griffin

while j++<ntambém tem exatamente o mesmo comprimento ... Você já tentou as várias opções ou são apenas coincidências?
Stewie Griffin

@ StewieGriffin Nesse caso, o whileloop tem o mesmo comprimento, tentei nos dois sentidos. Muitas vezes, do ... untilé um byte menor que while ... end, no entanto.
Steadybox 02/02

1

C (gcc) , 110 bytes

i,c,t,b;f(a,n)int*a;{for(b=n-1;i<n*n;t++,b--){for(c=0;c<n;)a[t*n+c++]=++i;for(c=0;c<n&i<n*n;)a[b*n+c++]=++i;}}

Experimente online!

Preenche uma matriz alternando entre 2 índices para linhas: um índice começando na parte superior e outro começando na parte inferior. O índice da linha superior começa em 0 e é incrementado a cada 2 linhas; o índice da linha inferior começa em n-1 e é decrementado a cada 2 linhas.

Ungolfed:

void f(int* a, int n)
{
    //i = value to be written [1,n]; c = column index; t = top row index; b = bottom row index
    for(int i=1, c=0, t=0, b=n-1;
        i <= n*n; //when i = n*n, we have written all the values and we're done
        t++, b--) //t increments every 2 rows, b decrements every 2 rows
    {
        //write out 2 rows per loop

        //first row: fill out row at t
        for(c=0; c<n; c++, i++)
            a[t*n+c]=i;

        //second row: fill out row at b
        //this step will be skipped on the final loop for odd values of n, hence the (i<=n*n) test
        for(c=0; c<n && i<=n*n; c++, i++) 
            a[b*n+c]=i;
    }
}

1

Intervalo C ++ + V3 , 159 bytes

#include<range/v3/all.hpp>
using namespace ranges::view;

[](int n){auto r=iota(1,n*n+1)|chunk(n);return concat(r|stride(2),r|reverse|drop(n%2)|stride(2));}

Ao vivo no Wandbox

Sem contar as duas novas linhas depois using namespace range::view; eles estão lá apenas para separar as importações do lambda.

Fato extremamente interessante: esta solução não faz alocações de heap. Resolve o problema no O(1)espaço.


Explicação:

  1. iota(1, n*n+1) -> [1 ... n*n]
  2. chunk(n): todos os nelementos juntos, então[1 ... n] [n+1 ... 2*n] ...
  3. Chame isso r
  4. r | stride(2): pegue todos os outros elementos: [1 ... n] [2*n+1...] ...
  5. concatenar isso com:
  6. r | reverse | drop(n % 2): reverse, depois solte o [1 ... n]termo se nfor ímpar (haverá um número ímpar de linhas e queremos imprimir o primeiro termo apenas uma vez). Parece que eu deveria ser capaz de fazer r | reverse | take, mas isso não funciona por algum motivo.
  7. stride(2)novamente, pegue todos os outros elementos. Desta vez, é o contrário.

Mais legível e testável:

#include <range/v3/all.hpp>
using namespace ranges::view;

auto f(int n)
{
    auto rows = iota(1, n * n + 1)
        | chunk(n);
    return concat(
        rows | stride(2),
        rows
            | reverse
            | drop(n % 2)
            | stride(2));
}

#include <iostream>
int main(int argc, char** argv)
{
    std::cout << "N = " << argc << '\n';
    auto res = f(argc);

    for (auto const& row : res | bounded) {
        for (auto const& elem : row | bounded) {
            std::cout << elem << ' ';
        }
        std::cout << '\n';
    }
}

O (log (n)) para armazenar a entrada, se medido na complexidade de bits.
User202729 3/0318

@ user202729 Não sabe ao certo o que você quer dizer. Você está dizendo que, para um int n, eu preciso de log(n)bits para armazenar a entrada? Mas essa é a entrada de qualquer maneira, e estamos lidando com um intwhere sizeof(int) == 4(na maioria dos sistemas), por isso é um número constante de bytes usados ​​independentemente da entrada.
Justin




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.