下雪!


18

您的任务:生成第n个深度的科赫雪花。您无需制作完整的Koch雪花,只需在起始三角形的一侧即可。关于科赫片的维基百科:https : //en.wikipedia.org/wiki/Koch_snowflake

规则:

  • 该程序必须将Koch雪花的一侧生成到第n个深度。
  • 输出必须为ASCII。
  • 可能会生成整个雪花;这不是必需的。
  • 输入/输出,漏洞和内容的标准规则适用。
  • 空格并不重要,只要所有字符之间的相对位置正确即可。
  • 最短的代码胜出!

测试用例:

n = 0:

__

n = 1:

__/\__

n = 2:

      __/\__
      \    /
__/\__/    \__/\__

n = 3:

                        __/\__
                        \    /
                  __/\__/    \__/\__
                  \                /
                  /_              _\
                    \            /
      __/\__      __/            \__      __/\__
      \    /      \                /      \    /
__/\__/    \__/\__/                \__/\__/    \__/\__

我希望这是有道理的。请注意,在每个测试用例中,分形都可以分为三个长度相等的部分。还要注意,每个雪花的宽度是上一代雪花的宽度的三倍。


仅供参考,大家一致认为这不是愚弄的这个
“ SparklePony同志” 17年

我认为您没有适当定义第n条Koch曲线的正确ASCII表示形式。
Orlp

我不确定比例是否合理。非重复使用__/\__两个下划线,使得每次迭代始终是上一个下划线的3倍。仅使用一个下划线似乎会产生矛盾,在n = 3时开始变得非常尴尬。例如,外部部分的宽度为12,而中间部分的宽度仅为10,这是由于的狭窄/__\ 导致的。甚至在此之前,您就已经_扩展到/和的宽度的两倍\
与Orjan约翰森

我认为/_and _\ 是唯一真正致命的部分-下划线需要删除,因为它们必须与/and 处于同一位置\ 。一旦完成,从n = 1开始,事物可以扩展3倍(但n = 0不适合。)
ØrjanJohansen

las,不,中间部分的宽度仍然与外部部分不匹配,n = 3的宽度为52,而不是54 = 2 * 3 ^ 3。尝试的一个这些。我提供了上下颠倒的版本,其中部分仅从n = 4或n = 5出现-它们与下划线掉落的向上版本有所不同。
与Orjan约翰森

Answers:


10

Haskell中308个 300 299字节

编辑:

  • -4字节:改变zipWith(+)zipWith(-)调整编码和偏移整肃每一个否定的标志。
  • -1个字节:进一步调整编码允许#使用r=reverse代替直接模式匹配来删除多个变量名。
  • -2个字节:使用运算符代替alphanum zipWith(-)
  • -1个字节:定义o=[0,0]以缩短列表常量。
  • -1字节:合并的两个分支?
import Data.List
k n=0?sort(o#(f=<<scanl1(+)(iterate(>>=(:[1,4,1]))[6]!!n)))
x?l@(([_,w],c):r)|x>w='\n':0?l|0<1=([2..w-x]>>" ")++[c|w>x]++w?r
_?_=""
w#((c,l):m)=(l&w,c):r l&(l&w)#m
_#_=[]
f x=zip"_/\\_/\\"([id,r]<*>[0:1:o,[0,1,0,1],o++[1,1]])!!mod x 6<$[1,3..gcd 3x]
(&)=zipWith(-)
r=reverse
o=[0,0]

在线尝试!(不幸的是,任何大于n = 3的东西都会被包裹并且难以读取,但是您可以将其复制到另一个程序中以查看它。)

变化

怎么运行的

  • k是主要功能,它需要一个Int n并返回String
  • iterate(>>=(:[1,4,1]))[6]生成一个无限列表,对于每个n,该列表包含该曲线迭代中连续线之间的转弯(乌龟图形样式),名义上为0和之间的数字5。每次迭代只是前一轮,1,4,1交织在一起。子列表开始6而不是的唯一原因0是通过避免来使gcd技巧f起作用f 0
  • scanl1(+)将匝数转换为“绝对”方向,直到模数为6。A 0表示向右,则每个更高的数字都与前一个逆时针方向成60度。(好吧,如果这是一个适当的图形而不是ASCII,那将是60度。)
  • f 将绝对方向转换为(字符,偏移编码)对的列表,该列表对要添加到曲线的字符进行编码(对于水平方向,它生成两对,否则生成一对),以及相对位置如何变化。
  • #通过(字符,偏移编码)对,产生实际的(坐标,字符)对以前的列表操作者进行迭代。
  • 编码原则:
    • 字符从_/\名义上代表从起始角穿过矩形单元格到另一个终止角所画的线。
    • 单元格坐标的格式为[y,x],从上到下,从左到右,以便它们按照我们要打印的顺序排序。列基于1。使用列表代替元组可以缩短向量运算量(&)=zipWith(-)
    • 用与[y,x]单元格左上角相同的坐标表示一个角。这样可确保从角到其相邻像元的所有偏移量均为非负值,从而避免了负常数。
    • 但是,将转角坐标传递为负数,以允许将所有矢量运算减法而不是加法,从而避免了所有其他显式符号。
    • 偏移编码列表是[y1,x1,x2,y2][y1,x1]是从起始角到字符单元格的坐标偏移,[y2,x2]是从结束角到字符单元格的偏移。这表示:
      • 编码列出了方向3.. 5只是用于反向清单的0.. 2,从而允许它们与被生成[id,r]<*>
      • 所有必需的矢量算法都可以通过(&)=zipWith(-)与编码列表或其反向符号结合使用来完成。
  • 在对(坐标,字符)对的列表进行排序之后,将它们传递给?,然后从中生成最终的String对。
    • In x?l@(([_,w],c):r) x是在此行上显示的前一个字符的x坐标,或者0在行的开头;l是整个当前列表,w是要添加的下一个字符的x坐标,c是该字符,并且r是剩余列表。
    • 在此阶段,不再需要y坐标。因为每行都包含字符,并且每行的第一个字符都位于前一个字符的末尾左侧,所以可以通过检查x坐标是否减小来检测新行的开始。
    • 下划线的ASCII值大于\/,因此,如果下划线与相同位置的另一个字符重叠,则下划线会最后排序。因此,通过检查是否重复了x坐标来检测到多余的下划线。

真好!如果今天在这个问题上没有更多活动,我将接受。
SparklePony同志
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.