星号螺旋


29

给定大小S和步长的螺旋N,输出S*S具有N星号的“方形” 螺旋,该螺旋从外半径到内半径顺时针方向构建。

下面的测试用例(示例)。

  1. 输入: 4 3

    输出:

    ***
    
  2. 输入: 4 6

    输出:

    ****
       *
       *
    
  3. 输入: 4 11

    输出:

    ****
       *
    *  *
    ****
    
  4. 输入: 6 18

    输出:

    ******
         *
         *
    *    *
    *    *
    ******
    
  5. 输入: 6 22

    输出:

    ******
    ***  *
    *    *
    *    *
    *    *
    ******
    
  6. 输入: 6 27

    输出:

    ******
    ******
    *   **
    *   **
    *   **
    ******
    
  7. 输入: 1 1

    输出:

    *
    

在以下情况下无需处理这些情况:

  • 提供的N星号不能“适合”给定S*S尺寸的螺旋线。

  • 任一NS为零。

挑战是代码高尔夫球,最短的字节答案胜出,可以使用任何语言。

您的输出可能具有任意数量的尾随(但没有前导)空格/换行符。


我们可以有尾随空格/换行符吗?
user202729 '18

2
我称之为S 大小(或至少直径),而不是半径
路易斯Mendo

@路易斯公平点!
nicael

3
亲爱的朋友们,请同时对答案投票,而不仅仅是问题。挑战很容易。(我认为)提供答案显然更加困难。
nicael

2
只有你这样想。编写一个易于接受且明确的挑战非常困难。(只需在此处查看评论主题,在发布挑战后有一些建议)
user202729 '18

Answers:


16

MATL17 16字节

UGlYLGoQ&P->42*c

在线尝试!

说明(带有示例)

考虑输入411作为一个例子。

U       % Implicit input: S. Push S^2
        % STACK: 16
G       % Push S again
        % STACK: 16, 4
lYL     % Outward, clockwise, east-first spiral of that size
        % STACK: 16,
                 [ 7  8  9 10;
                   6  1  2 11;
                   5  4  3 12;
                  16 15 14 13]
GoQ     % Push S, compute parity, add 1. Gives 1 for even S, 2 for odd
        % STACK: 16,
                 [ 7  8  9 10;
                   6  1  2 11;
                   5  4  3 12;
                  16 15 14 13],
                 1
&P      % Flip along that dimension (1 is vertical, 2 is horizontal).
        % This corrects for the orientation of the spiral
        % STACK: 16,
                 [16 15 14 13;
                   5  4  3 12;
                   6  1  2 11;
                   7  8  9 10]
-       % Subtract, element-wise. The upper-left corner becomes 0
        % STACK: [ 0  1  2  3
                  11 12 13  4
                  10 15 14  5
                   9  8  7  6]
>       % Implicit input (below): N. Greater than?, element-wise.
        % This transforms the first N entries, starting from
        % upper-left, inward, east-first, into 1, and the rest
        % into 0
        % STACK: [1 1 1 1;
                  0 0 0 1;
                  1 0 0 1;
                  1 1 1 1]
42*     % Multiply each entry by 42
        % STACK: [42 42 42 42;
                   0  0  0 42;
                  42  0  0 42;
                  42 42 42 42]
c       % Convert to char. Char 0 will be displayed as space.
        % Implicit display
        % STACK: ['****';
                  '   *';
                  '*  *';
                  '****']

1
哇,我从来都不擅长打高尔夫球,但是只能用17个字节来解决它……看起来很神奇:)(我知道可能会出现更短的答案,但是您是第一位,这就是我的印象:)
nicael

1
部分工作是通过内置的螺旋函数完成的。我刚刚添加了一个解释
Luis Mendo '18

@nicael欢迎来到针对特定目的的高尔夫语言世界。:)
暴民埃里克(Erik the Outgolfer)'18年

3
+1
加上


6

Stax,19 个字节

±♪☺ÿzMæ¡♠à╣♂7☼V♀§9↓

运行并调试

它首先构建一个字符串,该字符串包含结果中所有字​​符的所有星号都左对齐。然后,它将越来越大的切片从字符串的末尾取下来,并在旋转网格时将其“包裹”在网格周围。

这是相同的程序,已解压缩,已取消打包和已注释。

