打印小册子


39

读书很容易,但是印刷书可能有点棘手。在打印小册子时,打印机需要以某种方式排列页面,以便从左到右阅读。完成此操作的方式是使用如下所示的模式

n, 1, 2, n-1, n-2, 3, 4, n-3, n-4, 5, 6, n-5, n-6, 7, 8, n-7, n-8, 9, 10, n-9, n-10, 11, 12, n-11…

测试用例

4页的小册子: 4, 1, 2, 3

8页的小册子: 8,1,2,7,6,3,4,5

12页的小册子: 12,1,2,11,10,3,4,9,8,5,6,7

16页的小册子: 16,1,2,15,14,3,4,13,12,5,6,11,10,7,8,9

20页的小册子: 20,1,2,19,18,3,4,17,16,5,6,15,14,7,8,13,12,9,10,11

任务

给定一个整数n,该整数是4的倍数,您的任务是显示一个数字数组,该数字数组可用于打印一本书n

注意:只要输出生成正确的数字(无论是由空格,逗号,连字符还是括号定界),都可以使用任何方法来求解

这是一个问题,因此答案将以字节计分,赢得的字节数最少。


我们是否保证输入将始终被4甚至偶数整除?无论哪种方式,都可以添加更多测试用例吗?欢迎来到PPCG :)
毛茸茸的

8
欢迎来到PPCG,这是第一个不错的挑战!请注意,我们建议在发布之前在沙箱中提出新挑战。
奥利弗·尼

1
您的输入需要为4的倍数
tisaconundrum

1
会很好(但可能微不足道)以支持任何值,并在需要时用空白页填充(可能是另一个挑战?)
Barranka

1
我们可以用空格,连字符或其他定界符而不是逗号来定界数组吗?
TehPers

Answers:


8

05AB1E9 8 7字节

L`[Žˆrˆ

在线尝试!

说明

L           # push range [1 ... input]
 `          # split as separate to stack
  [Ž        # loop until stack is empty
    ˆ       # add top of stack to global list
     r      # reverse stack
      ˆ     # add top of stack to global list
            # implicitly display global list

13

JavaScript(ES6),49个 45字节

@RickHitchcock的帮助下保存了4个字节

f=(n,k=1)=>n<k?[]:[n,k,k+1,n-1,...f(n-2,k+2)]

演示版


非递归,51字节

n=>[...Array(n)].map((_,i)=>[2*n-i,,++i][i&2]+1>>1)

演示版


47个字节: f=(n,a=1)=>n<a+3?[]:[n,a,a+1,n-1,...f(n-2,a+2)]
瑞克·希区柯克

1
@RickHitchcock n<a实际上足够了,因此节省了4个字节。谢谢!
Arnauld

6

Python 2,99 93 88 58 56 55字节

f=input()
for i in range(1,f/2,2):print-~f-i,i,i+1,f-i,

在线尝试!

通过消除不必要的缩进,可以减少-6个字节,谢谢Oliver Ni

-5字节通过更改条件,谢谢Luis Mendo

通过优化打印语句来实现-30字节,谢谢Arnold Palmer

通过将循环放在一行上来获得-2字节,谢谢nedla2004

通过做一些巫术-1字节,谢谢Xcoder先生


保存字节通过使用1个空间,而不是4
奥利弗镍

哦,是的,我总是忘记了。谢谢。
LyricLy

1
-29个字节使用lambda(尽管这可能足以保证单独的答案)。
notjagan

@notjagan继续发布,并发表自己的想法。
LyricLy

58字节,只需稍微更改一下打印即可。现在f-i+1,i,i+1,f-i,它在每个循环中打印,而不是有条件地打印最后一个值。这也允许删除首字母print f,
阿诺德·帕尔默

6

Python 2,46个字节

lambda n:map(range(1,n+1).pop,n/4*[-1,0,0,-1])

在线尝试!

生成范围[1..n]并以重复方式从正面和背面弹出back, front, front, back, ...


Python 2,49个字节

f=lambda n,k=1:n/k*[0]and[n,k,k+1,n-1]+f(n-2,k+2)

在线尝试!

生成前4个元素,然后递归继续,上限值n减少2,下限值k增加2。


Python 2,49个字节

lambda n:[[n-i/2,i/2+1][-i%4/2]for i in range(n)]

在线尝试!

直接生成i列表的'th值,使用-i%4/2布尔值表示采用较低还是较高的值。



5

MATL19 17 10字节

:t"0&)@o?P

在线尝试!

说明

:          % Implicitly input n. Push range [1 2 ... n]
t          % Duplicate
"          % For each (that is, do n times)
  0&)      %   Push last element, and then subarray with remaining elements
  @        %   Push 1-based iteration index
  o?       %   Is it odd? If so
    P      %     Reverse subarray of remaining elements
           %   Implicit end
           % Implicit end
           % Implicitly display stack

