生成ASCII Padovan螺旋


22

这是此挑战的ASCII版本。最初的职位由Martin Ender根据请求分开

介绍

类似于斐波那契数列,Padovan OEIS A000931)是一个数字序列,是通过在序列中添加前项产生的。初始值定义为:

P(0) = P(1) = P(2) = 1

第0,第1和第2项均为1。递归关系如下所示:

P(n) = P(n - 2) + P(n - 3)

因此,它产生以下序列:

1, 1, 1, 2, 2, 3, 4, 5, 7, 9, 12, 16, 21, 28, 37, 49, 65, 86, 114, 151, 200, 265, 351, ...

将这些数字放在一起时,将它们用作等边三角形的边长会产生一个不错的螺旋,就像斐波那契螺旋:

在此处输入图片说明

图片由维基百科提供


任务

您的任务是编写一个程序,用ASCII艺术重新创建此螺旋,并使用与哪个术语相对应的输入。由于边长为1(1个字符)的三角形不可能用ASCII很好地表示,因此边长已被扩大了2倍。因此,边长为1的三角形实际上表示为:

 /\
/__\

因此,例如,如果输入为5(第五项),则输出应为:

   /\
  /  \
 /    \
/______\
\      /\
 \    /__\ 
  \  /\  /
   \/__\/

前五个项分别为1、1、1、2、2,因此由于膨胀,三角形的边长为2、2、2、4、4。输入8的另一个示例:

     __________
   /\          /\
  /  \        /  \
 /    \      /    \
/______\    /      \
\      /\  /        \
 \    /__\/          \
  \  /\  /            \
   \/__\/______________\
    \                  /
     \                /
      \              /
       \            /
        \          /
         \        /
          \      /
           \    /
            \  /
             \/

规则

  • 您必须打印结果,并且输入必须是与术语编号相对应的整数
  • 允许尾随换行符,也允许在行后尾随空格
  • 您提交的内容必须至少能够处理第十个学期(9)
  • 您提交的文件必须是完整的程序或函数,可以接受输入并打印结果
  • 允许以60度的倍数旋转输出,但是三角形的大小以及表示形式必须保持相同
  • 也可以逆时针旋转
  • 禁止出现标准漏洞

您可以假定输入将> 0,并且将给出正确的输入格式。

计分

这是,因此以字节为单位的最短代码获胜。大家新年快乐!


1
我的语言Turtlèd可以接受以10为基数的输入,并且可以很好地进行处理,但是如果将输入设为一进制,则此挑战将容易得多。会被允许吗?
破坏的柠檬

1
@DestructibleWatermelon是的。输入只是必须是某种形式的整数。
安德鲁·李

凉。我会从现在起就可以了
可破坏柠檬

3
等待,实际上还是很困难
Destructible

Answers:


13

Befunge,871个 836 798字节

&00p45*:10p20p030p240p050p060p9010gp9110gp1910gp1-91+10gpv
<v-g03+g06*2g041g055_v#!:%6:p06p05+p04g05g06:g04<p*54+292<
->10g:1\g3+:70p110gv >:5- #v_550g:01-\2*40g+1-30g
/\110:\-g03:\1:g055 _v#!-4:<vp01:-1g01-g03-1\-
^1<v07+1:g07< p08p < >:1-#v_550g:01-\40g+60g+1-30g-50g>v
 _0>p80gp:5-|v1\+66\:p\0\9:$<:p02:+1g02-g03+g06-\g04\1:<
