Loop e loop e loop


16

La sfida

Crea una funzione che, quando viene fornito un input di arte ASCII (dirigendo un percorso che potrebbe eventualmente eseguire un loop), genera la lunghezza del loop (se ce n'è uno) e la lunghezza della "coda" che conduce nel loop in uno dei moduli di seguito.


Ingresso

L'input deve essere passato a una funzione. Di seguito è riportato un esempio di un semplice input.

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

È possibile visualizzare i blocchi sopra in questo modo

La "coda" è un elemento, mentre il ciclo è lungo quattro.

Uno più difficile:

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

Produzione

È necessario eseguire l'output tramite STDOUT o l'alternativa più vicina alla propria lingua.

I tuoi due numeri interi di output dovrebbero essere la lunghezza della coda e la lunghezza del loop. Questo output può essere in due forme.

  1. una stringa delimitata da spazi: "2 10"
  2. una matrice di numeri interi: [2, 10]

Regole

  • Ogni blocco, o #, avrà solo un singolo percorso lontano da se stesso.

  • Ogni freccia è composta da due segmenti di linea e una testa.

  • Il blocco iniziale sarà sempre nella colonna più a sinistra.

  • L'input non sarà mai solo un loop.


Esempio

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

Questo ha una lunghezza della coda di 2 e una lunghezza dell'anello di 6. Sotto, la coda e l'anello sono separati.

Coda

# -->
^
|
|
#

Ciclo continuo

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

Le uscite corrette sono [2, 6]e "2 6".

Se l'ingresso è solo una coda , la lunghezza del loop è zero.

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

Le uscite corrette per l'ingresso sopra sono [6, 0]e"6 0"


@orlp Penso che stai confondendo input e output.
Sanchises,

1
L'ingresso può avere parti di percorso extra disconnesse?
xnor

Penso che l'introduzione sia confusa. Mi fa pensare che il problema riguarderà l'analisi dei programmi, mentre riguarda la ricerca di percorsi nell'arte ASCII.
xnor

Ho rimosso l'introduzione. Era un po 'confuso / fuorviante. @xnor
Zach Gates,

Risposte:


11

JavaScript (ES6), 221 229

Una funzione con input come parametro, output come stringa tramite finestra popup (avviso).

Scansiona ripetutamente l'input:
ad ogni passo

  • rimuovere l'estremità della coda
  • contare i restanti '#'

Quando non c'è più coda da rimuovere, il numero di passaggi finora è la dimensione della coda e il numero di '# rimanenti è la dimensione del loop.

Tutte le newline all'interno dei backtick sono significative e contate

Prova a eseguire lo snippet di seguito con Firefox (non Chrome, in quanto non supporta ...)

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>


... l'operatore di spread ha ragione? Potresti voler nominarlo in questo modo poiché esiste in altre lingue (come groovy) con altre sintassi (*: list for groovy). Bella soluzione comunque!
Aaron,

1
+1 Stavo pensando 'Deve esserci un modo intelligente per farlo', ho trovato questa soluzione, solo per scorrere fino a questa risposta.
Sanchises,

8

Rubino, 287 278 byte

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

Provalo qui .

Questo crea un hash (dizionario) di nodi. Per ciascun nodo, vengono memorizzati il ​​numero di connessioni in entrata e il nodo successivo (possibilmente nullo).

Infine:

  • Se non esiste un nodo con 2 connessioni in entrata (ovvero nessun ciclo), restituisce 0 per la coda e il numero di nodi esistenti per il ciclo.
  • Altrimenti, iniziare iterando dal nodo con 0 connessioni in entrata (inizio) tramite successivo -> ...-> successivo fino a raggiungere il nodo con 2 connessioni in entrata (inizio loop). Restituisce i conteggi appropriati.

La versione leggibile del codice è disponibile qui .


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}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.