주머니에 무엇을 넣었습니까?


16

개요 : 로 둘러싸인 문자를 찾으십시오 MYPOCKET.

입력 예

MYPHEIF
YFOCKVH
MBNDEIF
TEUFTMY
ESNDUWP
KBOVUVO
CENWFKC
OPYMTEB

출력 예

F   
BND 
EUF   
SNDUW 
BOVUV 
ENWF  

응? 출력으로 어떻게 얻었습니까? "포켓"은 때때로보기 어려울 수 있습니다. 이것은 더 명확해질 것입니다 :

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

굵은 글씨는 MYPOCKET반복해서 반복 되는 줄로 구성되어 서로 직교로 연결된 문자의 고리를 나타냅니다 . 프로그램은 해당 링 내에있는 문자를 출력해야합니다.

노트:

  • 하나의 "포켓"만 있습니다.
  • 줄 뒤의 새로운 줄이나 공백이 허용됩니다.
  • 그리드의 나머지 부분에는의 문자도 포함될 수 MYPOCKET있지만 링 모양을 모호하게 만드는 방식은 아닙니다.
  • 그만큼 M 항상 오른쪽 상단에있는 것은 아닙니다.
  • "포켓"은 시계 방향 또는 시계 반대 방향으로 움직일 수 있습니다.
  • "포켓"은 대각선 방향으로 움직이지 않습니다. 즉, 각 문자는 왼쪽, 오른쪽, 위 또는 아래로 연결됩니다.

다음은 프로그램을 테스트 할 수있는 다른 입력입니다.

입력 예

EKCYMOPD
KCOPHAYM
EKNDSEST
JETHACKE
KRMYPOBN

출력 예

  HA
NDSES
 HA

14
불쾌한 작은 주머니에 무엇이 있습니까?
Doorknob

이것이 무정부 골프의 도전 에서 영감을 얻었습니까 ?
xnor

@ xnor 아니요, 그렇지 않았습니다. (비록이 ... 다소 유사하다)
압생트

답변:


1

펄 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

사용법 : pocket.pl로 저장하고 다음을 실행하십시오.

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

나는 최선의 방법은 아니지만 경로를 무차별 대입하기 위해 재귀 함수를 사용했지만 처음 고려한 접근법이었습니다.

현재 테스트 사례 모두에서 작동하지만 몇 가지주의 사항이 있습니다.

  • 여기에는 앞 공백이 포함됩니다 (규칙에서 언급하지 않은 ...); 과
  • 중간에 문자가 포함 된 '포켓'(예 : U 자형 또는 이와 유사한 형식)에서는 작동하지 않습니다.

이 작업을 계속하고 싶지만 질문에 관심이 있다는 것을 보여주고 싶었습니다! 도움이된다면 내 프로세스를 기록해 드리겠습니다.


5

파이썬 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:]])

프로그램 (재귀 함수에 대한 뱅킹)으로 작동하고 stdin의 입력을 수락합니다.
여기 데모.
(그것을 테스트 ex1.txt하고 ex2.txt문제의 예입니다) -

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

주석이 달린 언 골프 버전-

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

내가 멍청한 짓을하거나 더 잘할 수 있다면 알려주세요.
나는 그것이 어리 석다는 것을 알고 있지만, 내가 할 수있는 최선입니다 : P


Eh, 나는 파이썬에 너무 나쁘다. 아마도 그것을 무력하게 만들 것이다. // 파이썬에 람다에 대한 지식이 없다. 여전히 아무것도 아닌 것보다 낫습니다.
Kurousagi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.