Code Golf:为我打造一条弧线 [英] Code Golf: Build Me an Arc

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

问题描述

挑战

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

  • R是小于等于8的非负十进制数
  • XY 是非负角,以十进制表示,为 45° 的倍数.(04590135等)
  • X 小于 Y
  • 如果 X0,则
  • Y 不是 360

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

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

如果输入无效,程序不需要产生有意义的输出.任何语言的解决方案都是允许的,当然除了专门为此挑战编写的语言,或者不公平地使用外部实用程序的语言.只要输出的格式保持正确,输出中允许存在无关的水平和垂直空格.

打高尔夫球愉快!

大量示例

输入:

0-45 8

输出:

<上一页>//X/xx/xxx/xxxx/xxxxx/xxxxxx/xxxxxxo--------

输入:

0-135 4

输出:

<上一页>xxxxxxxxxxxxxxxxxxxxxxxxxxo----

输入:

180-360 2

输出:

<上一页>--o--xxxxxxxxxx

输入:

45-90 0

输出:

o

输入:

0-315 2

输出:

<上一页>xxxxxxxxxxxxo--xxxxxxx

解决方案

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


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

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


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}


原版评论:

$_=<>;m/(d+)-(d+) (d+)/;$e=$1/45;$f=$2/45;# 解析角度和半径,角度为0-8for$y(-$3..$3){ # 循环每一行和每列$x(-$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",如果是封闭行,则从数组中获取符号# 如果它在封闭角x"之间,否则为空格}$s.=$/;}打印$s;


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

  • 内部 for 循环 -> 映射(1 个字符)
  • 来自 split 字符串的符号数组 -> qw (3 chars)
  • 内联符号数组(6个字符,加上之前改进的9个字符!)
  • 逻辑或 -> 按位或(1 个字符)
  • 正则表达式改进(1 个字符)
  • 受 Jacob 的回答(5 个字符)启发,使用算术测试负角


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

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

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