Language agnostic 代码高尔夫:复活节螺旋

Language agnostic 代码高尔夫:复活节螺旋,language-agnostic,code-golf,rosetta-stone,spiral,Language Agnostic,Code Golf,Rosetta Stone,Spiral,对于复活节代码高尔夫训练,有什么比螺旋形更合适好吧,我想几乎什么都可以 挑战 按字符数计算的最短代码,用于显示由星号(“*”)组成的漂亮ASCII螺旋线 输入为单个数字,R,即螺旋的x尺寸。另一个维度(y)总是R-2。程序可以假定R总是奇数且>=5 一些例子: Input 7 Output ******* * * * *** * * * * ***** * Input 9 Output ********* * *

对于复活节代码高尔夫训练,有什么比螺旋形更合适
好吧,我想几乎什么都可以

挑战 按字符数计算的最短代码,用于显示由星号(“*”)组成的漂亮ASCII螺旋线

输入为单个数字,
R
,即螺旋的x尺寸。另一个维度(y)总是
R-2
。程序可以假定
R
总是奇数且>=5

一些例子:

Input
    7
Output

*******
*     *
* *** *
*   * *
***** *                   

Input
    9
Output

*********
*       *
* ***** *
* *   * *
* *** * *
*     * *
******* *

Input
   11
Output

***********
*         *
* ******* *
* *     * *
* * *** * *
* *   * * *
* ***** * *
*       * *
********* *
代码计数包括输入/输出(即完整程序)。 任何语言都是允许的

我的易于击败的303个字符长的Python示例:

import sys;
d=int(sys.argv[1]);
a=[d*[' '] for i in range(d-2)];
r=[0,-1,0,1];
x=d-1;y=x-2;z=0;pz=d-2;v=2;
while d>2:
    while v>0:
        while pz>0:
            a[y][x]='*';
            pz-=1;
            if pz>0:
                x+=r[z];
                y+=r[(z+1)%4];
        z=(z+1)%4; pz=d; v-=1;
    v=2;d-=2;pz=d;
for w in a:
    print ''.join(w);
现在,进入螺旋…

Java 328个字符

