代码高尔夫:打造一条弧线 [英] Code Golf: Build Me an Arc

查看:163
本文介绍了代码高尔夫:打造一条弧线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

挑战



字符计数的最短程序,接受 XY R 形式的标准输入,以下担保:


  • R 是一个小于或等于的非负数十进制数至8

  • X Y 作为45°的倍数; ( 0 45 90 ,<$ c $ )

  • X 小于 Y

  • Y 不是 360 if X 0



并且在标准输出上产生从起始角度 X 到半径<$的结束角 Y 的ASCII弧 c $ c> R ,其中:


  • 圆弧的顶点由 o

  • 0 180 表示为 -

  • 45 和<$ c $的角度

  • 90 270 表示为 |

  • code> 135 315 \

  • 由两行包围的多边形区域填充了非空白字符。



如果给定无效输入,程序不需要产生有意义的输出。任何语言的解决方案都是允许的,当然除了专门为这个挑战编写的语言,或者不公平使用外部工具的语言。如果输出的格式保持正确,输出中允许有额外的水平和垂直空格





众多例子



输入:

 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\


解决方案

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

 <>> =〜/  - \\d + /;对于$ Y(@a =  -  $ '.. $'){打印+(映射$ _ | $ Y($ T = 8 *($ Y>!0)+ ATAN2( -  $ Y,$ _)/ atan2 1,1)&  -  $& / 45 == 8 | $ t> = $`/ 45& $ t< =  -  $& / 45?qw( -  / | \\)[$ t%4]:$:o,@ a),$ /} 




使用say功能的Perl, 161 149 139个字符



  $ echo -n'<> =〜/ -\d + /; for $ y(@a =  -  $''''.. $'' ''){说地图$ _ | $ 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 = - $'''..''''' ''){说地图$ _ | $ y?!($ t = 8 *($ y> 0)+ atan2( - $ y,$ _)/ atan2 1,1)& - $& / 45 = = 8 | $ t> = $`/ 45& $ t <= - $& / 45?qw( - / | \\)[$ t%4]:$:o,@ a}'



$ b

新行, 153 <143> chars



 <> =〜/ -\d + /; for $ Y(@a =  -  $ '.. $'){打印$ /,映射$ _ | $ Y($ T = 8 *($ Y>!0)+ ATAN2( -  $ Y,$ _)/ atan2 1,1)&  -  $& / 45 == 8 | $ t> = $`/ 45& $ t <=  -  $& / 45?qw( -  / | \\)[$ t %4]:$:o,@ a} 



原始版本评论:

  $ _ =<> ;; m /(\ d +) - (\ d +)(\\ \\d +)/; $ E = $ 1/45; $ F = $ 2/45; #解析角度和半径,对于$ y( -  $ 3 .. $ 3),角度为0-8 
(每行和每列col为
( - $ 3 .. $ 3){
$ t = atan2( - $ y,$ x)/ atan2 1,1; #此点的角度
$ t + = 8if($ t <0); #规范负角
@ w = split //, - / | \\x2; #用于封闭线条的ASCII符号数组
$ s。=!$ x&&!$ y?o:$ t == $ e || $ t == $ f?$ w [$ t ]:$ t> $ e&& $ t< $ f?x:$;
#如果它是原点 - >o,如果它包含行, b#如果它包围角度x,否则空间
}
$ s。= $ /;
}
print $ s;

$ b 编辑1:内联子,关系和等于运算符返回0或1 。


编辑2:新增评论版。


编辑3:修正了360º的封闭线,Char数量显着增加


编辑4:添加了一个缩短版本,弯曲规则


编辑5:更智能修复360º封闭线,并且使用数字作为填充,这两件事情都很明显,呃,我应该睡更多:/
>
编辑6:删除不需要的 m 来自匹配运算符。删除了一些分号。


编辑7:更智能的正则表达式。 200字以下!


编辑8:很多小改进:



  • 内for循环 - > map(1个字符)

  • 符号数组 split string - > qw(3个字符)
  • $
  • 内联符号数组(6个字符,连同之前的改进9个字符!)
  • 逻辑或 - >按位或(1个字符)

  • 正则表达式改进(1个字符)

  • 使用算术法测试负面角度,受Jacob的答案(5个字符)启发





编辑9:在条件运算符中重新排序可以节省2个字符。


编辑10:使用空白字符。


编辑11:在Lowjacker的答案的启发下,在循环内移动了打印内容。


编辑12:使用添加版本。


编辑13:重复使用填充字符的角度字符,正如Gwell的答案所做的那样。输出不如Gwell's那么好,那需要5个额外的字符:)另外,操作符不需要括号。


编辑14:直接应用regex到<>。根据Adrian对bta答案的建议,将范围运算符分配给一个变量。添加没有最终换行符的版本。更新版本。


编辑15:更多内联。地图{block} @a - >地图表达式,@ a。


Challenge

The shortest program by character count that accepts standard input of the form X-Y R, with the following guarantees:

  • R is a non-negative decimal number less than or equal to 8
  • X and Y are non-negative angles given in decimal as multiples of 45° (0, 45, 90, 135, etc.)
  • X is less than Y
  • Y is not 360 if X is 0

And produces on standard output an ASCII "arc" from the starting angle X to the ending angle Y of radius R, where:

  • The vertex of the arc is represented by o
  • Angles of 0 and 180 are represented by -
  • Angles of 45 and 225 are represented by /
  • Angles of 90 and 270 are represented by |
  • Angles of 135 and 315 are represented by \
  • The polygonal area enclosed by the two lines is filled with a non-whitespace character.

The program is not required to produce meaningful output if given invalid input. Solutions in any language are allowed, except of course a language written specifically for this challenge, or one that makes unfair use of an external utility. Extraneous horizontal and vertical whitespace is allowed in the output provided that the format of the output remains correct.

Happy golfing!

Numerous Examples

Input:

0-45 8

Output:

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

Input:

0-135 4

Output:

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

Input:

180-360 2

Output:

--o--
xxxxx
xxxxx

Input:

45-90 0

Output:

o

Input:

0-315 2

Output:

xxxxx
xxxxx
xxo--
xxx\
xxxx\

解决方案

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

<>=~/-\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),$/}


Perl using say feature, 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}'


Perl without trailing newline, 153 143 chars

<>=~/-\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}


Original version commented:

$_=<>;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;


EDIT 1: Inlined sub, relational and equality operators return 0 or 1.
EDIT 2: Added version with comments.
EDIT 3: Fixed enclosing line at 360º. Char count increased significantly.
EDIT 4: Added a shorter version, bending the rules.
EDIT 5: Smarter fix for the 360º enclosing line. Also, use a number as fill. Both things were obvious. Meh, I should sleep more :/
EDIT 6: Removed unneeded m from match operator. Removed some semicolons.
EDIT 7: Smarter regexp. Under 200 chars!
EDIT 8: Lots of small improvements:

  • Inner for loop -> map (1 char)
  • symbol array from split string -> qw (3 chars)
  • inlined symbol array (6 chars, together with the previous improvement 9 chars!)
  • Logical or -> bitwise or (1 char)
  • Regexp improvement (1 char)
  • Use arithmethic for testing negative angles, inspired by Jacob's answer (5 chars)


EDIT 9: A little reordering in the conditional operators saves 2 chars.
EDIT 10: Use barewords for characters.
EDIT 11: Moved print inside of loop, inspired by Lowjacker's answer.
EDIT 12: Added version using say.
EDIT 13: Reuse angles characters for fill character, as Gwell's answer does. Output isn't as nice as Gwell's though, that would require 5 additional chars :) Also, .. operator doen't need parentheses.
EDIT 14: Apply regex directly to <>. Assign range operator to a variable, as per Adrian's suggestion to bta's answer. Add version without the final newline. Updated say version.
EDIT 15: More inlining. map{block}@a -> map expr,@a.

这篇关于代码高尔夫:打造一条弧线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