20
\$\begingroup\$

This challenge is inspired by this, now deleted question.


Take a positive integer N as input, and output a matrix with the numbers 1 .. N2 that follows the pattern below:

Fill in the first row with 1 .. N then fill the last row (row number N) with (N+1) .. 2N, then fill the second row with (2N+1) .. 3N and continue until you have filled all rows.

The output format is flexible, so list of lists etc. are accepted.

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

Standard rules apply. Shortest answer in bytes in each language wins. Explanations are encouraged as always.

\$\endgroup\$
  • \$\begingroup\$ Are entries allowed to terminate with an error, as long as that error is not printed to STDOUT? \$\endgroup\$ – Sok Mar 1 '18 at 10:14
  • \$\begingroup\$ @Sok yes, that's allowed by default. \$\endgroup\$ – Martin Ender Mar 1 '18 at 10:17
  • 1
    \$\begingroup\$ I guess the title is taken from the deleted question, but as it's not very searchable (to find for dupe etc.), can you change to a better one? \$\endgroup\$ – user202729 Mar 1 '18 at 11:59
  • 1
    \$\begingroup\$ Since "the output format is flexible", may I output a one-dimensional array with the numbers ordered from line to line? (ex: 1 2 3 7 8 9 4 5 6) Is the output format that flexible? \$\endgroup\$ – Olivier Grégoire Mar 1 '18 at 13:12
  • 4
    \$\begingroup\$ The APL solution is probably a single character of Old Persian cuneiform. \$\endgroup\$ – Mark Mar 2 '18 at 2:38

21 Answers 21

7
\$\begingroup\$

05AB1E, 13 8 bytes

Saved 5 bytes thanks to Rod

nLô«āÉÏ

Try it online!

Explanation

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
\$\endgroup\$
5
\$\begingroup\$

Ruby, 53 bytes

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

Explanation:

Put all the numbers into a single array first, then slice the array skipping a line for each iteration. After the first (n/2+n%2) iterations there is nothing left to skip, then get all the remaining lines backwards.

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Python 2, 75 bytes

def f(n):a=range(n);print[[i*n-~j for j in a]for i in a[::2]+a[~(n%2)::-2]]

Try it online!

\$\endgroup\$
4
\$\begingroup\$

JavaScript, 68 bytes

Edit 3 bytes saved, whetted by @user71546

First try, following the obvious route: count from 1 and fill the array from both sides, from outer to inner

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>

\$\endgroup\$
  • 3
    \$\begingroup\$ 70 bytes ;) \$\endgroup\$ – Shieru Asakoto Mar 1 '18 at 8:24
  • 1
    \$\begingroup\$ @user71546 now 68 \$\endgroup\$ – edc65 Mar 1 '18 at 9:43
3
\$\begingroup\$

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]

Try it online! Output is a list of lists, e.g. (0#) 3 yields [[1,2,3],[7,8,9],[4,5,6]].

\$\endgroup\$
3
\$\begingroup\$

><>, 51+3=54 47 bytes

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

Try it online!

Input is expected on top of the stack at program start using the -v flag. Output consists of non-aligned numbers separated by single spaces, and each line is separated by a single newline. Example output for 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

... followed by a single newline. Program terminates with an error (something smells fishy...), but that's on STDERR rather thatn STDOUT.

Explaination:

The first line simply stores a copy of N in the register.

The second line builds up the offset for each output row by subtracting 1 from N, multiplying this by N, rotating it to the bottom of the stack and then reversing the entire stack. When the number on top of the stack reaches 0, the stack should look like this (example uses N=5):

5 15 20 10 0 0

The third line discards the duplicate 0 from the top of the stack.

The fourth line increments the top of the stack and outputs a copy of it. This is then taken mod N, and this is used to decide if a space or newline should be printed, and if the top of the stack should be discarded - if last number printed is x, then x mod N == 0 indicates that the end of that output row has been reached. Execution ends when 1+ gets executed on an empty stack, throwing the termination error.

Previous version

This explicitly checked for an empty stack to end execution, and I was also including 3 bytes for the -v flag usage.

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

Try it online!

\$\endgroup\$
  • \$\begingroup\$ According to this meta, we no longer add flags to byte count so it is enough that you specify that the flag is used. \$\endgroup\$ – Emigna Mar 1 '18 at 10:29
  • \$\begingroup\$ @Emigna O_O thank goodness for that! Thanks for the heads up \$\endgroup\$ – Sok Mar 1 '18 at 10:32
3
\$\begingroup\$

Perl 5, -p 52 51 bytes

#!/usr/bin/perl -p
map{$|--?$\="@0
".$\:say"@0";$_+=@0for@0}@0=1..$_}{

Try it online!

\$\endgroup\$
2
\$\begingroup\$

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

Try it online!

Credits

\$\endgroup\$
  • 1
    \$\begingroup\$ You can save three bytes by changing the position of the j++: 102 bytes \$\endgroup\$ – Kevin Cruijssen Mar 1 '18 at 12:34
  • 1
    \$\begingroup\$ And another byte changing n-i/2-1 to n+~i/2 101 bytes \$\endgroup\$ – Kevin Cruijssen Mar 1 '18 at 12:36
  • \$\begingroup\$ @KevinCruijssen Thanks! I somehow posted the raw version, not the fully golfed one. My mistake, the first issue was tackled, but not the second. But you wrote them, so credits to you ;-) \$\endgroup\$ – Olivier Grégoire Mar 1 '18 at 13:04
  • \$\begingroup\$ Note: if somehow one-dimensional arrays are accepted, 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;} \$\endgroup\$ – Olivier Grégoire Mar 1 '18 at 13:27