5

果冻 12  11 字节

改进为11个字节,“组合方法”:

9Bṁ×ḶṚÆ¡‘Œ?

在线尝试!

怎么样?

这使用置换计算和阶乘数系统:

9Bṁ×ḶṚÆ¡‘Œ? - Link n                        e.g. 16
9B          - nine in binary                     [1,0,0,1]
  ṁ         - mould like n                       [1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1]
    Ḷ       - lowered range(n)                   [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
   ×        - multiply                           [0,0,0,3,4,0,0,7,8,0,0,11,12,0,0,15]
     Ṛ      - reverse                            [15,0,0,12,11,0,0,8,7,0,0,4,3,0,0,0]
      Æ¡    - convert from factorial base        19621302981954 (=15*15!+12*12!+...+3*3!)
        ‘   - increment                          19621302981955 (we actually wanted 1*0! too)
         Œ? - shortest permutation of natural numbers [1,2,...] that would reside at that
            -   index in a sorted list of all permutations of those same numbers
            -                                    [16,1,2,15,14,3,4,13,12,5,6,11,10,7,8,9]

未经改进的12个字符,“编织图案”:

RṚ‘żRs2Z€FḊṁ

在线尝试!

怎么样?

这是简单的方法,它创建了两个股,将它们交织,然后修剪松散的末端:

RṚ‘żRs2Z€FḊṁ - Link: n                      e.g. 8
R            - range(n)                          [1,2,3,4,5,6,7,8]
 Ṛ           - reverse                           [8,7,6,5,4,3,2,1]
  ‘          - increment                         [9,8,7,6,5,4,3,2]
    R        - range(n)                          [1,2,3,4,5,6,7,8]
   ż         - zip (interleave)                  [[9,1],[8,2],[7,3],[6,4],[5,5],[4,6],[3,7],[2,8]]
     s2      - split into chunks of length 2     [[[9,1],[8,2]],[[7,3],[6,4]],[[5,5],[4,6]],[[3,7],[2,8]]]
       Z€    - transpose €ach (cross-stitch?!)   [[[9,8],[1,2]],[[7,6],[3,4]],[[5,4],[5,6]],[[3,2],[7,8]]]
         F   - flatten                           [9,8,1,2,7,6,3,4,5,4,5,6,3,2,7,8]
          Ḋ  - dequeue (removes excess start)    [8,1,2,7,6,3,4,5,4,5,6,3,2,7,8]
           ṁ - mould like n (removes excess end) [8,1,2,7,6,3,4,5]

聪明。+1
暴民埃里克'17年

4

八度43 36字节

在C 中可以找到此答案的端口号(gcc)。

@(n)[n-(k=1:2:n/2)+1;k;k+1;n-k](:)';

说明

  1. k=1:2:n/2:生成一个从1到n/22 的线性序列。请注意,此序列将立即用于下一步。
  2. [n-k+1;k;k+1;n-k]:创建一个4行矩阵,使得第一行创建n, n-2, n-4...向下的序列n-(n/2)+2,第二行1, 3, 5...向上直到n/2 - 1,第三行是第二行加1,第四行是第一行加1。
  3. [n-k+1;k;k+1;n-k](:)':这会将矩阵的所有列从左到右堆叠在一起,以形成单个列向量,然后将其转置为行向量以便于显示。通过这种方式将列堆叠在一起,可以精确地创建所需的顺序。

请注意,这是一个匿名函数,因此您可以在使用它之前将其分配给变量,也可以使用ans在创建函数后创建的内置变量。

在线尝试!


1
嗨,我认为您甚至可以通过使其成为匿名函数来缩短它,因此您不必调用输入。看到这个链接:gnu.org/software/octave/doc/v4.0.3/…–
Michthan

1
@Michthan True。我最初这样做是因为代码不止一个语句。我对此进行了进一步的研究,因此删除了对它的调用,input并在创建第一行并存储n实际匿名函数输入本身的输入时,通过存储基本增量向量进一步滥用了语法,因此现在可以将其放入一个声明。谢谢!
rayryeng-恢复莫妮卡的时间

3

R,48个字节(改进)

感谢@Giuseppe -7个字节!

n=scan();(x=order(1:n%%2))[order(-(n/2+.5-x)^2)]

诀窍是x=1:n;x[order(x%%2)]等同于order(1:n%%2)

在线尝试!

R,55个字节(原始)

打高尔夫球

n=scan();x=1:n;x=x[order(x%%2)];x[order(-(n/2+.5-x)^2)]

取消评论

n从stdin中读取。

n=scan()

定义x为从1到的页面顺序n

x=1:n

订购页面,使均匀页面位于不均匀页面之前。

x=x[order(x%%2)]

相对于书籍的中心,按降序对页面进行排序n/2+.5

x[order(-(n/2+.5-x)^2)]

8页示例:

  • 中心为4.5;
  • 第1页和第8页距离中心最远,但是第8页排在第一位,因为8页是偶数。
  • 第2页和第7页是离中心第二远的位置,但第2页排在最前面,因为2是偶数。
  • 等等。

在线尝试!


1
不错,比我(被盗)的解决方案还好
Giuseppe


1
诀窍是注意到(1:n)[order(1:n%%2)]order(1:n%%2)
Giuseppe

2

Mathematica,54 53 45字节

Join@@Range[#][[(-1)^k{k,-k}]]~Table~{k,#/2}&

说明

Join@@Range[#][[(-1)^k{k,-k}]]~Table~{k,#/2}&  (* Input: # *)
                              ~Table~{k,#/2}   (* Iterate from k=1 to #/2 *)
      Range[#][[            ]]                 (* From {1..#}, take... *)
                      {k,-k}                   (* k-th and negative k-th element *)
                                               (* negative k-th = k-th from the end *)
                (-1)^k                         (* Reversed for odd k *)
Join@@                                         (* Join the result *)


2

Haskell,42个字节

n#a|n<a=[]|x<-n-2=n:a:a+1:n-1:x#(a+2)
(#1)

在线尝试!

长一字节:

Haskell,43个字节

f n=[1,3..div n 2]>>= \x->[n-x+1,x,x+1,n-x]

2

Java 8,84 72字节

n->{for(int j=0;++j<n;System.out.printf("%d,%d,%d,%d,",n--,j++,j,n--));}

要么

n->{for(int j=0;++j<n;System.out.print(n--+","+j+++","+j+","+n--+","));}

-12个字节感谢@TheLethalCoder对C#答案的评论。

旧答案(84个字节):

n->{int r[]=new int[n],i=1,N=n,J=1;for(r[0]=n;i<n;r[i]=-~i++%4<2?J++:--N);return r;}

说明:

在这里尝试。

n->{                  // Method with integer parameter and no return-type
  for(int j=0;++j<n;  //  Loop from 1 to `n` (exclusive)
    System.out.printf("%d,%d,%d,%d,",n--,j++,j,n--)
                      //   Print four numbers simultaneously
  );                  //  End of loop
}                     // End of method


1

迅捷 3,74字节

func g(f:Int){for i in stride(from:1,to:f/2,by:2){print(f-i+1,i,i+1,f-i)}}

在线尝试!

斯威夫特3,60字节

{f in stride(from:1,to:f/2,by:2).map{(f-$0+1,$0,$0+1,f-$0)}}

由于某种原因,这在我到目前为止尝试过的任何在线环境中均不起作用。如果你想测试它,把var g=它前面,并与调用它print(g(12))Xcode中(游乐场)

这是我在8.3.1(Running Swift 3.1)版本的Xcode操场上运行后的图片:

在此处输入图片说明


1

QBIC,25个字节

[1,:/2,2|?b-a+1,a,1+a,b-a

尽管输入为%4,但实际节奏是基于2的。

说明

[1,:/2,2|   FOR ( b=1; b <= <input>/2; b=b+2)               
?           PRINT
 b-a+1,     n
 a,         1
 1+a,       2
 b-a        n-1


1

cQuents,21字节

=n::n-z+1,z+1,x-1,z-1

在线尝试!

说明

                            Implicit input n
=n                          First item in the sequence is n
  ::                        Mode :: (Sequence 2): print sequence from 1 to n
                            Comma delimited items are rotated through
    n-z+1,                    n - previous + 1
          z+1,                previous + 1
              x-1,            third-previous - 1
                  z-1         previous - 1

1

R64 60字节

令人震惊的是djhurio!他的回答很优雅,请赞成。

n=scan();matrix(c(n-(k=seq(1,n/2,2))+1,k,k+1,n-k),4,,T)[1:n]

rayryeng的Octave答案的端口。

在线尝试!

原始解决方案(64字节):

f=function(n,l=1:n)`if`(n,c(l[i<-c(n,1,2,n-1)],f(n-4,l[-i])),{})

递归函数。

在线尝试!


第一次有人用我的答案作为灵感。谢谢:)
rayryeng-恢复莫妮卡

1
很难打败您,但是我用55字节的答案(codegolf.stackexchange.com/a/138045/13849)来解决这个问题。
djhurio '17

1

Bash + Perl + Groff + Psutils,48个字节

perl -nE'say".bp
"x--$_'|groff|psbook>/dev/null

在显示输出stderr。输出包含一些尾随垃圾。

使用示例:

$ echo 20 | perl -nE'say".bp
> "x--$_'|groff|psbook>/dev/null
[20] [1] [2] [19] [18] [3] [4] [17] [16] [5] [6] [15] [14] [7] [8] [13] [12] 
[9] [10] [11] Wrote 20 pages, 4787 bytes

0

Pyth21 20字节

sm[hK-QddhdK):1/Q2 2

测试套件。

如果允许输出为嵌套列表:

Pyth20 19字节

m[hK-QddhdK):1/Q2 2

测试套件。


说明

sm [hK-QddhdK):1 / Q2 2-完整程序。

 m:1 / Q2 2-使用变量d映射范围(1,input()/ 2,2)。
  []-构造具有以下内容的列表:
   hK-Qd-输入-d + 1,
        d-d
         hd-d +1和
           K-输入-d。
s-展平列表并隐式打印。


0

C#,107个字节

int[]F(int p){var a=new int[p];for(int i=0,q=1;q<p;a[i++]=p--){a[i++]=p--;a[i++]=q++;a[i++]=q++;}return a;}

保留两个计数器,一个从1开始,一个在p处。在每个循环迭代中,写入四个元素,然后在每个条目之后仅增加或减少计数器。当柜台在中间相遇时,停下来。

int[] F(int p)
{
    var a = new int[p];
    for(int i = 0, q = 1; q < p; a[i++] = p--)
    {
        a[i++] = p--;
        a[i++] = q++;
        a[i++] = q++;
    }
    return a;
}

您可以通过将方法放在委托中来节省一些字节。然后,您的代码将如下所示:p=>{var a=new int[p];for(int i=0,q=1;q<p;a[i++]=p--){a[i++]=p--;a[i++]=q++;a[i++]=q++;}return a;};,其中System.Func<int, int[]> f =不包含字节数。您还可以添加一个指向TIO的链接,这在尝试使人们自己尝试您的代码时非常有用!
伊恩H.17年

@IanH。使用lambda时,可以省略尾随的半冒号。
TheLethalCoder

初始化q0和预增量在q<p- > ++q<p然后删除第二后增量保存一个字节。将两个尾随循环语句移至for循环的最后阶段,以便删除花括号。
TheLethalCoder

2
如果允许尾随逗号,则以下内容适用于71个字节p=>{for(int q=0;++q<p;)System.Console.Write(p--+$",{q++},{q},{p--},");}TIO。
TheLethalCoder


0

Pyth27 24 23字节

-3字节,而不是在末尾打印。

-1感谢Xcoder先生

V:1/Q2 2pjd[-QtNNhN-QNk

在线尝试!

或在在线编译器/执行器上

这是我在Pyth中的第一个真实程序,所以可能有我不知道的更好的方法。

说明

V:1/Q2 2pjd[-QtNNhN-QNk
V:1/Q2 2                   # For N in range(1, Q/2, 2):
        pjd                # print " ".join(...),
           [-QtNNhN-QNk    # The list [n - (N-1), N, N + 1, n - N, ""] (n is input)

我发现了一些改进,并决定他们应该得到自己的答案。
Xcoder先生17年

顺便提一下,更换FNV-1字节
Xcoder先生

0

C ++(gcc)89 84 68字节

作为未命名的通用lambda。n是#pages(%4 == 0),C是结果的参考参数,是一个空容器,例如vector<int>(仅push_back需要)。

[](int n,auto&C){for(int i=0,j=0;i<n;C.push_back(++j%4<2?n--:++i));}

先前的解决方案:

#define P C.push_back(
[](int n,auto&C){for(int i=0;i<n;P n--),P++i),P++i),P n--));}

在线尝试!

稍微松了一下:

auto f=
[](int n,auto&C){
 for(int i=0,j=0;
     i<n;
     C.push_back(++j%4<2 ? n-- : ++i));
}

先前的解决方案略显不足

auto f=
[](int n, auto&C){
 for(
  int i=0;
  i<n;
   P n--),
   P++i),
   P++i),
   P n--)
 );
}
;

它开发起来非常简单,并且肯定在算法上有一些小的优化。

  • Edit1:将算术统一保存5个字节
  • Edit2:统一后,将4个步骤合并

用法:

std::vector<int> result;
f(n, result);

Print-Variant,已过时 77字节

如果您坚持要打印值,则有以下解决方案:

[](int n,auto&o){for(int i=0;i<n;o<<n--<<' '<<++i<<' '<<++i<<' '<<n--<<' ');}

o您想要的地方在哪里std::ostream,就像std::cout

用法(如果将第二个lambda分配给g):

g(n, std::cout);


0

Lua,94个字节

对于这个挑战,我实际上想出了两种都是94字节的不同方法。

方法1:

function f(n,i)i=i or 1 return n>i and('%s,%s,%s,%s,%s'):format(n,i,i+1,n-1,f(n-2,i+2))or''end

注释代码:

function f(n,i)
  i=i or 1
  -- On the first iteration i will be nil so I'm setting it's value to 1 if it is.

  return n>i and ('%s,%s,%s,%s,%s'):format(n,i,i+1,n-1,f(n-2,i+2)) or ''
  -- Here i return a ternary statement
  -- If n>i is true, it will return a string using string.format() and part of this is recursion
  -- If it's false, it will just return an empty string
end

方法2:

function f(n,i)i=i or 1 return n>i and n..','..i..','..i+1 ..','..n-1 ..','..f(n-2,i+2)or''end

此方法类似于第一个方法,但是我返回的是串联字符串,而不是string.format()

在这两种方法中,我都使用了n的概念,并且我越来越靠近


0

PHP,51 + 1字节

while($i<$k=&$argn)echo$k--,_,++$i,_,++$i,_,$k--,_;

打印带下划线的下划线分隔的页码。
与管道一起运行-nR在线尝试


0

J,22字节

($,)_2|.`]\1+],@,.&i.-

在线尝试!

说明

($,)_2|.`]\1+],@,.&i.-  Input: integer n
             ]          Identity
                     -  Negate
                  &i.   Form the ranges [0, 1, ..., n-1] and [n-1, ..., 1, 0]
                ,.      Interleave
              ,@        Flatten
           1+           Add 1
    _2    \             For each non-overlapping sublist of size 2
        `                 Cycle between these two operations
      |.                    Reverse for the first, third, ...
         ]                  Identity for the second, fourth, ...
  ,                     Flatten
 $                      Reshape to length n
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.