Comment imprimer le format ci-dessous dans le moins d'octets?


20

Ce défi est inspiré par cette question désormais supprimée.


Prenez un entier positif N en entrée et sortez une matrice avec les nombres 1 .. N 2 qui suit le modèle ci-dessous:

Remplissez la première ligne avec 1 .. N puis remplissez la dernière ligne (numéro de ligne N ) avec (N + 1) .. 2N , puis remplissez la deuxième ligne avec (2N + 1) .. 3N et continuez jusqu'à ce que vous ayez rempli toutes les lignes.

Le format de sortie est flexible, donc la liste des listes etc. est acceptée.

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

Des règles standard s'appliquent. La réponse la plus courte en octets dans chaque langue l'emporte. Les explications sont encouragées comme toujours.


Les entrées peuvent-elles se terminer par une erreur, tant que cette erreur n'est pas imprimée sur STDOUT?
Sok

@Sok oui, c'est autorisé par défaut.
Martin Ender

1
Je suppose que le titre est tiré de la question supprimée, mais comme il n'est pas très recherchable (à rechercher pour dupe, etc.), pouvez-vous changer pour un meilleur?
user202729

1
Puisque "le format de sortie est flexible", puis-je sortir un tableau unidimensionnel avec les nombres ordonnés d'une ligne à l'autre? (ex 1 2 3 7 8 9 4 5 6:) Le format de sortie est-il si flexible?
Olivier Grégoire

4
La solution APL est probablement un caractère unique de cunéiforme persan ancien.
Mark

Réponses:


7

05AB1E , 13 8 octets

Enregistré 5 octets grâce à Rod

nLô«āÉÏ

Essayez-le en ligne!

Explication

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

Rubis , 53 octets

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

Explication:

Mettez d'abord tous les nombres dans un seul tableau, puis coupez le tableau en sautant une ligne pour chaque itération. Après les premières (n / 2 + n% 2) itérations, il ne reste plus rien à sauter, puis récupérez toutes les lignes restantes.

Essayez-le en ligne!



4

JavaScript, 68 octets

Modifier 3 octets enregistrés, aiguisé par @ user71546

Essayez d'abord, en suivant l'itinéraire évident: comptez à partir de 1 et remplissez le tableau des deux côtés, de l'extérieur vers l'intérieur

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

Tester

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 octets

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

