Pętle i pętle i pętle

16

Wyzwanie

Utwórz funkcję, która po wprowadzeniu danych ASCII (kierowanie ścieżką, która może ostatecznie zapętlić), wyświetla długość pętli (jeśli taka istnieje) i długość „ogona” prowadzącego do pętli w jednym z formularze poniżej.


Wejście

Dane wejściowe należy przekazać do funkcji. Poniżej znajduje się przykład prostego wejścia.

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

Możesz wizualizować powyższe bloki w ten sposób

„Ogon” jest jednym przedmiotem, a pętla ma cztery długości.

Trudniejszy:

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

Wynik

Musisz wyprowadzać dane przez STDOUT lub najbliższą alternatywę dla twojego języka.

Dwie wyjściowe liczby całkowite powinny mieć długość ogona i długość pętli. Ten wynik może mieć dwie formy.

  1. ciąg rozdzielany spacjami: "2 10"
  2. tablica liczb całkowitych: [2, 10]

Zasady

  • Każdy blok, lub #, będzie miał tylko jedną ścieżkę od siebie.

  • Każda strzała to dwa segmenty linii i jedna głowa.

  • Blok początkowy zawsze będzie znajdować się w lewej kolumnie.

  • Wejście nigdy nie będzie tylko pętlą.


Przykład

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

Ten ma długość ogona 2 i długość pętli 6. Poniżej ogon i pętla są oddzielone.

Ogon

# -->
^
|
|
#

Pętla

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

Prawidłowe dane wyjściowe to [2, 6]i "2 6".

Jeśli wejście jest tylko ogonem , długość pętli wynosi zero.

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

Prawidłowe dane wyjściowe dla powyższego wejścia to [6, 0]i"6 0"

Zach Gates
źródło
@orlp Myślę, że mylisz wejście i wyjście.
Sanchises,
1
Czy wejście może mieć dodatkowe odłączone fragmenty ścieżki?
xnor
Myślę, że wprowadzenie jest mylące. To sprawia, że ​​myślę, że problem dotyczy analizy programu, podczas gdy chodzi o wyszukiwanie ścieżek w sztuce ASCII.
xnor
Usunąłem wprowadzenie. To było trochę mylące / mylące. @xnor
Zach Gates
3
Powiązane: Gdzie wskazuje strzałka?
mınxomaτ

Odpowiedzi:

11

JavaScript (ES6), 221 229

Funkcja z wejściem jako parametrem, wyprowadzana jako ciąg znaków przez wyskakujące okienko (alert).

Skanuj wielokrotnie dane wejściowe:
na każdym kroku

  • usuń koniec ogona
  • policz pozostałe „#”

Gdy nie ma już więcej ogona do usunięcia, liczba kroków do tej pory jest rozmiarem ogona, a liczba pozostałych „# jest rozmiarem pętli.

Wszystkie nowe linie w backticks są znaczące i liczone

Przetestuj poniższy fragment kodu w przeglądarce Firefox (nie w Chrome, ponieważ nie obsługuje ...)

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
źródło
... czy operator rozprzestrzeniania ma rację? Możesz nazwać to w ten sposób, ponieważ istnieje on w innych językach (np. Groovy) według innych składni (*: lista dla groovy). W każdym razie fajne rozwiązanie!
Aaron
1
+1 Myślałem „Musi być sprytny sposób”, wymyśliłem to rozwiązanie, aby przewinąć w dół do tej odpowiedzi.
Sanchises
8

Rubinowy, 287 278 bajtów

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

Wypróbuj tutaj .

To tworzy skrót (słownik) węzłów. Dla każdego węzła zapisywana jest liczba połączeń przychodzących i (ewentualnie zerowy) następny węzeł.

Wreszcie:

  • Jeśli nie ma węzła z 2 połączeniami przychodzącymi (co oznacza brak pętli), zwróć 0 dla ogona i liczbę istniejących węzłów dla pętli.
  • W przeciwnym razie rozpocznij iterację od węzła z 0 połączeniami przychodzącymi (start) przez next -> ...-> next aż do osiągnięcia węzła z 2 połączeniami przychodzącymi (start pętli). Zwróć odpowiednie liczby.

Czytelna wersja kodu jest dostępna tutaj .

Cristian Lupascu
źródło
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
źródło