不断放大的锯齿形


24

编写一个程序或函数,该程序或函数使用正整数N并仅使用所需的行输出此放大的Z字形模式的前N个数字:

                                         26
                                       25  27                                      .
         10                          24      28                                  .
        9  11                      23          29                              .
 2     8     12                  22              30                          44
1 3   7        13              21                  31                      43
   4 6           14          20                      32                  42
    5              15      19                          33              41
                     16  18                              34          40
                       17                                  35      39
                                                             36  38
                                                               37

所以,如果N是1输出

1

如果N为2,则输出为

 2
1

如果N是3输出

 2
1 3

如果N是4输出

 2
1 3
   4

如果N是10输出

         10
        9
 2     8
1 3   7
   4 6
    5

如果N是19输出

         10
        9  11
 2     8     12
1 3   7        13
   4 6           14
    5              15      19
                     16  18
                       17

等等。

笔记

  • 之字形的每个峰或谷到达其点的距离1都比其上的峰或谷低一线。

  • N不限于44。之字形以相同的方式增长,应支持更大的N。

  • 如图所示,具有多个数字的数字只能在其角处“接触”。确保在N 100或更高时有效。

  • 除了一个可选的尾随换行符,输出中不应有空行(或仅空格)。

  • 任何行都可以有任意数量的尾随空格。

计分

以字节为单位的最短代码获胜。抢七是较早的答案。


最大可能的N是多少?
朱莉·佩勒捷

@JuliePelletier理论上没有,但是您可以假设它小于2 ^ 16。
加尔文的业余爱好

是否允许使用控制字符,还是我们仅限于数字空格和换行符?
丹尼斯

2
@丹尼斯让我们说不。只是数字/空格/换行符。
加尔文的爱好

1
有人应该以此为笑话将其提交给OEIS。
DanTheMan '16

Answers:


10

果冻41 37 29 字节

RDµḌ’½Ċ-*_\x©L€Ṣ.ị®ạ€⁶ẋj"FZj⁷

在线尝试!

怎么运行的

RDµḌ’½Ċ-*_\x©L€Ṣ.ị®ạ€⁶ẋj"FZj⁷  Main link. Argument: n (integer)

R                              Range; yield [1, ..., n].
 D                             Decimal; yield A =: [[1], ..., [1, 0], ...].
  µ                            Begin a new, monadic chain. Argument: A
   Ḍ                           Undecimal; convert back to falt range.
    ’                          Decrement to yield [0, ..., n-1].
     ½Ċ                        Take the square root and round up (ceil).
       -*                      Elevate -1 to each rounded square root.
         _\                    Cumulatively reduce by subtraction.
                               This yields [1, 2, 1, 0, -1, 0, ...], i.e., the
                               vertical positions of the digits in A.
             L€                Compute the length of each list in A.
           x                   Repeat the nth position l times, where l is the
                               nth length.
            ©                  Copy the result to the register.
               Ṣ               Sort.
                .ị             At-index 0.5; yield the last and first element,
                               which correspond to the highest and lowest position.
                  ạ€®          Take the absolute difference of each position in the
                               register and the extrema.
                               This yields the number of spaces above and below
                               the integers in r as a list of pairs.
                     ⁶ẋ        Replace each difference with that many spaces.
                         F     Flatten the list A.
                       j"      Join the nth pair of strings of spacing, separating
                               by the nth digit in flat A.
                          Z    Zip/transpose the result.
                           j⁷  Join, separating by linefeeds.

2
为什么不使用您的语言(果冻)创建一个可以在您使用几个字符的情况下就可以实现的功能?
Julie Pelletier

19
@JuliePelletier编写一种良好的高尔夫语言的技巧是提出一套指令(以及语法/语言语义),使您能够为尽可能多的不同任务编写简短的解决方案,而不是能够解决一个非常具体的问题并在单个字节中进行了挑战。好的高尔夫语言实际上往往非常强大和富于表现力,而不是仅仅是一些内置组件的集合,这些内置组件仅对它们所计算的特定功能有用,而对其他任何功能都没有用。
Martin Ender

@JuliePelletier而且这也违背PPCG SE规则
巴林特

8

PHP,211个 177 164 163字节

$n使用($x, $y)输出光标预测峰并在任一方向上动态增加阵列。

数字与对齐,str_pad()最终输出是该implode()字符串数组($g)的结果。

for($x=0,$d=-1,$h=$n=2,$y=$a=1;$a<=$argv[1];$y+=$d){$g[$y]=str_pad($g[$y],$x).$a;$x+=strlen($a);if($a++==$n){$h+=2;$n+=$h-1;$d*=-1;}}ksort($g);echo implode(~õ,$g);

在线测试!

更新:通过删除不需要的array_pad()删除了34个字节。Update2:遵循@insertusername的建议将其缩短一些。Update3:遵循@Lynn的建议,用〜õ保存一个字节,这意味着要使用LATIN-1字符集。(在在线PHP仿真器中不可用,因此未包含在其中)


