Come stampare il formato seguente nel minor numero di byte?


20

Questa sfida si ispira a questa domanda, ora eliminata.


Prendi un intero positivo N come input e genera una matrice con i numeri 1 .. N 2 che segue il modello seguente:

Riempi la prima riga con 1 .. N quindi riempi l'ultima riga (riga numero N ) con (N + 1) .. 2N , quindi riempi la seconda riga con (2N + 1) .. 3N e continua fino a quando non hai riempito tutte le righe.

Il formato di output è flessibile, quindi sono accettati elenchi di elenchi ecc.

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

Si applicano le regole standard. Vince la risposta più breve in byte in ogni lingua. Le spiegazioni sono incoraggiate come sempre.


Le voci possono terminare con un errore, purché l'errore non venga stampato su STDOUT?
Dal

@Sì sì, è consentito per impostazione predefinita.
Martin Ender

1
Immagino che il titolo sia preso dalla domanda cancellata, ma poiché non è molto ricercabile (da trovare per dupe ecc.), Puoi passare a uno migliore?
user202729

1
Dato che "il formato di output è flessibile", posso generare un array unidimensionale con i numeri ordinati da riga a riga? (es 1 2 3 7 8 9 4 5 6:) Il formato di output è flessibile?
Olivier Grégoire

4
La soluzione APL è probabilmente un singolo personaggio del vecchio cuneiforme persiano.
Marco

Risposte:


7

05AB1E , 13 8 byte

5 byte salvati grazie a Rod

nLô«āÉÏ

Provalo online!

Spiegazione

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

Rubino , 53 byte

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

Spiegazione:

Inserire prima tutti i numeri in un singolo array, quindi suddividere l'array saltando una riga per ogni iterazione. Dopo le prime iterazioni (n / 2 + n% 2) non rimane più nulla da saltare, quindi riportare indietro tutte le righe rimanenti.

Provalo online!



4

JavaScript, 68 byte

Modifica 3 byte salvati, sollecitati da @ user71546

Primo tentativo, seguendo il percorso ovvio: contare da 1 e riempire l'array da entrambi i lati, da esterno a interno

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

Test

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 ora 68
edc65

3

Haskell , 62 byte

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

Provalo online! L'output è un elenco di elenchi, ad esempio i (0#) 3rendimenti [[1,2,3],[7,8,9],[4,5,6]].


3

> <> , 51 + 3 = 54 47 byte

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

Provalo online!

L'ingresso è previsto in cima allo stack all'avvio del programma utilizzando il -vflag. L'output è composto da numeri non allineati separati da spazi singoli e ogni riga è separata da una nuova riga. Esempio di output per 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

... seguito da una sola nuova riga. Il programma termina con un errore ( something smells fishy...), ma è su STDERR piuttosto che su STDOUT.

spiegazione:

La prima riga memorizza semplicemente una copia di Nnel registro.

La seconda riga crea l'offset per ciascuna riga di output sottraendo 1 da N, moltiplicandolo per N, ruotandolo verso il fondo dello stack e quindi invertendo l'intero stack. Quando il numero in cima allo stack raggiunge 0, lo stack dovrebbe apparire in questo modo (esempio utilizzato N=5):

5 15 20 10 0 0

La terza riga scarta il duplicato 0dalla cima dello stack.

La quarta riga incrementa la parte superiore dello stack e ne genera una copia. Questo viene quindi preso mod Ne viene utilizzato per decidere se stampare uno spazio o una nuova riga e se la parte superiore della pila deve essere scartata - se viene stampato l'ultimo numero x, quindi x mod N == 0indica che è stata raggiunta la fine di quella riga di output . L'esecuzione termina quando 1+viene eseguita su uno stack vuoto, generando l'errore di terminazione.

Versione precedente

Ciò ha verificato esplicitamente la presenza di uno stack vuoto per terminare l'esecuzione e includevo anche 3 byte per l' -vutilizzo del flag.

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

Provalo online!


Secondo questo meta , non aggiungiamo più flag al conteggio dei byte, quindi è sufficiente specificare che viene utilizzato il flag.
Emigna

@Emigna O_O meno male per quello! Grazie per il testa a testa
Sok


2

Java (OpenJDK 9) , 101 byte

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

Provalo online!

Titoli di coda


1
È possibile salvare tre byte modificando la posizione di j++: 102 byte
Kevin Cruijssen

1
E un altro byte che cambia n-i/2-1in n+~i/2 101 byte
Kevin Cruijssen il

@KevinCruijssen Grazie! In qualche modo ho pubblicato la versione grezza, non quella completamente giocata a golf. Errore mio, il primo problema è stato affrontato, ma non il secondo. Ma li hai scritti, quindi crediti a te ;-)
Olivier Grégoire

