循环与循环与循环


16

挑战

创建一个函数,当给定ASCII艺术作品的输入(引导可能最终循环的路径)时,该函数将输出循环的长度(如果存在)和“尾部”的长度,而其中的“尾部”将通过以下方式之一进入循环表格如下。


输入值

您的输入必须传递给函数。下面是一个简单输入的示例。

# --> # --> #
      ^     |
      |     |
      |     v
      # <-- #

您可以像这样可视化上面的块

“尾巴”是一个项目,而循环是四个长。

一个更困难的:

            # --> # --> #
            ^           |
            |           |
            |           v
      # --> # <-- #     # --> #
      ^           ^           |
      |           |           |
      |           |           v
# --> #           # <-- # <-- #

输出量

您必须通过STDOUT或您的语言最接近的替代品进行输出。

您的两个输出整数应该是尾部的长度和循环的长度。此输出可以采用两种形式。

  1. 用空格分隔的字符串: "2 10"
  2. 整数数组: [2, 10]

规则

  • 每个块(或#)都只有一条单独的路径

  • 每个箭头是两个线段和一个头。

  • 起始块将始终位于最左列。

  • 输入永远不会只是一个循环。


# --> # --> # --> #
^     ^           |
|     |           |
|     |           v
#     # <-- # <-- #

这条尾巴的长度为2,环圈的长度为6。在下面,尾巴和环圈是分开的。

尾巴

# -->
^
|
|
#

# --> # --> #
^           |
|           |
|           v
# <-- # <-- #

正确的输出是[2, 6]"2 6"

如果输入仅为尾部,则循环长度为零。

# --> # --> # --> #
                  |
                  |
                  v
        <-- # <-- #

上述输入的正确输出是[6, 0]"6 0"


@orlp我认为您在混淆输入和输出。
Sanchises

1
输入中是否可以有更多断开的路径?
xnor 2015年

我认为简介令人困惑。它使我认为问题将与程序分析有关,而与ASCII艺术中的路径查找有关。
xnor

我已经删除了简介。这有点令人困惑/误导。@xnor
扎克·盖茨

Answers:


11

JavaScript的(ES6),221 229

以输入为参数的函数,通过弹出窗口(警报)以字符串形式输出。

重复扫描输入:
每一步

  • 去除尾巴的末端
  • 计算剩余的“#”

当没有更多的尾巴要去除时,到目前为止的步骤数是尾巴的大小,剩余的“#”数是循环的大小。

反引号内的所有换行符都很重要且已计数

在Firefox(不支持Chrome,因为它不支持...)上测试下面的代码段

F=s=>{s=`


${s}


`.split`
`.map(r=>[...r]);for(t=0,f=1;f;)s.map((r,y)=>r.map((c,x)=>c=='#'&&((r[x+2]+r[x-2]+s[y-1][x]+s[y+1][x]).match`[v<>^]`?++l:t+=(f=r[x-4]=r[x+4]=s[y-3][x]=s[y+3][x]=r[x]=1))),f=l=0);alert(t+' '+l)}

// Less golfed
U=s=>{
  s=`\n\n\n${s}\n\n\n`.split`\n`.map(r=>[...r])
  t=0
  do {
    f=l=0
    s.forEach((r,y) => {
      r.forEach((c,x) => {
        if (c == '#')
        {
          if (!(r[x+2] == '<' || r[x-2] == '>' || s[y-1][x] == 'v' || s[y+1][x] == '^'))
            t+=(f=r[x-4]=r[x+4]=s[y-3][x]=s[y+3][x]=r[x]=1)
          else
            ++l
        }
      })
    })
  } while(f)
  alert(t+' '+l)
}  

//Test

// Redefine console.log
alert=(...x)=>O.innerHTML+=x+'\n'

test=[`
# --> # --> #
      ^     |
      |     |
      |     v
      # <-- #`
,`
            # --> # --> #
            ^           |
            |           |
            |           v
      # --> # <-- #     # --> #
      ^           ^           |
      |           |           |
      |           |           v
# --> #           # <-- # <-- #`
,`
# --> # --> # --> #
^     ^           |
|     |           |
|     |           v
#     # <-- # <-- #`      
]

test.forEach(t=>(alert(t),F(t)))
<pre id=O></pre>


...传播操作员正确吗?您可能想这样命名,因为它以其他语法(*:list代表groovy)存在于其他语言(如groovy)中。反正不错的解决方案!
亚伦2015年

1
+1我在想“必须有一个聪明的方法来做到这一点”,想出了这个解决方案,只是向下滚动到这个答案。
Sanchises

8

Ruby,287278字节

->i{n={}
g=->x{n[x]||=[0,p]}
t=y=0
i.lines{|l|x=0
l.chars{|c|x+=1
'><'[c]&&(r=c.ord-61;s,d=[y,x-4*r],[y,x+2*r])
'^v'[c]&&(r=c<?_?1:-1;s,d=[y+r*3,x],[y-r,x])
s&&(g[s][1]=g[d])[0]+=1}
y+=1}
c,*_,s=n.values.sort_by{|v|v[0]}
l=n.size
s[0]>1?((t+=1;c=c[1])while c!=s):t=l-=1
[t,l-t]}

在这里尝试。

这将构建节点的哈希(字典)。对于每个节点,将存储传入连接的数量和(可能为null)下一个节点。

最后:

  • 如果没有带有2个传入连接的节点(表示无循环),则尾部返回0,循环返回现有节点数。
  • 否则,通过next-> ...-> next从具有0个传入连接的节点(开始)开始迭代,直到到达具有2个传入连接的节点(循环开始)。返回适当的计数。

该代码的可读版本在此处提供


2

红宝石276

->s{a=k=w=s.index(r='
')*2+2
s=r*w+s+r*w
(s.size).times{|i|s[i,2]=='
#'&&(s[3+j=i+1]+s[j+w]+s[j-w]).strip.size<2&&(a=[j]
d=0
loop{("|-|-"[d])+?#=~/#{s[k=j+[-w,3,w,-3][d]]}/?(a.include?(k)&&break;a<<(j=k);d-=1):d=(d+1)%4}
)}
u=a.size
v=a.index(k)
t=(u-v)/4*2
print u/2-t," ",t}
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.