Code Golf:让我成为一个弧

Jon*_*rdy 20 language-agnostic geometry code-golf rosetta-stone

挑战

按字符数计算的最短程序,接受表单的标准输入X-Y R,具有以下保证:

  • R 是小于或等于8的非负十进制数
  • XY是在十进制给定为45°的倍数(非负角度0,45,90,135,等等)
  • X 小于 Y
  • Y不是,360如果X0

并在标准输出上生成从起始角度XY半径结束角度的ASCII"弧" R,其中:

  • 弧的顶点用.表示 o
  • 的角度0180由下式表示-
  • 的角度45225由下式表示/
  • 的角度90270由下式表示|
  • 的角度135315由下式表示\
  • 由两条线包围的多边形区域填充有非空白字符.

如果给出无效输入,则程序不需要产生有意义的输出.允许使用任何语言的解决方案,当然除了专门针对此挑战而编写的语言,或者不公平地使用外部实用程序的语言.外来的水平和垂直空白允许在提供的输出的格式保持正确的输出.

开心打高尔夫!

众多例子

输入:

0-45 8

输出:

        /
       /x
      /xx
     /xxx
    /xxxx
   /xxxxx
  /xxxxxx
 /xxxxxxx
o--------

输入:

0-135 4

输出:

\xxxxxxxx
 \xxxxxxx
  \xxxxxx
   \xxxxx
    o----

输入:

180-360 2

输出:

--o--
xxxxx
xxxxx

输入:

45-90 0

输出:

o

输入:

0-315 2

输出:

xxxxx
xxxxx
xxo--
xxx\
xxxx\

nin*_*alj 15

Perl,235 211 225 211 207 196 179 177 175 168 160 156 146字符

<>=~/-\d+/;for$y(@a=-$'..$'){print+(map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,@a),$/}
Run Code Online (Sandbox Code Playgroud)


Perl使用say功能,161 149 139 chars

$ echo -n '<>=~/-\d+/;for$y(@a=-$'"'"'..$'"'"'){say map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,@a}' | wc -c
139
$ perl -E '<>=~/-\d+/;for$y(@a=-$'"'"'..$'"'"'){say map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,@a}'
Run Code Online (Sandbox Code Playgroud)


Perl没有尾随换行符,153 143个字符

<>=~/-\d+/;for$y(@a=-$'..$'){print$/,map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,@a}
Run Code Online (Sandbox Code Playgroud)


原版评论:

$_=<>;m/(\d+)-(\d+) (\d+)/;$e=$1/45;$f=$2/45; # parse angles and radius, angles are 0-8
for$y(-$3..$3){                               # loop for each row and col
    for$x(-$3..$3){
            $t=atan2(-$y,$x)/atan2 1,1;   # angle of this point
            $t+=8if($t<0);                # normalize negative angles
            @w=split//,"-/|\\"x2;         # array of ASCII symbols for enclosing lines
            $s.=!$x&&!$y?"o":$t==$e||$t==$f?$w[$t]:$t>$e&&$t<$f?"x":$";
            # if it's origin -> "o", if it's enclosing line, get symbol from array
            # if it's between enclosing angles "x", otherwise space
    }
    $s.=$/;
}
print$s;
Run Code Online (Sandbox Code Playgroud)


编辑1:内联子,关系和相等运算符返回0或1.
编辑2:添加带注释的版本.
编辑3:固定封闭线在360º.字数显着增加.
编辑4:添加了更短的版本,弯曲规则.
编辑5: 360º封闭线的智能修复.另外,使用数字作为填充.这两件事都很明显.嗯,我应该睡得更多:/
编辑6:m从匹配运算符中删除不需要的东西.删除了一些分号.
编辑7:更聪明的正则表达式.不到200个字符!
编辑8:很多小的改进:

  • 内循环 - >地图(1个字符)
  • split字符串中的符号数组- > qw(3个字符)
  • 内联符号数组(6个字符,以及之前的改进9个字符!)
  • 逻辑或 - >按位或(1个字符)
  • Regexp改进(1个字符)
  • 使用arithmethic测试负角度,灵感来自雅各布的答案(5个字符)


编辑9:在条件运算符中稍微重新排序可以节省2个字符.
编辑10:对字符使用裸字.
编辑11:在Lowjacker的答案的启发下,在循环内部移动了打印.
编辑12:使用添加版本say.
编辑13:重复使用填充字符的角度字符,正如Gwell的答案所做的那样.输出不如Gwell那么好,这将需要5个额外的字符:)此外,..运算符不需要括号.
编辑14:将正则表达式直接应用于<>.根据Adrian对bta答案的建议,将范围运算符分配给变量.添加没有最终换行符的版本.更新say版本.
编辑15:更多内联.map {block} @a - > map expr,@ a.


gwe*_*ell 12

Lua,259个字符

略微滥用该non-whitespace character条款以产生令人眼花缭乱的显示,更重要的是保存笔画.

m=math i=io.read():gmatch("%d+")a=i()/45 b=i()/45 r=i()for y=r,-r,-1 do for x=-r,r do c=m.atan2(y,x)/m.pi*4 c=c<0 and c+8 or c k=1+m.modf(c+.5)io.write(x==0 and y==0 and'o'or c>=a and c<=b and('-/|\\-/|\\-'):sub(k,k)or c==0 and b==8 and'-'or' ')end print()end
Run Code Online (Sandbox Code Playgroud)

输入: 45-360 4

\\\|||///
\\\|||// 
\\\\|//  
--\\|/   
----o----
--//|\\--
////|\\\\
///|||\\\
///|||\\\

