Co mam w kieszeni?

16

Streszczenie: Znajdź znaki, które są otoczone przez MYPOCKET.

Przykładowe dane wejściowe

MYPHEIF
YFOCKVH
MBNDEIF
TEUFTMY
ESNDUWP
KBOVUVO
CENWFKC
OPYMTEB

Przykładowy wynik

F   
BND 
EUF   
SNDUW 
BOVUV 
ENWF  

Co? Jak otrzymaliśmy to jako wynik? „Kieszeń” może być czasem trudna do zauważenia. Ułatwi to:

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

Pogrubione litery oznaczają pierścień znaków połączonych ze sobą prostopadle, składający się z ciągów MYPOCKETpowtarzanych w kółko. Twój program powinien wypisywać znaki znajdujące się w tym pierścieniu.

Uwagi:

  • Będzie tylko jedna „kieszeń”.
  • Końcowe nowe linie lub spacje po liniach są dozwolone.
  • Reszta siatki może również zawierać znaki z MYPOCKET, ale nie w sposób, który sprawia, że ​​kształt pierścienia jest niejednoznaczny.
  • MNie zawsze znajduje się w prawym górnym rogu.
  • „Kieszeń” może poruszać się w kierunku zgodnym z ruchem wskazówek zegara lub przeciwnie do ruchu wskazówek zegara.
  • „Kieszeń” nie porusza się po przekątnej - to znaczy każda litera jest połączona w lewo, w prawo, w górę lub w dół do następnej.

Oto kolejne wejście, za pomocą którego możesz przetestować swój program.

Przykładowe dane wejściowe

EKCYMOPD
KCOPHAYM
EKNDSEST
JETHACKE
KRMYPOBN

Przykładowy wynik

  HA
NDSES
 HA
Absynt
źródło
14
Co ma w swoich paskudnych kieszonkach?
Klamka
Czy inspiracją było to wyzwanie Anarchy Golf?
xnor
@xnor Nie, nie było. (Chociaż jest nieco podobny ...)
absynt

Odpowiedzi:

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

Sposób użycia: zapisz jako pocket.pl i uruchom z:

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

Wybrałem funkcję rekurencyjną, by brutalnie wymusić ścieżkę, co może nie było najlepsze, ale było to pierwsze podejście, jakie rozważałem.

Chociaż działa w obu przypadkach testowych, istnieją pewne zastrzeżenia:

  • obejmuje wiodące spacje (których nie widziałem wspomniane w regułach ...); i
  • na pewno nie zadziała z „kieszenią”, która zawiera znaki pośrodku (powiedzmy w kształcie litery U lub podobną).

Chcę dalej nad tym pracować, ale chciałem pokazać, że pytanie jest interesujące! W razie potrzeby chętnie udokumentuję mój proces.

Dom Hastings
źródło
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:]])

Działa jako program (bankowość na funkcji rekurencyjnej) i akceptuje dane wejściowe ze standardowego wejścia.
Demo tutaj.
Testowanie ( ex1.txti ex2.txtprzykłady z pytania) -

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

Wersja bez golfa z komentarzami -

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

Daj mi znać, jeśli zrobiłem coś głupiego lub coś można zrobić lepiej.
Wiem, że to jest długie, ale najlepsze, co mogłem zrobić: P.

Kamehameha
źródło
Eh, jestem taki zły w Pythonie, że prawdopodobnie użyłbym brutalnej siły // Nie mam żadnej wiedzy o lambdach w Pythonie ... // ale fajne rozwiązanie! Nadal lepsze niż żadne.
Kurousagi,