Loops e Loops e Loops

16

O desafio

Crie uma função que, quando recebida uma entrada da arte ASCII (direcionando um caminho que possa eventualmente fazer um loop), produza o comprimento do loop (se houver) e o comprimento da "cauda" que leva ao loop em um dos formulários abaixo.


Entrada

Sua entrada deve ser passada para uma função. Abaixo está um exemplo de uma entrada simples.

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

Você pode visualizar os blocos acima como este

A "cauda" é um item, enquanto o loop tem quatro longos.

Um mais difícil:

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

Resultado

Você deve enviar pelo STDOUT ou a alternativa mais próxima do seu idioma.

Seus dois números inteiros de saída devem ser o comprimento da cauda e o comprimento do loop. Esta saída pode estar em duas formas.

  1. uma sequência delimitada por espaço: "2 10"
  2. uma matriz de números inteiros: [2, 10]

Regras

  • Cada bloco, ou #, terá apenas um único caminho de distância .

  • Cada flecha tem dois segmentos de linha e uma cabeça.

  • O bloco inicial estará sempre na coluna mais à esquerda.

  • A entrada nunca será apenas um loop.


Exemplo

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

Este tem um comprimento de cauda de 2 e um comprimento de loop de 6. Abaixo, o rabo e o loop são separados.

Rabo

# -->
^
|
|
#

Ciclo

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

As saídas corretas são [2, 6]e "2 6".

Se a entrada for apenas uma cauda , o comprimento do loop será zero.

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

As saídas corretas para a entrada acima são [6, 0]e"6 0"

Zach Gates
fonte
@ orlp Acho que você está confundindo entrada e saída.
Sanchises 17/09/2015
11
A entrada pode ter partes extras de caminho desconectadas?
xnor
Eu acho que a introdução é confusa. Isso me faz pensar que o problema será sobre análise de programas, enquanto que é sobre encontrar caminhos na arte ASCII.
xnor
Eu removi a introdução. Foi um pouco confuso / enganador. @xnor
Zach Gates
3
Relacionado: Para onde a seta está apontando?
mınxomaτ 17/09/2015

Respostas:

11

JavaScript (ES6), 222222

Uma função com a entrada como parâmetro, saída como uma string via janela pop-up (alerta).

Digitalize repetidamente a entrada:
a cada etapa

  • remova a ponta da cauda
  • conte o '#' restante

Quando não há mais cauda para remover, o número de etapas até agora é o tamanho da cauda e o número de '# restante é o tamanho do loop.

Todas as novas linhas dentro dos backticks são significativas e contadas

Teste a execução do trecho abaixo com o Firefox (não o Chrome, pois ele não suporta ...)

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>

edc65
fonte
... o operador de propagação está certo? Você pode nomeá-lo dessa maneira, pois ele existe em outros idiomas (como o groovy) por outras sintaxes (*: list for groovy). Solução agradável de qualquer maneira!
Aaron
11
+1 Eu estava pensando 'Deve haver uma maneira inteligente de fazer isso', surgiu com esta solução, apenas para rolar para baixo até esta resposta.
Sanchises 28/09/2015
8

Ruby, 287 278 bytes

->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]}

Tente aqui .

Isso cria um hash (dicionário) de nós. Para cada nó, o número de conexões de entrada e o próximo nó (possivelmente nulo) são armazenados.

Finalmente:

  • Se não houver nó com 2 conexões de entrada (significando nenhum loop), retorne 0 para a cauda e o número de nós existentes para o loop.
  • Caso contrário, comece a iterar a partir do nó com 0 conexões de entrada (start) via next -> ...-> next até que o nó com 2 conexões de entrada (loop start) seja atingido. Retorne as contagens apropriadas.

A versão legível do código está disponível aqui .

Cristian Lupascu
fonte
2

Ruby, 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}
Level River St
fonte