Nota: se in qualche modo vengono accettate matrici unidimensionali,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 byte

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

Beh, è ​​stato superato prima che potessi pubblicarlo, ma eccolo qui. Modifica: salvato 1 byte grazie a @KevinCruijssen.


n+n-i-1può essere n+n+~iper -1 byte, quindi sei di nuovo in punta di piedi con l'altra risposta JavaScript. :)
Kevin Cruijssen

@KevinCruijssen Grazie brillante!
Neil

2

Gelatina , 10 byte

²ss2Ṛj@/Fs

Provalo online!

Come funziona

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

│æ╘▐⌡r▌═∟Y

Esegui ed esegui il debug online

La corrispondente rappresentazione ASCII dello stesso programma è di 12 caratteri.

JRx/r{]+rFmJ

Ecco come funziona.

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


2

R , 70 59 47 byte

function(n)matrix(1:n^2,n,,T)[c(1:n,n:1)*!0:1,]

Provalo online!

Grazie a Robin Ryder per un golf a 4 byte, che ho poi golfato ulteriormente.

Restituisce una matrice; costruisce la matrixsequenza, ad es. [[1 2 3] [4 5 6] [7 8 9]], quindi riordina le righe.


66 byte evitando rbind.
Robin Ryder

@RobinRyder 59 byte - sul cellulare, quindi lo modificherò più avanti
Giuseppe

1

Python 2 , 72 68 63 byte

-4 byte grazie a Neil

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

Provalo online!


Presumo che tu possa salvare 4 byte eliminando la xvariabile intermedia ?
Neil

1

Ottava , 102 byte

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

Provalo online!


Bello! Non sapevo che Octave avesse un untilcomando e non sapevo di vec2mat:( Purtroppo la stessa lunghezza: A=B=vec2mat(1:(n=input(''))*n,n):(
Stewie Griffin

while j++<nè anche esattamente della stessa lunghezza ... Hai provato le varie opzioni o sono solo coincidenze?
Stewie Griffin,

@StewieGriffin In questo caso il whileloop ha la stessa lunghezza, l'ho provato in entrambi i modi. Spesso però do ... untilè un byte più breve di while ... end, però.
Steadybox

1

C (gcc) , 110 byte

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

Provalo online!

Compila un array alternando 2 indici per righe: un indice che inizia nella parte superiore e uno che inizia nella parte inferiore. L'indice della riga superiore inizia da 0 e viene incrementato ogni 2 righe; l'indice della riga inferiore inizia da n-1 e viene decrementato ogni 2 righe.

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

C ++ + Range V3 , 159 byte

#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 su Wandbox

Non contando le 2 nuove righe dopo using namespace range::view; sono lì solo per separare le importazioni dalla lambda.

Fatto leggermente interessante: questa soluzione non prevede allocazioni di heap. Risolve il problema nello O(1)spazio.


Spiegazione:

  1. iota(1, n*n+1) -> [1 ... n*n]
  2. chunk(n): tutti gli nelementi insieme, quindi[1 ... n] [n+1 ... 2*n] ...
  3. Chiamalo così r
  4. r | stride(2): prendi ogni altro elemento: [1 ... n] [2*n+1...] ...
  5. concatenalo con:
  6. r | reverse | drop(n % 2): inverti, quindi rilascia il [1 ... n]termine se nè dispari (ci sarà un numero dispari di righe e vogliamo stampare il primo termine una sola volta). Sembra che dovrei essere in grado di farlo r | reverse | take, ma non funziona per qualche motivo.
  7. stride(2)di nuovo, prendi ogni altro elemento. Questa volta è al contrario.

Più leggibile e testabile:

#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)) per la memorizzazione dell'ingresso, se misurato in complessità bit.
user202729

@ user202729 Non so cosa intendi. Stai dicendo che per un int n, ho bisogno di log(n)bit per memorizzare l'input? Ma è comunque l'input e abbiamo a che fare con un intdove sizeof(int) == 4(la maggior parte dei sistemi), quindi è un numero costante di byte utilizzati indipendentemente dall'input.
Justin



0

C (gcc) 80 78

Vedo ora che questa soluzione è sbagliata

i;f(n){for(i=0;i++<n*n;printf("\n%3d"+!!(~-i%n),i>n?n+(i+n>n*n?i%n?:n:i):i));}

Provalo online!


0

C (gcc) , 36 + 8 + 61 = 105 byte

compilare con -Dp=printf("%d ",i),i++%n;);puts("") -Dq=i,n)

f(q{g(1,i);}g(q{for(;p;i<n*n&&h(q;}h(q{for(n+i<n*n&&g(n+q;p;}

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.