0v|-g00:+1$$<>\p907^>p:!7v>3-#v_550g:30g+:30p1\0\-
1>10g+::0\g3-:70p\0^^07<v<>50#<g::30g+:30p-1-01-\
v >\$0gg> :1+10gg1- #v_^>0g10gg*+\:!2*-70g2+10gv>:#->#,"_"$#1_:1#<p
+1+g03$_^#`gg011+3:+3<g07\+*2+*`0:-\gg01+5g07:g<>1#,-#*:#8>#4_$#:^#
>55+,p30g40p10gg10g1>#v_
#v:#p0$#8_:$#<g!#@_0^ >
 >>:180gg`>>#|_:2+80gg:!v
3+^g\0p08:<vgg08+2::+3<$_100p1-v>g,\80gg+\80gp:2+90g:!01p\80gp
!#^_80g:1+^>\180gg`+!#^_20g80g`
5*g10!g09p04-1-\0\+g04:gg08:p09<^3`0:gg08+1:::$$_1#!-#\\:,#\<g

在线尝试!

与Befunge一样,技巧在于提出一种算法,该算法允许我们从上到下渲染图案,因为在可用空间有限的情况下首先将其渲染到内存中是不可行的。

这种工作方式是首先建立一个简单的数据结构,该结构代表绘制螺旋所需的边缘。然后,第二阶段从上到下解析该结构,呈现输出的每一行所需的边缘片段。

使用此技术,在开始在8位存储单元中出现溢出问题之前,我们最多可以在参考实现中支持n = 15。单元大小较大的解释器在内存用完之前应该能够支持多达n = 25的内容。


令人印象深刻……但是您发现您能够阅读这些程序吗?对我来说,它看起来如此随意。它如何建立数据结构?它使用哪种数据结构?谢谢!
不要亮

1

768字节

func 卷(n int){
    数:=0
    p:=[]int{1,1,1}
    for i:=3;i<n;i++ {p=append(p,p[i-2]+p[i-3])}
    宽:=p[len(p)-1]*10+10
    素:=make([]int,宽*宽)
    for 数=range 素 {素[数]=32}
    for i:=0;i<数;i+=宽 {素[i]=10}
    态:=[]int{1,1,宽/2,宽/2,92}
    表:=[70]int{}
    s:="SRSQTSPQQ!QOQP~QQQQQQSQR~ORQR!OPOPTSQRQ$QPPQNQPPPXQQQQQQRRQXQRRRNOQPQ$"
    for i:=range s {表[i]=int(s[i])-33-48}
    表[49],表[59]=48,48
    for i:=0;i<4*n;i++ {
        梴:=p[i/4]*2
        if 态[1]==0 {梴=梴*2-2}
        for k:=0;k<梴;k++ {
            址:=(态[2]+态[3]*宽)%len(素)
            if 素[址]==32 {素[址]=态[4]}
            态[2]+=态[0]
            态[3]+=态[1]
        }
        数=((态[0]+1)*2+态[1]+1)*5
        if i%4>2 {数+=35}
        for k:=0;k<5;k++ {态[k]+=表[数+k]}
    }
    for i:=0;i<宽*宽;i++ {fmt.Printf("%c",rune(素[i]))}
}

这当然不是最佳选择,但这并不是一个不好的开始。我知道这对于高尔夫标准来说可能有点简单,但是这很有趣,我希望如果我给未来的自我留下一些笔记,也不要介意。

怎么运行的

基本上,我在ASCII像素网格上模拟LOGO中的“绘图乌龟”,但是乌龟只能执行以下三个命令:

rt   - right turn, turn 120 degrees right (1/3 of a Turn)
rth  - right turn half, turn  60 degrees right (1/6 of a Turn)
fd n - forward, go forward n steps, drawing a trail of _, /, or \

现在,对于每个三角形,我都是这样的,其中P是第n个Padovan数的2倍:

fd P
rt
fd P
rt 
fd P
rt
fd P
rth

第四个“ fd”表示我正在重新绘制每个三角形的第一边。这有助于回到下一个三角形的理想起点。右转一半可确保下一个三角形处于正确的方向。


为了打乌龟,我在阵列状态中存储了5个状态变量:x位置,y位置,x速度,y速度和“绘图符文”。在每个动画帧处,x + = x速度,y + = y速度,并绘制符文。

然后,我设置了表格表,该表格说明了如何实际执行转弯。由于ASCII艺术的工作方式,因此转码非常棘手。这不是像像素显示器那样简单的动作。由x和y速度确定的乌龟方向决定了使转弯看起来正确所需的更改。

首先,它查看当前的x和y速度,并将它们组合为一个索引。

xv = x velocity, yv = y velocity. 
i.e. a turtle facing down and to the right has 
xv of 1, and yv of 1. It can only face 6 
different directions. Formula is (xv+1)*2+yv+1

xv  yv    index
-1  -1    0
-1   0    1
-1   1    2
 1  -1    4
 1   0    5
 1   1    6

该索引用于在表表中查找5个值的集合。然后将表表中的这5个值添加到状态状态的5个变量中的每个变量上。然后有效地转动乌龟,为下一个“ FD”做准备。

对于第r个路,右转弯的一半,表表格的单独部分。从表中的第一个表开始,它偏移了7 * 5或35个条目。

最后,我对表的整数进行了一些简单的编码,将其编码为ascii字符串。

我知道我可以通过删除Hanzi来“保存字节”,但是就像我说的那样,这不是最佳选择,而且还有更多的打高尔夫球的可能。如果没有其他可能的优化方法,我将删除它们。这些汉字实际上是根据它们的实际含义来定义的,即使我不懂中文,也可以帮助我考虑该程序。

数  index number
宽  screen width
素  pixel data
梴  length of side of triangle
态  current state
址  address of pixel
表  state transition table

要测试代码,您将需要带有此标头的完整golang文件

package main
import "fmt"

这个页脚

func main ()  {
    for i := 0; i<15; i++ {
       卷(i)
    }
}

谢谢

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.