class S{
public static void main(String[]a){
int n=Integer.parseInt(a[0]),i=n*(n-2)/2-1,j=0,t=2,k;
char[]c=new char[n*n];
java.util.Arrays.fill(c,' ');
int[]d={1,n,-1,-n};
if(n/2%2==0){j=2;i+=1+n;}
c[i]='*';
while(t<n){
for(k=0;k<t;k++)c[i+=d[j]]='*';
j=(j+1)%4;
if(j%2==0)t+=2;
}
for(i=0;i<n-2;i++)System.out.println(new String(c,i*n,n));
}
}
S类{
公共静态void main(字符串[]a){
intn=Integer.parseInt(a[0]),i=n*(n-2)/2-1,j=0,t=2,k;
char[]c=新字符[n*n];
java.util.Arrays.fill(c');
int[]d={1,n,-1,-n};
如果(n/2%2==0){j=2;i+=1+n;}
c[i]='*';
while(tPython:238-221-209个字符
欢迎所有评论:

d=input();r=range
a=[[' ']*d for i in r(d-2)]
x=y=d/4*2
s=d%4-2
for e in r(3,d+1,2):
 for j in r(y,y+s*e-s,s):a[x][j]='*';y+=s
 for j in r(x,x+s*e-(e==d)-s,s):a[j][y]='*';x+=s
 s=-s
for l in a:print''.join(l)
Python(2.6):156个字符 感谢您的评论。我已经删除了多余的空格并使用了input()。我仍然喜欢在命令行上获取参数的程序,因此这里有一个版本仍然使用sys.argv,共176个字符:

import sys
r=int(sys.argv[1])
def p(r,s):x=(i+1)/2;print "* "*x+("*" if~i%2 else" ")*(r-4*x)+" *"*x+s
for i in range(r/2):p(r,"")
for i in range((r-1)/2-1)[::-1]:p(r-2," *")
解释 取螺旋,将其切成几乎相等的两部分,顶部和底部,顶部一行比底部大:

***********
*         *
* ******* *
* *     * *
* * *** * *

* *   * * *
* ***** * *
*       * *
********* *

观察顶部是对称的,观察底部有一个垂直的线,在右边,但是非常类似于顶部。注意每一个第二行的图案:两边都有越来越多的星星。有星星的区域

函数p(r,s)打印出宽度为r的螺旋顶部的第i行,并在末尾粘贴后缀s。请注意,i是一个全局变量,尽管它可能不明显!当i为偶数时,它会在行中间填充空格,否则会填充星星。(为了得到i%2==0的效果,~i%2是一种令人讨厌的方法,但实际上根本没有必要,因为我应该简单地交换“*”和“.”)我们首先用增加的i绘制螺旋的顶行,然后用减少的i绘制底行。我们将r降低2,后缀为“*”要获得右边的星星列。

Groovy,373 295 257 243个字符 尝试了一种递归的方法,从最外部的开始到内部建立正方形。我使用了Groovy

等等

r=args[0] as int;o=r+1;c='*'
t=new StringBuffer('\n'*(r*r-r-2))
e(r,0)
def y(){c=c==' '?'*':' '}
def e(s,p){if (s==3)t[o*p+p..o*p+p+2]=c*s else{l=o*(p+s-3)+p+s-2;(p+0..<p+s-2).each{t[o*it+p..<o*it+p+s]=c*s};y();t[l..l]=c;e(s-2,p+1)}}
println t
r=args[0]作为int;o=r+1;c='*'
t=新的StringBuffer('\n'*(r*r-r-2))
e(r,0)
定义y(){c=c=''?'*'':'''}
def e(s,p){if(s==3)t[o*p+p..o*p+p+2]=c*s else{l=o*(p+s-3)+p+s-2;(p+0..F#,267个字符)
很多答案都是从空格开始,然后加上
*
s,但我认为从一个星域开始并加上空格可能更容易

let n=int(System.Console.ReadLine())-2
let mutable x,y,d,A=n,n,[|1;0;-1;0|],
 Array.init(n)(fun _->System.Text.StringBuilder(String.replicate(n+2)"*"))
for i=1 to n do for j=1 to(n-i+1)-i%2 do x<-x+d.[i%4];y<-y+d.[(i+1)%4];A.[y].[x]<-' '
Seq.iter(printfn"%O")A
好的,我明白了。第一个程序:

let Main() =
    let n=int(System.Console.ReadLine())
    let A=Array2D.create(n-2)n '*'
    let mutable x,y,z,i=n-2,n-2,0,n-2
    let d=[|0,-1;-1,0;0,1;1,0|]  // TODO
    while i>0 do
     for j in 1..i-(if i%2=1 then 1 else 0)do
      x<-x+fst d.[z]
      y<-y+snd d.[z]
      A.[y,x]<-'0'+char j
     z<-(z+1)%4
     i<-i-1
    printfn"%A"A
Main()
好,现在让我们将元组数组更改为int数组:

let n=int(System.Console.ReadLine())-2
let mutable x,y,z,i,d=n,n,0,n,[|0;-1;0;1;0|]
let A=Array.init(n)(fun _->System.Text.StringBuilder(String.replicate(n+2)"*"))
while i>0 do
 for j in 1..i-i%2 do x<-x+d.[z];y<-y+d.[z+1];A.[y].[x]<-' '
 z<-(z+1)%4;i<-i-1
A|>Seq.iter(printfn"%O")
downto
很长,请重新计算,以便我可以在循环中(向上)

let n=int(System.Console.ReadLine())-2
let mutable x,y,d,A=n,n,[|1;0;-1;0|],
 Array.init(n)(fun _->System.Text.StringBuilder(String.replicate(n+2)"*"))
for i=1 to n do for j in 1..(n-i+1)-i%2 do x<-x+d.[i%4];y<-y+d.[(i+1)%4];A.[y].[x]<-' '
Seq.iter(printfn"%O")A
let n=int(System.Console.ReadLine())-2
设可变x,y,d,A=n,n,[| 1;0;-1;0 |],
Array.init(n)(fun->System.Text.StringBuilder(String.replicate(n+2)“*”))
对于i=1到n do,对于j在1..(n-i+1)-i%2 do xRuby,237个字符
我是高尔夫新手,所以我有点不对劲,但我想我应该试试看

x=ARGV[0].to_i
y=x-2
s,h,j,g=' ',x-1,y-1,Array.new(y){Array.new(x,'*')}
(1..x/2+2).step(2){|d|(d..y-d).each{|i|g[i][h-d]=s}
(d..h-d).each{|i|g[d][i]=s}
(d..j-d).each{|i|g[i][d]=s}
(d..h-d-2).each{|i|g[j-d][i]=s}}
g.each{|r|print r;puts}

Java,265250 245 240个字符 我没有预先分配一个矩形缓冲区并填充它,而是在x/y坐标上循环并输出当前位置的“*”或“”。为此,我们需要一个算法,可以评估任意点是否在螺旋上。我使用的算法是基于观察到螺旋相当于一个集合对于同心正方形,除了沿着特定对角线出现的一组位置外;这些位置需要校正(必须反转)

有些可读的版本:

public class Spr2 {

  public static void main(String[] args) {
    int n = Integer.parseInt(args[0]);
    int cy = (n - 5) / 4 * 2 + 1;
    int cx = cy + 2;
    for (int y = n - 3; y >= 0; y--) {
      for (int x = 0; x < n; x++) {
        int dx = cx - x;
        int dy = cy - y;
        int adx = Math.abs(dx);
        int ady = Math.abs(dy);
        boolean c = (dx > 0 && dx == dy + 1);
        boolean b = ((adx % 2 == 1 && ady <= adx) || (ady % 2 == 1 && adx <= ady)) ^ c;
        System.out.print(b ? '*' : ' ');
      }
      System.out.println();
    }
  }

}
优化了0.265个字符:

public class S{
public static void main(String[]a){
int n=Integer.parseInt(a[0]),c=(n-5)/4*2+1,d=c+2,e,f,g,h,x,y;
for(y=0;y<n-2;y++){
for(x=0;x<=n;x++){
e=d-x;f=c-y;g=e>0?e:-e;h=f>0?f:-f;
System.out.print(x==n?'\n':(g%2==1&&h<=g||h%2==1&&g<=h)^(e>0&&e==f+1)?'*':' ');
}}}}
公共类S{
公共静态void main(字符串[]a){
intn=Integer.parseInt(a[0]),c=(n-5)/4*2+1,d=c+2,e,f,g,h,x,y;
对于(y=0;y0?f:-f;
System.out.print(x==n?'\n':(g%2==1&&hC#,29262255个字符)
简单方法:从外到内逐行绘制螺旋线

using C=System.Console;class P{static void Main(string[]a){int A=
1,d=1,X=int.Parse(a[0]),Y=X-2,l=X,t=0,i,z;while(l>2){d*=A=-A;l=l<
4?4:l;for(i=1;i<(A<0?l-2:l);i++){C.SetCursorPosition(X,Y);C.Write
("*");z=A<0?Y+=d:X+=d;}if(t++>1||l<5){l-=2;t=1;}}C.Read();}}
使用C=System.Console;类P{static void Main(string[]a){int a=
1,d=1,X=int.Parse(a[0]),Y=X-2,l=X,t=0,i,z;而(l>2){d*=a=-a;l=l<
4?4:l;对于(i=1;iOCaml,299个字符)

这里有一个OCaml解决方案,不是最短的,但我相信它是可读的

它仅使用字符串操作,即可以通过镜像上一个螺旋来构建螺旋

假设从n=5开始:

55555
5   5
555 5
现在n=7:

7777777
7     7
5 555 7
5   5 7
55555 7
你看到5个人都去哪了吗

以下是仅使用OCaml提供的有限库的未模糊代码:

(* The standard library lacks a function to reverse a string *)
let rev s =
  let n = String.length s - 1 in
  let r = String.create (n + 1) in
    for i = 0 to n do
      r.[i] <- s.[n - i]
    done;
    r
;;

let rec f n =
  if n = 5 then
    [
      "*****";
      "*   *";
      "*** *"
    ]
  else
    [
      String.make n '*';
      "*" ^ (String.make (n - 2) ' ') ^ "*"
    ] @ ( 
      List.rev_map (fun s -> (rev s) ^ " *") (f (n - 2))
    )
;;

let p n =
  List.iter print_endline (f n)
;;

let () = p (read_int ());;
(*标准库缺少反转字符串的函数*)
让我们=
设n=String.length s-1英寸
设r=String.create(n+1)in
对于i=0到n do
r、 [i](修订本s)^“*”(f(n-2))
)
;;
让p n=
List.iter打印结束行(f n)
;;
设()=p(read_int());;
以下是长度为299个字符的模糊版本:

open String
let rev s=
  let n=length s-1 in
  let r=create(n+1)in
    for i=0 to n do r.[i]<-s.[n-i]done;r
let rec f n=
  if n=5 then["*****";"*   *";"*** *"]else
    [make n '*';"*"^(make (n-2) ' ')^"*"]
    @(List.rev_map(fun s->(rev s)^" *")(f(n-2)));;
List.iter print_endline (f(read_int ()))
打开字符串
让我们=
设n=长度s-1英寸
设r=in中创建(n+1)
对于i=0到n的情况,则[i](修订本s)^“*”(f(n-2));;
List.iter print\u endline(f(read\u int())
Ruby(1.9.2)-126
f=->s{使用
Integer.parseInt(args[0])
可以节省几个字节。OP的示例是从传递的参数中获取参数,而不是轮询用户输入。还可以将
args
重命名为
a
;)@friol必须有人做脏活;)但说真的,我只是想知道Java与其他语言相比会如何。很难说清楚,因为当我通过
wc-c yourcode.py
运行您的示例时,大多数答案都遵循自己的算法(这是典型的-代码-难以理解),我得到了357个字符计数。christophed,您在计算空格吗?Signif
public class Spr2 {

  public static void main(String[] args) {
    int n = Integer.parseInt(args[0]);
    int cy = (n - 5) / 4 * 2 + 1;
    int cx = cy + 2;
    for (int y = n - 3; y >= 0; y--) {
      for (int x = 0; x < n; x++) {
        int dx = cx - x;
        int dy = cy - y;
        int adx = Math.abs(dx);
        int ady = Math.abs(dy);
        boolean c = (dx > 0 && dx == dy + 1);
        boolean b = ((adx % 2 == 1 && ady <= adx) || (ady % 2 == 1 && adx <= ady)) ^ c;
        System.out.print(b ? '*' : ' ');
      }
      System.out.println();
    }
  }

}
cx,cy = center
dx,dy = delta from center
adx,ady = abs(delta from center)
c = correction factor (whether to invert)
b = the evaluation
public class S{
public static void main(String[]a){
int n=Integer.parseInt(a[0]),c=(n-5)/4*2+1,d=c+2,e,f,g,h,x,y;
for(y=0;y<n-2;y++){
for(x=0;x<=n;x++){
e=d-x;f=c-y;g=e>0?e:-e;h=f>0?f:-f;
System.out.print(x==n?'\n':(g%2==1&&h<=g||h%2==1&&g<=h)^(e>0&&e==f+1)?'*':' ');
}}}}
class S{
public static void main(String[]a){
int n=Integer.parseInt(a[0]),c=(n-5)/4*2+1,d=c+2,g,h,x,y;
for(y=-c;y<n-2-c;y++){
for(x=-d;x<=n-d;x++){
g=x>0?x:-x;h=y>0?y:-y;
System.out.print(x==n-d?'\n':(g%2==1&&h<=g||h%2==1&&g<=h)^(x<0&&x==y-1)?'*':' ');
}}}}
class S{
public static void main(String[]a){
int n=Integer.parseInt(a[0]),c=(n-5)/4*2+1,d=c+2,g,h,x,y=-c;
for(;y<n-2-c;y++){
for(x=-d;x<=n-d;x++){
g=x>0?x:-x;h=y>0?y:-y;
System.out.print(x==n-d?'\n':(g%2==1&h<=g|h%2==1&g<=h)^(x<0&x==y-1)?'*':' ');
}}}}
class S{
public static void main(String[]a){
int n=Byte.decode(a[0]),c=(n-5)/4*2+1,d=c+2,g,h,x,y=-c;
for(;y<n-2-c;y++){
for(x=-d;x<=n-d;x++){
g=x>0?x:-x;h=y>0?y:-y;
System.out.print(x==n-d?'\n':(g%2==1&h<=g|h%2==1&g<=h)^(x<0&x==y-1)?'*':' ');
}}}}
using C=System.Console;class P{static void Main(string[]a){int A=
1,d=1,X=int.Parse(a[0]),Y=X-2,l=X,t=0,i,z;while(l>2){d*=A=-A;l=l<
4?4:l;for(i=1;i<(A<0?l-2:l);i++){C.SetCursorPosition(X,Y);C.Write
("*");z=A<0?Y+=d:X+=d;}if(t++>1||l<5){l-=2;t=1;}}C.Read();}}
55555
5   5
555 5
7777777
7     7
5 555 7
5   5 7
55555 7
(* The standard library lacks a function to reverse a string *)
let rev s =
  let n = String.length s - 1 in
  let r = String.create (n + 1) in
    for i = 0 to n do
      r.[i] <- s.[n - i]
    done;
    r
;;

let rec f n =
  if n = 5 then
    [
      "*****";
      "*   *";
      "*** *"
    ]
  else
    [
      String.make n '*';
      "*" ^ (String.make (n - 2) ' ') ^ "*"
    ] @ ( 
      List.rev_map (fun s -> (rev s) ^ " *") (f (n - 2))
    )
;;

let p n =
  List.iter print_endline (f n)
;;

let () = p (read_int ());;
open String
let rev s=
  let n=length s-1 in
  let r=create(n+1)in
    for i=0 to n do r.[i]<-s.[n-i]done;r
let rec f n=
  if n=5 then["*****";"*   *";"*** *"]else
    [make n '*';"*"^(make (n-2) ' ')^"*"]
    @(List.rev_map(fun s->(rev s)^" *")(f(n-2)));;
List.iter print_endline (f(read_int ()))
f=->s{s<0?[]:(z=?**s;[" "*s]+(s<2?[]:[z]+f[s-4]<<?*.rjust(s))).map{|i|"* #{i} *"}<<z+"** *"}
s=gets.to_i;puts [?**s]+f[s-4]