能够处理奇怪的角度

输入: 15-75 8

           |/////
          |//////
          |//////
          |//////
          ///////
         |//////-
         ////--- 
         //-     
        o        









Jac*_*cob 8

MATLAB,188个字符:)

input '';[w x r]=strread(ans,'%d-%d%d');l='-/|\-/|\-';[X Y]=meshgrid(-r:r);T=atan2(-Y,X)/pi*180;T=T+(T<=0)*360;T(T>w&T<x)=-42;T(T==w)=-l(1+w/45);T(T==x)=-l(1+x/45);T(r+1,r+1)=-'o';char(-T)

评论代码:

%%# Get the string variable (enclose in quotes, e.g. '45-315 4')
input ''
%%# Extract angles and length
[w x r]=strread(ans,'%d-%d%d');
%%# Store characters
l='-/|\-/|\-';
%%# Create the grid
[X Y]=meshgrid(-r:r);
%%# Compute the angles in degrees
T=atan2(-Y,X)/pi*180;
%%# Get all the angles
T=T+(T<=0)*360;
%# Negative numbers indicate valid characters
%%# Add the characters
T(T>w&T<x)=-42;
T(T==w)=-l(1+w/45);
T(T==x)=-l(1+x/45);
%%# Add the origin
T(r+1,r+1)=-'o';
%%# Display
char(-T)
Run Code Online (Sandbox Code Playgroud)

  • 现在我想知道为什么在MATLAB中没有更多的高尔夫球. (2认同)
  • 如果使用大写'O'而不是小'o',你可以保存一个额外的字符:`T(r + 1,r + 1)= - 79` (2认同)

Dr.*_*ius 8

Mathematica 100 Chars

出于竞争,因为图形太完美了:)

  f[x_-y_ z_]:=Graphics@Table[
                 {EdgeForm@Red,Disk[{0,0},r,{x °,y °}],{r,z,1,-1}]
                 SetAttributes[f,HoldAll]
Run Code Online (Sandbox Code Playgroud)

用f [30-70 5]调用

结果

alt text http://a.imageshack.us/img80/4294/angulosgolf.png

alt text http://a.imageshack.us/img59/7892/angulos2.png

注意

SetAttributes [f,HoldAll];

需要因为输入

    f[a-b c] 
Run Code Online (Sandbox Code Playgroud)

否则被解释为

    f[(a-b*c)]
Run Code Online (Sandbox Code Playgroud)


nin*_*alj 7

GNU BC,339个字符

GNU BC因为read(),else和逻辑运算符.

scale=A
a=read()/45
b=read()/45
c=read()
for(y=c;y>=-c;y--){for(x=-c;x<=c;x++){if(x==0)if(y<0)t=-2else t=2else if(x>0)t=a(y/x)/a(1)else if(y<0)t=a(y/x)/a(1)-4else t=a(y/x)/a(1)+4
if(y<0)t+=8
if(x||y)if(t==a||t==b||t==b-8){scale=0;u=(t%4);scale=A;if(u==0)"-";if(u==1)"/";if(u==2)"|";if(u==3)"\"}else if(t>a&&t<b)"x"else" "else"o"};"
"}
quit
Run Code Online (Sandbox Code Playgroud)


gno*_*ice 7

MATLAB 7.8.0(R2009a) - 168 163 162个字符

雅各布的答案开始,灵感来自gwell使用任何非空白字符来填补弧线,我设法得到以下解决方案:

[w x r]=strread(input('','s'),'%d-%d%d');
l='o -/|\-/|\-';
X=meshgrid(-r:r);
T=atan2(-X',X)*180/pi;
T=T+(T<=-~w)*360;
T(T>x|T<w)=-1;
T(r+1,r+1)=-90;
disp(l(fix(3+T/45)))
Run Code Online (Sandbox Code Playgroud)

还有一些测试输出:

>> arc
0-135 4
\||||////
 \|||///-
  \||//--
   \|/---
    o----
Run Code Online (Sandbox Code Playgroud)

我可以通过删除调用将其进一步减少到156个字符disp,但这会ans =在输出之前添加额外的内容(这可能违反输出格式规则).

即便如此,我觉得有一些方法可以进一步减少这种情况.;)


bta*_*bta 6

Ruby,292 276 186字符

x,y,r=gets.scan(/\d+/).map{|z|z.to_i};s=(-r..r);s.each{|a|s.each{|b|g=Math::atan2(-a,b)/Math::PI*180/1%360;print a|b==0?'o':g==x||g==y%360?'-/|\\'[g/45%4].chr: (x..y)===g ?'*':' '};puts}
Run Code Online (Sandbox Code Playgroud)

更加格式化的版本:

x, y, r = gets.scan(/\d+/).map{|z| z.to_i}
s = (-r..r)
s.each {|a|
    s.each {|b|
        g = (((Math::atan2(-a,b) / Math::PI) * 180) / 1) % 360
        print ((a | b) == 0) ? 'o' :
            (g == x || g == (y % 360)) ? '-/|\\'[(g / 45) % 4].chr :
                ((x..y) === g) ? '*' : ' '
    }
    puts
}
Run Code Online (Sandbox Code Playgroud)

我相信那些比我更多睡眠的人可以更加凝聚......

编辑1:if内部循环中的切换语句到嵌套? :操作符

编辑2:存储范围到中间变量(感谢Adrian),使用stdin代替CLI params(感谢澄清Jon),消除了数组,支持直接输出,修复了bug,其中360的结束角度不显示一条线,删除了一些不需要的括号,使用除法舍入代替.round,使用modulo而不是条件add