Cosa ho in tasca?


16

Sinossi: trova i caratteri racchiusi tra MYPOCKET.

Esempio di input

MYPHEIF
YFOCKVH
MBNDEIF
TEUFTMY
ESNDUWP
KBOVUVO
CENWFKC
OPYMTEB

Esempio di output

F   
BND 
EUF   
SNDUW 
BOVUV 
ENWF  

Eh? Come l'abbiamo ottenuto come output? La "tasca" a volte può essere difficile da vedere. Ciò renderà più chiaro:

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

Le lettere in grassetto indicano un anello di caratteri collegati ortogonalmente tra loro costituiti dalla stringa MYPOCKETripetuta più e più volte. Il tuo programma dovrebbe generare i caratteri che si trovano all'interno di quell'anello.

Appunti:

  • Ci sarà solo una "tasca".
  • Trascinamento di nuove righe o spazi dopo le righe sono consentite.
  • Anche il resto della griglia può contenere caratteri MYPOCKET, ma non in modo tale da rendere ambigua la forma dell'anello.
  • Non Mè sempre nell'angolo in alto a destra.
  • La "tasca" può spostarsi in senso orario o antiorario.
  • La "tasca" non si sposta in direzioni diagonali, ovvero ogni lettera è connessa a sinistra, a destra, in alto o in basso alla successiva.

Ecco un altro input con cui puoi testare il tuo programma.

Esempio di input

EKCYMOPD
KCOPHAYM
EKNDSEST
JETHACKE
KRMYPOBN

Esempio di output

  HA
NDSES
 HA

14
Che cosa ha nelle sue piccole e cattive tasche?
Maniglia della porta

È stato ispirato da questa sfida di Anarchy Golf?
xnor

@xnor No, non lo era. (Anche se è in qualche modo simile ...)
Assenzio

Risposte:


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

Utilizzo: salva come pocket.pl ed esegui con:

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

Ho optato per una funzione ricorsiva per forzare il percorso, che potrebbe non essere stato il migliore, ma è stato il primo approccio che ho preso in considerazione.

Mentre funziona per entrambi i casi di test attuali ci sono alcuni avvertimenti:

  • include spazi iniziali (che non ho visto menzionato nelle regole ...); e
  • sicuramente non funzionerà con una 'tasca' che contiene caratteri nel mezzo (diciamo a forma di U o simili).

Voglio continuare a lavorare su questo, ma volevo dimostrare che c'è interesse per la domanda! Felice di documentare il mio processo se utile.


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

Funziona come un programma (basandosi su una funzione ricorsiva) e accettando input dallo stdin.
Demo qui.
Test ( ex1.txte ex2.txtsono gli esempi dalla domanda) -

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

Versione non golfata con commenti -

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

Fammi sapere, se ho fatto qualcosa di stupido o qualcosa può essere fatto meglio.
So che è troppo lungo, ma è il massimo che potrei fare: P


Eh, sono così cattivo con Python che probabilmente lo avrei forzato // Non ho alcuna conoscenza di lambda in Python ... // ma bella soluzione! Ancora meglio di niente.
Kurousagi,
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.