2
\$\begingroup\$

JavaScript (ES6), 69 68 bytes

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

Well it got outgolfed before I could post it but here it is anyway. Edit: Saved 1 byte thanks to @KevinCruijssen.

\$\endgroup\$
  • \$\begingroup\$ n+n-i-1 can be n+n+~i for -1 byte, so then you are toe-to-toe with the other JavaScript answer again. :) \$\endgroup\$ – Kevin Cruijssen Mar 1 '18 at 12:33
  • \$\begingroup\$ @KevinCruijssen Brilliant thanks! \$\endgroup\$ – Neil Mar 1 '18 at 13:24
2
\$\begingroup\$

Jelly, 10 bytes

²ss2Ṛj@/Fs

Try it online!

How it works

²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.
\$\endgroup\$
2
\$\begingroup\$

Stax, 10 bytes

│æ╘▐⌡r▌═∟Y

Run and debug it online

The corresponding ascii representation of the same program is 12 characters.

JRx/r{]+rFmJ

Here's how it works.

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
\$\endgroup\$
2
\$\begingroup\$

Jelly, 13 ... 6 bytes

Thanks JonathanAllan for -1 byte!

²sm0m2

Try it online!


Use an identical algorithm to the 05AB1E answer.

\$\endgroup\$
2
\$\begingroup\$

R, 70 59 47 bytes

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

Try it online!

Thanks to Robin Ryder for a 4 byte golf, which I then golfed further.

Returns a matrix; constructs the matrix in sequence, e.g., [[1 2 3] [4 5 6] [7 8 9]], then rearranges the rows.

\$\endgroup\$
  • \$\begingroup\$ 66 bytes by avoiding rbind. \$\endgroup\$ – Robin Ryder May 8 at 11:18
  • \$\begingroup\$ @RobinRyder 59 bytes -- on mobile so I'll edit this in later \$\endgroup\$ – Giuseppe May 8 at 11:47
1
\$\begingroup\$

Python 2, 72 68 63 bytes

-4 bytes thanks to Neil

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

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I assume you can save 4 bytes by eliminating the intermediate x variable? \$\endgroup\$ – Neil Mar 1 '18 at 12:23
1
\$\begingroup\$

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

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Nice! I didn't know Octave had an until command.And I didnt\'t know about vec2mat :( Unfortunately the same length: A=B=vec2mat(1:(n=input(''))*n,n) :( \$\endgroup\$ – Stewie Griffin Mar 2 '18 at 19:39
  • \$\begingroup\$ while j++<n is also exactly the same length... Have you tried the various options or are those just coincidences? \$\endgroup\$ – Stewie Griffin Mar 2 '18 at 19:51
  • \$\begingroup\$ @StewieGriffin In this case the while loop is the same length, I tried it both ways. Often do ... until is one byte shorter than while ... end, though. \$\endgroup\$ – Steadybox Mar 2 '18 at 19:52
1
\$\begingroup\$

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

Try it online!

Fills out an array by alternating between 2 indices for rows: one index starting at the top and one starting at the bottom. The top row index starts at 0 and is incremented every 2 rows; the bottom row index starts at n-1 and is decremented every 2 rows.

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;
    }
}
\$\endgroup\$
1
\$\begingroup\$

C++ + Range 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

Not counting the 2 newlines after using namespace range::view; they are just there to separate imports from the lambda.

Mildly interesting fact: this solution makes no heap allocations. It solves the problem in O(1) space.


Explanation:

  1. iota(1, n*n+1) -> [1 ... n*n]
  2. chunk(n): every n elements together, so [1 ... n] [n+1 ... 2*n] ...
  3. Call that r
  4. r | stride(2): take every other element: [1 ... n] [2*n+1...] ...
  5. concatenate that with:
  6. r | reverse | drop(n % 2): reverse, then drop the [1 ... n] term if n is odd (there'll be an odd number of rows and we only want to print the first term once). It seems like I should be able to just do r | reverse | take, but that doesn't work for some reason.
  7. stride(2) again, take every other element. This time it's in reverse.

More readable, and 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';
    }
}
\$\endgroup\$
  • \$\begingroup\$ O(log(n)) for storing the input, if measured in bit complexity. \$\endgroup\$ – user202729 Mar 3 '18 at 5:15
  • \$\begingroup\$ @user202729 Unsure what you mean. Are you saying that for an int n, I need log(n) bits to store the input? But that's the input anyway, and we are dealing with an int where sizeof(int) == 4 (most systems), so it's a constant number of bytes used regardless of the input. \$\endgroup\$ – Justin Mar 3 '18 at 5:28
0
\$\begingroup\$

Jelly, 11 bytes

s2ZU2¦Ẏị²s$

Try it online!

\$\endgroup\$
0
\$\begingroup\$

CJam, 22 bytes

ri__*,:)/2/z[1W].{%:p}

Try it online!

\$\endgroup\$
0
\$\begingroup\$

C (gcc) 80 78

I see now this solution is wrong

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

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

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

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.