'**     repeat "*" specified number of times
,J(     square the top of the input stack, and right-pad string to that length
z       push an empty array - this is the result grid built up in the loop
{       begin a block to loop
  ~     push grid to the input stack
  ihNv  push -(i / 2) - 1 where i is the 0-based iteration index using integer division
  :/]   split the string at that index and wrap the second half in a singleton array
  ,     pop the grid from the input stack
  rM+   rotate the grid clockwise, then prepend the split string as the new first row
  n     copy what's left of the original string to top of stack for the loop condition
w       while; execute block until condition is truthy
m       display resulting grid

运行并调试


2
令我感到非常惊奇的是,在Android上,这个答案包含一个橙色的Blob笑脸。
StarWeaver

@StarWeaver在Stax中有许多答案可以做到这一点。

当我阅读解释并没有看到解释时,我真的很困惑。我只是以为Stax的代码页真的很奇怪!
ndm13'4

@ ndm13:我想它确实有一个奇怪的代码页。它源自CP437,它是一种具有相同字符的“真实”编码。如果您在手机上点击该链接,则应该看到同一张笑脸。
递归

5

Python 2,117个字节

n,k=input()
i=0;d=1
l=(' '*n+'\n')*n
exec"l=l[:i]+'*'+l[i+1:];d=[~n/d*cmp(d*d,2),d][' '<l[i+d:]<'*'];i+=d;"*k
print l

在线尝试!


4

APL(Dyalog),65字节

' *'[1+⎕>⊖∘⌽⍣o(⊖×⍨-,⍨⍴∘(⍋+\)×⍨↑(⌈2÷⍨×⍨),(+⍨⍴1,⊢,¯1,-)(/⍨)2/⍳)o←⎕]

在线尝试!

螺旋矩阵的代码取自我的另一个答案


如果a N为奇数,您的代码会向错误的方向画螺旋线:)
nicael '18年

@nicael已修复(更像是修补程序)。谢谢
Uriel '18


也许我以错误的方式使用输入?
nicael

@nicael啊。好的,我认为现在很好。
Uriel '18


4

Python 2,150个字节

S,N=input()
X=y=n=0
Y=x=c=-1
s=eval(`[[' ']*S]*S`)
exec"if n%S<1:S-=c%2<1;X,Y=-Y,X;c+=1;n=0\nx+=X;y+=Y;s[y][x]='*';n+=1\n"*N
for i in s:print`i`[2::5]

在线尝试!


3

木炭,34字节

NθFE⮌E⊗N∨ι¹÷⁺鬬겫F‹θι≔θι×ι*≧⁻ιθ↷

在线尝试!链接是详细版本的代码。说明:

Nθ

输入N

FE⮌E⊗N∨ι¹÷⁺鬬겫

旋臂(不包括角部)的长度是S-1S-1S-1S-2S-2S-3,..., ,3221,。1 1这是通过从范围到0上限(但不包括在内)开始2S,将0更改为1,将其反转,在第一个元素之后的每个元素加1,最后将所有元素除以2的整数,然后循环遍历。

F‹θι≔θι

如果要绘制的星星少于下一臂的长度,则将臂减小到该长度。

×ι*

绘制适当数量的星星。

≧⁻ιθ

从剩余的星数中减去。

将绘图方向顺时针旋转90°。


3

J,60 56字节

通过修改螺旋的生成过程来获得-4字节,从而无需从y ^ 2减去它