只是关于此代码的问题。在访问特定元素之前,不必不必初始化$ g数组吗?我是说,给它一个长度还是插入行?我对PHP不太有经验,所以对我来说看起来很奇怪...谢谢。
Yotam Salmon

否。一旦定义$arr = [];,就可以参考$arr[anything]。某些情况下将输出通知,但此处将忽略这些通知。请注意,阅读此类内容可能对您学习语言没有太大帮助。您的评论使我意识到我可以将其缩短,尽管我最初以为我需要填充数组,但我不需要。:)
朱莉·佩莱捷

哈哈很乐于帮助;)刚刚意识到,在PHP中,数组和字典的初始化方式相同,并且在查看语法时完全相同(为什么,PHP ?!)
Yotam Salmon 2016年

一些小的改进– 164个字节:(for($x=0,$d=-1,$h=$n=2,$y=$a=1;$a<=$argv[1];$y+=$d){$g[$y]=str_pad($g[$y],$x).$a;$x+=strlen($a);if($a++==$n){$h+=2;$n+=$h-1;$d*=-1;}}ksort($g);echo implode("⏎",$g);用实际的换行符替换⏎。)
6

我相信,如果你设置了正确的编码(Latin-1的,不是UTF-8),是两个字节的替代方案"⏎"
林恩

8

Pyth,60 53 52 46 42 39 38 36 34 32 31字节

39:现在它与Jelly的错误修复版本相当,并且我已经超越了Dennis的竞争版本!

38:我对丹尼斯感到不满意

36:我又使丹尼斯感到厌烦!

34:比他的错误修复版本还低!

31:32-> 31感谢Dennis。

J1K.u+N=J_WsI@Y2JtQZjsM.t.e ++ *] * dl`hkabhSK`hk *] * dl`hkabeSKKd 
J1K.u+N=J_WsI@Y2JtQZjsM.t.eX *] * 
dl`hkhaeSKhSKabhSKhk + K N=J_WsI@Y2JtQZ=-RhSKKjsM.t.eX *] * dl`hkheSKbhkKd 
J1K.u+N=J_WsI@Y2JtQQj-#dsMC.eX *] * dl`hkheSKbhkK 
J1j-#dsMC.eX *] * dl`hkheSKbhkKd + Qbhkm = + Z = J_WsI @ td2J 
J1j-#dsMCmX *] *; l`hdyQ + Q = + Z = J_WsI @ td2Jhd 
J1j-#dsMCmX *] *; l`hdyQ + Q = + Z = J_WsI @ td2Jh 
J1j -#dsMCmX *] *; l`hdyQ + Q = + Z = @ _ BJsI @ td2h 
j-#dsMCmX *] *; l`hdyQ + Q = + Zsty%s @ td2 2h 
j-#dsMCmX *] *; l `hdyQ + Q = + Z @ _B1.E @ d2h 
JQj-#dsMCmX *] *; l`hdyQ = + J @ _B1.E @ d2h 
JyQj-#dsMCmX *] *; l`hdJ = + Q @ _B1。 E @ d2h 
j-#dsMCmX *] *; l`hdyQ = + Q @ _B1.E @ d2h
j-#dsMCmX *] *; l`hdyQ=+Q^_1.E@d2h

在线尝试!

怎么运行的

