Loops und Loops und Loops

16

Die Herausforderung

Erstellen Sie eine Funktion, die bei Eingabe von ASCII-Zeichen (zum Leiten eines Pfads, der möglicherweise eine Schleife enthält) die Länge der Schleife (falls vorhanden) und die Länge des "Schwanzes" ausgibt, der in eine der Schleifen führt Formen unten.


Eingang

Ihre Eingabe muss an eine Funktion übergeben werden. Unten sehen Sie ein Beispiel für eine einfache Eingabe.

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

Sie könnten die obigen Blöcke so visualisieren

Der "Schwanz" ist ein Gegenstand, während die Schleife vier lang ist.

Ein schwierigeres:

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

Ausgabe

Sie müssen über STDOUT oder die nächstgelegene Alternative Ihrer Sprache ausgeben.

Ihre zwei Ausgabe-Ganzzahlen sollten die Länge des Schwanzes und die Länge der Schleife sein. Diese Ausgabe kann in zwei Formen vorliegen.

  1. eine durch Leerzeichen getrennte Zeichenfolge: "2 10"
  2. eine Reihe von ganzen Zahlen: [2, 10]

Regeln

  • Jeder Block oder #wird nur einen einzigen Weg von sich selbst haben.

  • Jeder Pfeil besteht aus zwei Liniensegmenten und einem Kopf.

  • Der Startblock befindet sich immer in der linken Spalte.

  • Die Eingabe wird niemals nur eine Schleife sein.


Beispiel

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

Dieser hat eine Schwanzlänge von 2 und eine Schleifenlänge von 6. Unten sind der Schwanz und die Schleife voneinander getrennt.

Schwanz

# -->
^
|
|
#

Schleife

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

Die korrekten Ausgänge sind [2, 6]und "2 6".

Wenn die Eingabe nur ein Tail ist , ist die Schleifenlänge Null.

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

Die korrekten Ausgaben für die obigen Eingaben sind [6, 0]und"6 0"

Zach Gates
quelle
@orlp Ich denke, du verwirrst Eingabe und Ausgabe.
Sanchises,
1
Kann der Eingang zusätzliche getrennte Pfade haben?
Donnerstag,
Ich finde das Intro verwirrend. Ich denke, das Problem liegt in der Programmanalyse, wohingegen es in der ASCII-Kunst um die Suche nach Pfaden geht.
Donnerstag,
Ich habe das Intro entfernt. Es war ein bisschen verwirrend / irreführend. @xnor
Zach Gates
3
Verwandte: Wo zeigt der Pfeil?
Mittwoch,

Antworten:

11

JavaScript (ES6), 221 229

Eine Funktion mit der Eingabe als Parameter, die als String über ein Popup-Fenster ausgegeben wird (alert).

Scannen Sie die Eingabe wiederholt:
bei jedem Schritt

  • entferne das Ende des Schwanzes
  • Zähle die verbleibenden '#'

Wenn nicht mehr Schwanz zu entfernen ist, entspricht die Anzahl der bisherigen Schritte der Größe des Schwanzes und die Anzahl der verbleibenden '#' der Größe der Schleife.

Alle Zeilenumbrüche in Backticks sind signifikant und werden gezählt

Testen Sie das folgende Snippet mit Firefox (nicht Chrome, da es nicht unterstützt ...)

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
quelle
... ist der Spread-Operator richtig? Vielleicht möchten Sie es so benennen, da es in anderen Sprachen (wie Groovy) nach anderen Syntaxen existiert (*: Liste für Groovy). Trotzdem eine gute Lösung!
Aaron
1
+1 Ich dachte, es muss eine clevere Möglichkeit geben, dies zu tun. Ich habe diese Lösung gefunden, nur um nach unten zu dieser Antwort zu scrollen.
Sanchises
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]}

Probieren Sie es hier aus .

Dadurch wird ein Hash (Wörterbuch) von Knoten erstellt. Für jeden Knoten werden die Anzahl der eingehenden Verbindungen und der (möglicherweise null) nächste Knoten gespeichert.

Schließlich:

  • Wenn es keinen Knoten mit 2 eingehenden Verbindungen gibt (dh keine Schleife), geben Sie 0 für das Ende und die Anzahl der vorhandenen Knoten für die Schleife zurück.
  • Andernfalls starten Sie die Iteration vom Knoten mit 0 eingehenden Verbindungen (Start) über next -> ...-> next, bis der Knoten mit 2 eingehenden Verbindungen (Loop-Start) erreicht ist. Geben Sie die entsprechenden Zählungen zurück.

Die lesbare Version des Codes finden Sie hier .

Cristian Lupascu
quelle
2

Rubin, 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
quelle