4 :'''* ''{~x<|."1|.(|:@|.,<:@{:@{:-i.@#)^:(+:<:y),.*:y'

在线尝试!

解释即将推出

说明:

4 :'''* ''{~x<|."1|.(|:@|.,<:@{:@{:-i.@#)^:(+:<:y),.*:y'  | Explicit dyad definition
                    (|:@|.,<:@{:@{:-i.@#)^:(+:<:y),.*:y   | Generate a y by y inward spiral
                                                  ,.*:y   | The matrix [[y^2]]
                    (                   )^:(+:<:y)        | 2*(y-1) times...
                     |:@|.                                | Rotate
                          ,                               | Append
                                    i.@#                  | [0..len(n)-1]
                           <:@{:@{:-                      | Subtracted from the previous value and decremented
              |."1|.                                      | Flip around antidiagonal
            x>                                            | Test if each entry is less than x
    '' *''{~                                              | ' ' for 0, '*' for 1

例子:

   3 :'(|:@|.,<:@{:@{:-i.@#)^:(+:<:y),.*:y' 4
7  8  9 10
6 15 16 11
5 14 13 12
4  3  2  1
   3 :'|."1|.(|:@|.,<:@{:@{:-i.@#)^:(+:<:y),.*:y' 4
1  2  3 4
12 13 14 5
11 16 15 6
10  9  8 7
   11(4 :'x<|."1|.(|:@|.,<:@{:@{:-i.@#)^:(+:<:y),.*:y') 4
0 0 0 0
1 1 1 0
0 1 1 0
0 0 0 0
   11(4 :'''* ''{~x<|."1|.(|:@|.,<:@{:@{:-i.@#)^:(+:<:y),.*:y') 4
****
   *
*  *
****

您是否还可以添加指向可执行示例的链接?
nicael

@nicael添加了:)
Bolce Bussiere '18

2

科特林361个 355 353 334字节

乔纳森(Jonathan)节省了6个字节,将
2个字节更改为当
保存19个字节时切换到lambda和跟踪外部边缘

{s:Int,n:Int->var a=Array(s,{_->Array(s,{_->' '})})
var r=0
var c=0
var d=0
var e=0
var f=1
var g=s-1
var h=g
for(i in 1..n){a[r][c]='*'
when(d){0->if(c<g)c++
else{d=1
r++
g--}
1->if(r<h)r++
else{d=2
c--
h--}
2->if(c>e)c--
else{d=3
r--
e++}
3->if(r>f)r--
else{d=0
c++
f++}}}
for(i in 0..s-1){for(j in 0..s-1)print(a[i][j])
println()}}

在线尝试!


1
由于输入字段为空,我不太确定如何尝试。
nicael

1
@nicael这是一个功能。可能更易于使用-调用在页脚中进行。
乔纳森·艾伦

1
我不太了解Kotlin,但相信==' '可以被Kotlin 取代<'*'。也d==0d<1d==3d>2。这些看起来像是非常基础的高尔夫球,所以可能还有其他一些!
乔纳森·艾伦

@nicael,您可以在输入字段中输入两个整数,第一行的大小,第二行的数字。
JohnWells '18年

1
@JohnWells确实有效。某种程度上它太慢了,但是没关系。
nicael '18 -4-1

2

爪哇10,284个 282 281 263字节

s->n->{var c=new char[s][s];for(var d:c)java.util.Arrays.fill(d,' ');for(int i=0,j=0,y=0,x=1,u=s-1,l=0;n-->0;c[j][i]=42,i+=x,j+=y,l+=i==l&x==0?1:0,u-=i==l&j==l&y<1?1:0)if(x!=0){var b=x>0?i<u:i>l;y=b?0:x;x=b?x:0;}else{var b=y>0?j<u:j>l;x=b?0:-y;y=b?y:0;}return c;}

一个有趣的挑战!

在这里在线尝试。

感谢Kevin Cruijssen打高尔夫球18个字节。

非高尔夫版本:

s -> n -> { // lambda taking two integer arguments in currying syntax
    var c = new char[s][s]; // the matrix containing the spiral
    for(var d : c) // for every row
        java.util.Arrays.fill(d, ' '); // fill it with spaces
    for(int i = 0, j = 0, // the coordinates of the next '*'
            y = 0, x = 1, // the direction to move in
            u = s-1, l = 0; // the upper and lower bounds
        n-- > 0; // decrecement the length of the spiral and repeat as many times
        c[j][i] = 42, // draw the '*', 42 is ASCII code
        i += x, j += y, // move to the next cell
        l += i == l & x == 0 ? 1 : 0, // adjust lower bound if necessary
        u -= i == l & j == l & y < 1 ? 1 : 0) // adjust upper bound if necessary
        if(x != 0) { // if moving in x direction
            var b = x > 0 ? i < u : i > l; // if we hit the bounds
            y = b ? 0 : x; // flip directions,
            x = b ? x : 0; // turning around
        } else { // if moving in y direction
            var b = y > 0 ? j < u : j > l; // if we hit the bounds
            x = b ? 0 : -y; // flip directions,
            y = b ? y : 0;  // turning around
        }
    return c; // return the matrix
}

263字节主要更改了最后两个循环,并var b添加了a ,因此您只需执行一次x>0?i<u:i>ly>0?j<u:j>l,而不是每次两次。
凯文·克鲁伊森

@KevinCruijssen非常棒的高尔夫,谢谢!
OOBalance

2

JavaScript(Node.js)167 164 163字节

  • 感谢Outgolfer的@Erik和@nicael的空格(3个字节)
  • 感谢@micha的join``拆分,而不是映射(1字节)
(l,s)=>{a=(b=[...Array(l)]).map(x=>b.map(_=>" "))
for(d=1,x=y=D=0;s--;x+=d,y+=D)a[y][x]="*",(a[y+D]||[])[x+d]!=" "?[d,D]=[-D,d]:0
return a.join`
`.split`,`.join``}

在线尝试!


1
很好,可以用!您可以删除空格/换行符以使其更短吗?
nicael


1
美丽!如果Kotlin和Java版本使用相同的方法,则它们会短很多!这种优雅的检测方式是何时击中螺旋线或边界,然后转动“乌龟”。非常聪明!少一个字节:将return更改为return a.join` `.split`,`.join``
micha

@micha首先谢谢:)。第二个a.join` .split,`.join``不会“很好地”输出螺旋(用新行),所以我认为这是一个问题
DanielIndie

@DanielIndie,换行符已格式化,第一次加入时应具有换行符。看到它
micha
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.