如何以最少的字节数打印以下格式?


20

这个挑战的灵感来自这个现已删除的问题。


以一个正整数N作为输入,并输出遵循以下模式的数字为1 .. N 2的矩阵:

在第一行中用1 .. N填充,然后在最后一行(行号N)中用(N + 1).. 2N填充,然后在第二行中用(2N + 1).. 3N填充,并继续直到您填充所有行。

输出格式灵活,因此可以接受列表列表等。

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

适用标准规则。每种语言的最短答案(以字节为单位)获胜。一如既往地鼓励解释。


只要该错误未打印到STDOUT,是否允许条目以错误终止?
索克(Sok)

@Sok是的,默认情况下允许。
Martin Ender '18

1
我想标题是从已删除的问题中摘录的,但是由于它不是很容易搜索(查找重复等),因此您可以更改为更好的标题吗?
user202729'3

1
由于“输出格式灵活”,我可以输出一维数组,并按行对数字进行排序吗?(例如:)1 2 3 7 8 9 4 5 6输出格式是否灵活?
奥利维尔·格雷戈雷(OlivierGrégoire),

4
APL解决方案可能是旧波斯楔形文字的一个特征。
标记

Answers:


7

05AB1E13 8字节

借助Rod,节省了5个字节

nLô«āÉÏ

在线尝试!

说明

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

红宝石,53个字节

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

说明:

首先将所有数字放入单个数组,然后对数组进行切片,并在每次迭代时跳过一行。在第一次(n / 2 + n%2)次迭代之后,没有什么要跳过的,然后将所有剩余的行向后移动。

在线尝试!



4

JavaScript,68个字节

编辑保存的3个字节,@ user71546

首先尝试以下明显的方法:从1开始计数,并从外到内从两侧填充数组

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

测试

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现在68
edc65 '18

3

Haskell,62个字节

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

在线尝试!输出是列表的列表,例如(0#) 3yields [[1,2,3],[7,8,9],[4,5,6]]


3

> <>51 + 3 = 54 47字节

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

在线尝试!

程序启动时,使用该-v标志,预期在堆栈顶部输入。输出由不对齐的数字组成,这些数字由单个空格分隔,每行由单个换行符分隔。输出示例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

...后跟一个换行符。程序以错误(something smells fishy...)终止,但这是在STDERR而不是STDOUT上。

说明:

第一行只是将的副本存储N在寄存器中。

第二行通过从中减去1 N,乘以,将其N旋转到堆栈的底部,然后反转整个堆栈,为每个输出行建立偏移量。当堆栈顶部的数字达到0时,堆栈应如下所示(示例使用N=5):

5 15 20 10 0 0

第三行0从堆栈顶部丢弃重复项。

第四行递增堆栈的顶部并输出其副本。然后将其取为mod N,并用于确定是否应打印空格或换行符,以及是否应放弃堆栈的顶部-如果最后打印的数字为x,则x mod N == 0表明已到达输出行的末尾。1+在空堆栈上执行时,执行结束,并引发终止错误。

先前版本

这明确检查了一个空堆栈以结束执行,我还包括3个字节用于-v标志使用。

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

在线尝试!


根据此meta,我们不再将标志添加到字节数,因此您只需指定使用标志就足够了。
Emigna '18

@Emigna O_O感谢天哪!感谢您的抬起头


2

Java(OpenJDK 9),101字节

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

在线尝试!

学分


1
您可以通过更改以下位置来保存三个字节j++102个字节
Kevin Cruijssen

1
另一个字节n-i/2-1变为n+~i/2 101个字节
Kevin Cruijssen

@KevinCruijssen谢谢!我以某种方式发布了原始版本,而不是完整版本。我的错误是解决了第一个问题,但没有解决。但是您写了它们,所以功劳了;-)
OlivierGrégoire18年

注意:如果以某种方式接受一维数组,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;}
OlivierGrégoire'18

2

JavaScript(ES6),69 68字节

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

好吧,在我可以发布它之前,它已经过时了,但是无论如何它还是在这里。编辑:由于@KevinCruijssen,节省了1个字节。


n+n-i-1可以是n+n+~i-1个字节,因此您将与另一个JavaScript答案从头到尾。:)
Kevin Cruijssen

@KevinCruijssen非常感谢!
尼尔

2

果冻,10字节

²ss2Ṛj@/Fs

在线尝试!

怎么运行的

²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 个字节

│æ╘▐⌡r▌═∟Y

在线运行和调试

同一程序的相应ascii表示形式为12个字符。

JRx/r{]+rFmJ

运作方式如下。

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字节

-4字节归功于Neil

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

在线尝试!


我假设您可以通过消除中间x变量来节省4个字节?
尼尔

1

八度,102字节

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

在线尝试!


真好!我不知道Octave有until命令。而且我也不知道vec2mat:(不幸的是,同样的长度:A=B=vec2mat(1:(n=input(''))*n,n):(
Stewie Griffin

while j++<n长度也完全相同...您尝试过各种选择还是只是巧合?
Stewie Griffin

@StewieGriffin在这种情况下,while循环的长度是相同的,因此我尝试了两种方式。不过,通常通常do ... until比短一个字节while ... end
Steadybox'3

1

C(gcc),110个字节

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

在线尝试!

通过在行的2个索引之间交替来填充数组:一个索引从顶部开始,一个索引从底部开始。首行索引从0开始,每2行递增一次;最底行的索引从n-1开始,每2行减1。

取消高尔夫:

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 ++ + 范围V3,159字节

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

在魔盒上直播

之后不算2条换行符using namespace range::view; 它们只是将进口与lambda分开。

有趣的事实:此解决方案不进行堆分配。它解决了O(1)空间问题。


说明:

  1. iota(1, n*n+1) -> [1 ... n*n]
  2. chunk(n):每个n元素都在一起,所以[1 ... n] [n+1 ... 2*n] ...
  3. 叫那个 r
  4. r | stride(2):采用其他所有元素: [1 ... n] [2*n+1...] ...
  5. 将其与:
  6. r | reverse | drop(n % 2):反向,[1 ... n]如果if n是奇数,则删除该术语(行数为奇数,我们只希望将第一个术语打印一次)。看来我应该能够做到r | reverse | take,但是由于某些原因,这行不通。
  7. stride(2)再次,考虑其他所有要素。这次是相反的。

更具可读性和可测试性:

#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))用于存储输入(如果以位复杂度衡量)。
user202729

@ user202729不确定您的意思。您是说对int n,我需要log(n)位来存储输入吗?但这仍然是输入,而我们正在处理一个intwhere sizeof(int) == 4(大多数系统),因此无论输入如何,它都是一个恒定的字节数。
贾斯汀




By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.