Was habe ich in meiner Tasche?

16

Synopsis: Finden Sie Zeichen, die von eingeschlossen sind MYPOCKET.

Beispiel Eingabe

MYPHEIF
YFOCKVH
MBNDEIF
TEUFTMY
ESNDUWP
KBOVUVO
CENWFKC
OPYMTEB

Beispielausgabe

F   
BND 
EUF   
SNDUW 
BOVUV 
ENWF  

Huh? Wie haben wir das als Ergebnis erhalten? Die "Tasche" kann manchmal schwer zu sehen sein. Dies wird es klarer machen:

MYP heif
 Y F OCK VH
 M BND E IF
 T EUF TMY 
E SNDUW P 
K BOVUV O 
C ENWF KC 
OPYMTE B

Die fett gedruckten Buchstaben kennzeichnen einen orthogonal miteinander verbundenen Zeichenring, der aus der MYPOCKETimmer wieder wiederholten Zeichenfolge besteht . Ihr Programm sollte die Zeichen ausgeben, die sich in diesem Ring befinden.

Anmerkungen:

  • Es wird nur eine "Tasche" geben.
  • Es ist erlaubt, neue Zeilen oder Leerzeichen nach den Zeilen zu setzen.
  • Der Rest des Rasters kann auch Zeichen von enthalten MYPOCKET, jedoch nicht in einer Weise, die die Form des Rings mehrdeutig macht.
  • Das M ist nicht immer in der rechten oberen Ecke.
  • Die "Tasche" kann sich entweder im Uhrzeigersinn oder gegen den Uhrzeigersinn bewegen.
  • Die "Tasche" bewegt sich nicht in diagonale Richtungen - das heißt, jeder Buchstabe ist links, rechts, oben oder unten mit dem nächsten verbunden.

Hier ist ein weiterer Eingang, mit dem Sie Ihr Programm testen können.

Beispiel Eingabe

EKCYMOPD
KCOPHAYM
EKNDSEST
JETHACKE
KRMYPOBN

Beispielausgabe

  HA
NDSES
 HA
Absinth
quelle
14
Was hat es in seinen fiesen kleinen Taschen?
Türklinke
War dies inspiriert durch diese Herausforderung von Anarchy Golf?
Xnor
@xnor Nein, das war es nicht. (Obwohl es etwas ähnlich ist ...)
Absinth

Antworten:

1

Perl 5, 414

map{$y=0;push@{$h{$_}},[$-,$y++]for@$_;$-++}@l=map[/./g],<>;sub n{($a,$b,$c,$d)=@_;$a==$c&&1==abs$b-$d||$b==$d&&1==abs$a-$c}sub c{my($x,$y,$n)=@_;for(grep{($f=defined$x)?n$x,$y,@$_:1}@{$h{(MYPOCKET=~/./g)[$n%8]}}){($m,$l)=@$_ if!$f;return@r=([@$_],@r)if$n>2&&n(@$_,$m,$l)||c(@$_,$n+1)}''}c;$l[$_->[0]][$_->[1]]=$" for@r;($l[$_]=join'',@{$l[$_]})=~s/^(\w+)\s|\s(\w+)$/$"x($1||$2)=~y%%%c/eg for 0..@l;print join$/,@l

Verwendung: als pocket.pl speichern und ausführen mit:

perl pocket.pl <<< '<grid>'

Ich entschied mich für eine rekursive Funktion, um den Pfad zu brachialisieren, was vielleicht nicht der beste war, aber der erste Ansatz, den ich in Betracht zog.

Während es für beide aktuellen Testfälle funktioniert, gibt es einige Einschränkungen:

  • es enthält führende Leerzeichen (die ich nicht in den Regeln erwähnt habe ...); und
  • Es funktioniert definitiv nicht mit einer 'Tasche', die Zeichen in der Mitte enthält (sagen wir U-förmig oder ähnlich).

Ich möchte weiter daran arbeiten, aber zeigen, dass Interesse an der Frage besteht! Gerne dokumentiere ich meinen Ablauf wenn hilfreich.

Dom Hastings
quelle
5

Python 2.7 571 542 509

import sys
o,l,v,k,w="MYPOCKET",[list(e)for e in sys.stdin],[],enumerate,len
def f(z,q,t):
 for r,c in(z,q+1),(z,q-1),(z+1,q),(z-1,q):
  if w(l)>r>=0 and 0<=c<w(l[r])and o[t]==l[r][c]:
    v.append((r,c))
    if f(r,c,(t+1)%w(o)):return 1
    else:v.pop()
 if z==1 and(0,q)in v or z==0 and(z,q+1)in v:return 1
for i,x in k(l[0]):
 v=[(0,i)]
 if x==o[0]and f(0,i,1):break
for i in range(1,w(l)-1):b=[y for x,y in sorted(v)if x==i];print"".join(["".join(e)if w(e)>0 else" "for e in[l[i][b[j-1]+1:y]for j,y in k(b)][1:]])

Arbeitet als Programm (setzt auf eine rekursive Funktion) und akzeptiert Eingaben von stdin.
Demo hier.
Testen Sie es ( ex1.txtund ex2.txtsind die Beispiele aus der Frage) -

$ python pockets.py < ex1.txt
F
BND
EUF
SNDUW
BOVUV
ENWF
$ python pockets.py < ex2.txt 
  HA 
NDSES
 HA  

Ungolfed-Version mit Kommentaren -

s="""
EKCYMOPD
KCOPHAYM
EKNDSEST
JETHACKE
KRMYPOBN
"""
li2=[list(e.strip()) for e in s.split("\n") if e.strip()!='']
buf=[]
def find_precious(row, col, c_ind):
    for r,c in[(row,col+1),(row,col-1),(row+1,col),(row-1,col)]:
        if len(li2)>r>=0 and 0<=c<len(li2[r]) and seq[c_ind]==li2[r][c]:
            if (r,c)in buf:return True
            buf.append((r,c))
            if find_precious(r,c,(c_ind+1)%len(seq)):return True
            else:buf.pop()
    if row==1 and (row-1,col) in buf or row==0 and (row,col+1) in buf:return True
    return False

for i,x in enumerate(li2[0]):
    if x==seq[0]:
        buf=[(0,i)]
        if find_precious(0,i,1):break
if len(buf)==1:
    exit("Failed")

#Calculate the middle men
for i in range(1,len(li2)-1):
    b=[y for x,y in sorted(buf)if x==i]
    print "".join(["".join(e)for e in [li2[i][b[j-1]+1:y]for j,y in enumerate(b)][1:]if len(e)>0])

Lass es mich wissen, wenn ich etwas Dummes getan habe oder etwas besser gemacht werden kann.
Ich weiß, es ist lang, aber es ist das Beste, was ich tun kann: P

Kamehameha
quelle
Eh, ich bin so schlecht in Python, dass ich es wahrscheinlich brachial machen würde // Ich habe keine Kenntnisse über Lambdas in Python ... // aber eine nette Lösung! Immer noch besser als keine.
Kurousagi