j-#dsMCmX*]*;l`hdyQ=+Q^_1.E@d2h      input: Q
j-#dsMCmX*]*;l`hdyQ=+Q^_1.E@d2hdQ    implicit filling arguments

       m                        Q    for each number d from 0 to Q-1:
                           @d2           yield the square root of d.
                         .E              yield its ceiling.
                      ^_1                raise -1 to that power. this
                                         yields the desired direction.
                   =+Q                   increment Q by this amount.

               hd                        yield d+1.
              `                          yield its string representation.
             l                           yield its length.
           *;                            repeat " " for that number of times
          ]                              yield a list containing the string above.
         *       yQ                      repeat the list for Q*2 times.
                                         the Q has changed, but Q*2 is
                                         an overshoot that is high
                                         enough, so we don't have to
                                         worry about it.

        X                                in that list, replace the
                                         element with index being the
                                         number generated above
                              hd         with d+1.

      C                              transpose the resulting array.
    sM                               flatten each element.
 -#d                                 remove lines containing only spaces.
                                     (filter on truthiness of set difference with space)
j                                    join by newlines.

2
39:与果冻相当 ”;“ 38:我对Dennis感到厌恶! ”你做了几个小时,但是@Dennis似乎不喜欢在代码高尔夫中被殴打:果冻37个字节;)
Kevin Cruijssen

1
@KevinCruijssen完成。
Leaky Nun

真好!xDM̶a̶y̶b̶e̶我有一个疯狂的想像力,但是现在我想您已经经历了数小时的挫折,直到您终于找到了这个更短的解决方案,然后@Dennis会不经意地醒来并再次缩短他的代码。(Jk,我希望您留在Dennis之下!)
Kevin Cruijssen 2016年

@KevinCruijssen多田!现在,它低于错误修复的版本。
Leaky Nun

5

MATLAB,148个字节

n=input('');k=fix(n^.5);m=0;w=1;d=-1;for l=1:n;s=num2str(l);m(k+1,w:w+nnz(s)-1)=s;w=w+nnz(s);k=k+d;d=d*(-1)^(l^.5==fix(l^.5));end;[m(any(m,2),:),'']

请注意,八度中缺少空格,因为MATLAB会将索引0为的字符打印为空格,而八度只是忽略了该字符。

说明:

n=input('');
k=fix(n^.5);                    %caculate starting height
m=0;w=1;d=-1;                   %initialize counters and output matrix
for l=1:n;
    s=num2str(l);
    m(k+1,w:w+nnz(s)-1)=s;      %insert current index as a string
    w=w+nnz(s);                 %current horizontal position
    k=k+d;                      %current vertical position
    d=d*(-1)^(l^.5==fix(l^.5)); %if we reached a square number, change direction
end
[m(any(m,2),:),'']              %delete all zero rows

3

Haskell,144 142字节

g n|k<-take n$scanl(+)0$[1..]>>= \x->(-1)^x<$[2..2*x]=unlines[[1..n]>>= \x->show x#(k!!(x-1)==y)|y<-[minimum k..maximum k]]
s#g|g=s|1<2=' '<$s

用法示例:

*Main> putStr $ g 19
         10                  
        9  11                
 2     8     12              
1 3   7        13            
   4 6           14          
    5              15      19
                     16  18  
                       17    

怎么运行的:

s#g|g=s|1<2=' '<$s              -- # is a helper function that expects a string s
                                -- and a boolean g. It returns s if g is True, else
                                -- as many spaces as there a characters in s 

k<-take n$                      -- bind k to the first n elements of
 [1..]>>= \x->(-1)^x<$[2..2*x]  -- 2*x-1 copies of (-1)^x for each x in [1,2,3,...]
                                -- i.e. [-1, 1,1,1, -1,-1,-1,-1,-1, 1,1,1,1,1,1,1..]
 scanl(+)0                      -- build partial sums, starting with 0
                                -- i.e. [0,-1,0,1,2,1,0,-1,-2,-3,-2,-1...]
                                -- -> k is the list of y coordinates for the
                                --    numbers 1,2,3,...

 [  |y<-[minimum k..maximum k]] -- for all y coordinates in k 
      \x->show x#(k!!(x-1)==y)  -- map the # function
  [1..n]>>=                     -- over [1..n] (the x coordinates)
                                -- where # is called with
                                --  s -> a string representation of x 
                                --  g -> True if k at index x equals the current y
unlines                         -- join with newlines

编辑:感谢@Lynn两个字节!


2

JavaScript(ES6),213个字节

with(Math)n=>(a=[...Array(n)].map((_,i)=>n-=1+sqrt(--i)&1||-1).map((e,_,a)=>e-min(...a))).map((e,i)=>r[e][i]=++i,r=[...Array(1+max(...a))].map(_=>a.map((_,i)=>` `.repeat(1+log10(++i)))))&&r.map(a=>a.join``).join`\n`

其中\n代表文字换行符。说明:

with(Math)                          Bring functions into scope
 n=>                                Accepts one parameter
  (a=                               Intermediate result variable
   [...Array(n)].map(               For each number 0..n-1
    (_,i)=>n-=                      Accumulate index for each number
     1+sqrt(--i)&1||-1              Calculate the direction
    ).map((e,_,a)=>e-min(...a))     Scale the smallest index to zero
  ).map((e,i)=>r[e][i]=++i,         Overwrite the padding with 1..n
   r=[...Array(1+max(...a))].map(   Calculate number of lines
    _=>a.map((_,i)=>                For each number 1..n
     ` `.repeat(1+log10(++i)))))    Calculate the padding needed
  &&r.map(a=>a.join``).join`\n`     Join everything together

简而言之,pow(-1,ceil(sqrt(i)))我将其重写,因为sqrt(i-1)&1||-1这对它不起作用,i=0因此要修复,我加1,但这会翻转结果的符号,这就是我最终得到的原因n-=


嘿,您有金牌了!不错的工作!圣洁的烟雾几乎代表了我 保持下去!
Conor O'Brien

1
@CᴏɴᴏʀO'Bʀɪᴇɴ那仅仅是“狂热者”徽章。显然,我真的很接近获得金牌高尔夫标签徽章的权利!
Neil

双圣烟。我需要移动XD
Conor O'Brien

1

Python 2,137字节

l={}
i=x=y=n=v=0
exec"v+=1;l[y]=l.get(y,'').ljust(x)+`v`;x+=len(`v`);i=-~i%-~n;y+=n%4-1;n+=2>>i*2;"*input()
for k in sorted(l):print l[k]

查看ideone上的输出。


嗯...它不会持续不断。
Zizouz212 '16

@ Zizouz212确实如此,ideone只是具有固定的输出,并会自动中断太长的行。
瑕疵的
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.