Essayez-le en ligne! La sortie est une liste de listes, par exemple les (0#) 3rendements [[1,2,3],[7,8,9],[4,5,6]].


3

> <> , 51 + 3 = 54 47 octets

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

Essayez-le en ligne!

Une entrée est attendue en haut de la pile au démarrage du programme en utilisant l' -vindicateur. La sortie se compose de nombres non alignés séparés par des espaces simples, et chaque ligne est séparée par une seule nouvelle ligne. Exemple de sortie pour 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

... suivi d'une seule nouvelle ligne. Le programme se termine avec une erreur ( something smells fishy...), mais c'est sur STDERR plutôt que sur STDOUT.

Explication:

La première ligne stocke simplement une copie de Ndans le registre.

La deuxième ligne crée le décalage pour chaque ligne de sortie en soustrayant 1 de N, en multipliant cela par N, en le tournant vers le bas de la pile, puis en inversant la pile entière. Lorsque le nombre en haut de la pile atteint 0, la pile devrait ressembler à ceci (l'exemple utilise N=5):

5 15 20 10 0 0

La troisième ligne supprime le doublon 0du haut de la pile.

La quatrième ligne incrémente le haut de la pile et sort une copie de celle-ci. Ceci est ensuite pris mod N, et il est utilisé pour décider si un espace ou un retour à la ligne doit être imprimé, et si le haut de la pile doit être jeté - si le dernier numéro imprimé est x, x mod N == 0indique alors que la fin de cette ligne de sortie a été atteinte . L'exécution se termine lorsqu'elle 1+est exécutée sur une pile vide, ce qui déclenche l'erreur de terminaison.

La version précédente

Cela a explicitement vérifié la présence d'une pile vide pour terminer l'exécution, et j'incluais également 3 octets pour l' -vutilisation de l' indicateur.

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

Essayez-le en ligne!


Selon cette méta , nous n'ajoutons plus d'indicateurs au nombre d'octets, il suffit donc de spécifier que l'indicateur est utilisé.
Emigna

@Emigna O_O Dieu merci! Merci pour l'avertissement
Sok


2

Java (OpenJDK 9) , 101 octets

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

Essayez-le en ligne!

Crédits


1
Vous pouvez économiser trois octets en modifiant la position de j++: 102 octets
Kevin Cruijssen

1
Et un autre octet passant n-i/2-1à n+~i/2 101 octets
Kevin Cruijssen

@KevinCruijssen Merci! J'ai en quelque sorte posté la version brute, pas celle entièrement jouée. Mon erreur, le premier problème a été abordé, mais pas le second. Mais vous les avez écrites, donc merci à vous ;-)
Olivier Grégoire

Remarque: si les tableaux unidimensionnels sont acceptés,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 octets

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

Eh bien, il a été dépassé avant que je puisse le poster, mais le voici quand même. Edit: 1 octet enregistré grâce à @KevinCruijssen.


n+n-i-1peut être n+n+~ipour -1 octet, alors vous êtes à nouveau en face à face avec l'autre réponse JavaScript. :)
Kevin Cruijssen

@KevinCruijssen Un grand merci!
Neil

2

Gelée , 10 octets

²ss2Ṛj@/Fs

Essayez-le en ligne!

Comment ça fonctionne

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

│æ╘▐⌡r▌═∟Y

Exécutez-le et déboguez-le en ligne

La représentation ascii correspondante du même programme est de 12 caractères.

JRx/r{]+rFmJ

Voici comment ça fonctionne.

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 octets

-4 octets grâce à Neil

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

Essayez-le en ligne!


Je suppose que vous pouvez économiser 4 octets en éliminant la xvariable intermédiaire ?
Neil

1

Octave , 102 octets

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

Essayez-le en ligne!


Agréable! Je ne savais pas Octave avait un untilcommand.And je na pas \ 't sais vec2mat:( Malheureusement , la même longueur: A=B=vec2mat(1:(n=input(''))*n,n):(
Stewie Griffin

while j++<nest également exactement de la même longueur ... Avez-vous essayé les différentes options ou ne s'agit-il que de coïncidences?
Stewie Griffin

@StewieGriffin Dans ce cas, la whileboucle est de la même longueur, je l'ai essayée dans les deux sens. Souvent, cependant, do ... untilest un octet plus court que while ... end.
Steadybox

1

C (gcc) , 110 octets

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

Essayez-le en ligne!

Remplit un tableau en alternant entre 2 indices pour les lignes: un index commençant en haut et un commençant en bas. L'index de la ligne supérieure commence à 0 et est incrémenté toutes les 2 lignes; l'index de la ligne du bas commence à n-1 et est décrémenté toutes les 2 lignes.

Non 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 ++ + Range V3 , 159 octets

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

En direct sur Wandbox

Sans compter les 2 nouvelles lignes après using namespace range::view ; ils sont juste là pour séparer les importations de la lambda.

Fait légèrement intéressant: cette solution ne fait aucune allocation de tas. Il résout le problème dansO(1) espace.


Explication:

  1. iota(1, n*n+1) -> [1 ... n*n]
  2. chunk(n): chaque n éléments ensemble, donc[1 ... n] [n+1 ... 2*n] ...
  3. Appelez ça r
  4. r | stride(2): prenez tous les autres éléments: [1 ... n] [2*n+1...] ...
  5. concaténer cela avec:
  6. r | reverse | drop(n % 2): inverser, puis supprimer le [1 ... n]terme si nest impair (il y aura un nombre impair de lignes et nous ne voulons imprimer le premier terme qu'une seule fois). Il semble que je devrais être capable de fairer | reverse | take , mais cela ne fonctionne pas pour une raison quelconque.
  7. stride(2)encore une fois, prenez tous les autres éléments. Cette fois, c'est à l'envers.

Plus lisible et testable:

#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)) pour stocker l'entrée, si elle est mesurée en complexité binaire.
user202729

@ user202729 Je ne sais pas ce que vous voulez dire. Voulez-vous dire que pour un int n, j'ai besoin de log(n)bits pour stocker l'entrée? Mais c'est l'entrée de toute façon, et nous avons affaire à un intsizeof(int) == 4(la plupart des systèmes), c'est donc un nombre constant d'octets utilisés quelle que soit l'entrée.
Justin




En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.