¿Cómo imprimir el siguiente formato en la menor cantidad de bytes?


20

Este desafío está inspirado en esta pregunta, ahora eliminada.


Tome un entero positivo N como entrada y genere una matriz con los números 1 .. N 2 que sigue el siguiente patrón:

Complete la primera fila con 1 .. N, luego complete la última fila (número de fila N ) con (N + 1) .. 2N , luego complete la segunda fila con (2N + 1) .. 3N y continúe hasta que haya completado todas las filas

El formato de salida es flexible, por lo que se aceptan listas de listas, etc.

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

Aplican reglas estándar. La respuesta más corta en bytes en cada idioma gana. Se alientan las explicaciones como siempre.


¿Se permite que las entradas terminen con un error, siempre que ese error no se imprima en STDOUT?
Sok

@Sí, sí, eso está permitido por defecto.
Martin Ender

1
Supongo que el título está tomado de la pregunta eliminada, pero como no es muy fácil de buscar (para buscar engaños, etc.), ¿puedes cambiarlo por uno mejor?
user202729

1
Dado que "el formato de salida es flexible", ¿puedo generar una matriz unidimensional con los números ordenados de línea a línea? (ej . 1 2 3 7 8 9 4 5 6:) ¿El formato de salida es tan flexible?
Olivier Grégoire

44
La solución APL es probablemente un solo carácter de la antigua cuneiforme persa.
Mark

Respuestas:


7

05AB1E , 13 8 bytes

Guardado 5 bytes gracias a Rod

nLô«āÉÏ

Pruébalo en línea!

Explicación

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

Explicación:

Ponga todos los números en una sola matriz primero, luego corte la matriz omitiendo una línea para cada iteración. Después de las primeras iteraciones (n / 2 + n% 2) no queda nada que omitir, luego obtenga todas las líneas restantes hacia atrás.

Pruébalo en línea!



4

JavaScript, 68 bytes

Editar 3 bytes guardados, estimados por @ user71546

Primero intente, siguiendo la ruta obvia: cuente desde 1 y llene la matriz desde ambos lados, desde el exterior al interior

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

Prueba

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

Pruébalo en línea! La salida es una lista de listas, por ejemplo, (0#) 3rendimientos [[1,2,3],[7,8,9],[4,5,6]].


3

> <> , 51 + 3 = 54 47 bytes

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

Pruébalo en línea!

Se espera una entrada en la parte superior de la pila al inicio del programa utilizando el -vindicador. La salida consiste en números no alineados separados por espacios individuales, y cada línea está separada por una nueva línea. Ejemplo de salida 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 de una nueva línea. El programa termina con un error ( something smells fishy...), pero eso está en STDERR en lugar de STDOUT.

Explicación:

La primera línea simplemente almacena una copia de Nen el registro.

La segunda línea construye el desplazamiento para cada fila de salida restando 1 de N, multiplicándolo N, girándolo al fondo de la pila y luego invirtiendo toda la pila. Cuando el número en la parte superior de la pila llega a 0, la pila debería verse así (el ejemplo usa N=5):

5 15 20 10 0 0

La tercera línea descarta el duplicado 0de la parte superior de la pila.

La cuarta línea incrementa la parte superior de la pila y genera una copia de la misma. Esto se toma mod N, y se usa para decidir si se debe imprimir un espacio o una nueva línea, y si se debe descartar la parte superior de la pila; si se imprime el último número x, entonces x mod N == 0indica que se ha alcanzado el final de esa fila de salida . La ejecución finaliza cuando 1+se ejecuta en una pila vacía, arrojando el error de terminación.

Versión previa

Esto verificó explícitamente una pila vacía para finalizar la ejecución, y también estaba incluyendo 3 bytes para el -vuso del indicador.

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

Pruébalo en línea!


De acuerdo con este meta , ya no agregamos banderas al recuento de bytes, por lo que es suficiente que especifique que se usa la bandera.
Emigna

@Emigna O_O gracias a Dios por eso! Gracias por el aviso
Sok


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

Pruébalo en línea!

Créditos


1
Puede guardar tres bytes cambiando la posición de j++: 102 bytes
Kevin Cruijssen

1
Y otro byte cambiando n-i/2-1a n+~i/2 101 bytes
Kevin Cruijssen

@KevinCruijssen ¡Gracias! De alguna manera publiqué la versión en bruto, no la totalmente completa. Mi error, se abordó el primer problema, pero no el segundo. Pero los escribiste, así que te lo agradezco ;-)
Olivier Grégoire

Nota: si de alguna manera se aceptan matrices unidimensionales,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))

Bueno, se superó antes de que pudiera publicarlo, pero aquí está de todos modos. Editar: Guardado 1 byte gracias a @KevinCruijssen.


n+n-i-1puede ser n+n+~ide -1 byte, por lo que se enfrenta de nuevo con la otra respuesta de JavaScript. :)
Kevin Cruijssen

@KevinCruijssen ¡Gracias geniales!
Neil

2

Jalea , 10 bytes

²ss2Ṛj@/Fs

Pruébalo en línea!

Cómo 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

Ejecútelo y depúrelo en línea

La representación ascii correspondiente del mismo programa tiene 12 caracteres.

JRx/r{]+rFmJ

Así es como 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

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

Pruébalo en línea!


¡Agradable! No sabía que Octave tenía un untilcomando. Y no sabía sobre vec2mat:( Lamentablemente, la misma duración: A=B=vec2mat(1:(n=input(''))*n,n):(
Stewie Griffin

while j++<ntambién tiene exactamente la misma longitud ... ¿Has probado las diferentes opciones o son solo coincidencias?
Stewie Griffin

@StewieGriffin En este caso, el whilebucle tiene la misma longitud, lo intenté en ambos sentidos. Sin embargo, a menudo do ... untiles un byte más corto que while ... end.
Steadybox el

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

Pruébalo en línea!

Completa una matriz alternando entre 2 índices para las filas: un índice que comienza en la parte superior y otro que comienza en la parte inferior. El índice de la fila superior comienza en 0 y se incrementa cada 2 filas; el índice de la fila inferior comienza en n-1 y se reduce cada 2 filas.

Sin golf:

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

C ++ + Rango 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));}

Live on Wandbox

Sin contar las 2 nuevas líneas después using namespace range::view; solo están ahí para separar las importaciones de la lambda.

Hecho levemente interesante: esta solución no realiza asignaciones de montón. Resuelve el problema en el O(1)espacio.


Explicación:

  1. iota(1, n*n+1) -> [1 ... n*n]
  2. chunk(n): todos los nelementos juntos, entonces[1 ... n] [n+1 ... 2*n] ...
  3. Llama eso r
  4. r | stride(2): tome todos los demás elementos: [1 ... n] [2*n+1...] ...
  5. concatenar eso con:
  6. r | reverse | drop(n % 2): reversa, luego elimine el [1 ... n]término si nes impar (habrá un número impar de filas y solo queremos imprimir el primer término una vez). Parece que debería poder hacerlo r | reverse | take, pero eso no funciona por alguna razón.
  7. stride(2)de nuevo, tome todos los demás elementos. Esta vez es al revés.

Más legible y comprobable:

#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 almacenar la entrada, si se mide en complejidad de bits.
user202729

@ user202729 No estoy seguro de lo que quieres decir. ¿Estás diciendo que para un int n, necesito log(n)bits para almacenar la entrada? Pero esa es la entrada de todos modos, y estamos tratando con un intdónde sizeof(int) == 4(la mayoría de los sistemas), por lo que es un número constante de bytes utilizados independientemente de la entrada.
Justin




Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.