단어 검색 퍼즐


29

단어 검색 퍼즐과 검색 문자열로 직사각형 텍스트가 주어지면 텍스트에 검색 문자열이 포함되어 있는지 확인하십시오. 검색 문자열이 나타날 수 있습니다 :

  • 수평, 수직 또는 대각선
  • 앞으로 또는 뒤로

함수 또는 프로그램을 작성하고 함수 인수 ARGV 또는 STDIN을 통해 두 개의 문자열을 입력으로 사용할 수 있습니다. 출력은 함수에서 리턴되거나 STDOUT에 기록 될 수있는 진실되거나 허위 결과 여야합니다 .

텍스트가 임의의 인쇄 가능한 ASCII 문자 (16 진 코드 20-7E)와 줄 바꿈 문자를 포함한다고 가정하십시오. 문자는 대소 문자를 구분합니다. 입력 텍스트가 직사각형이라고 가정 할 수 있습니다. 즉 모든 줄의 길이가 같습니다. 입력이 후행 줄 바꿈으로 끝나는 지 여부 (제출에 중요한 경우)가있을 ​​수 있습니다.

이것은 코드 골프이며, 가장 짧은 대답 (바이트)이 이깁니다.

단어 검색에 대한 Wikipedia 기사의이 표를 첫 번째 입력으로 사용합니다.

WVERTICALL
ROOAFFLSAB
ACRILIATOA
NDODKONWDC
DRKESOODDK
OEEPZEGLIW
MSIIHOAERA
ALRKRRIRER
KODIDEDRCD
HELWSLEUTH

다음 검색 문자열은 각각 진실하거나 허위 결과를 산출해야합니다.

Truthy: RANDOM, VERTICAL, HORIZONTAL, WORDSEARCH, WIKIPEDIA, TAIL
Falsy:  WordSearch, CODEGOLF, UNICORN

또는이 입력 텍스트를 사용하여

Lorem ipsum dolor sit amet consectetu
r adipisicing elit sed do eiusmod tem
por incididunt ut labore et dolore ma
gna aliqua. Ut enim ad minim veniam, 
quis nostrud exercitation ullamco lab
oris nisi ut aliquip ex ea commodo co
nsequat. Duis aute irure dolor in rep
rehenderit in voluptate velit esse ci
llum dolore eu fugiat nulla pariatur.

다음과 같은 검색 결과를 얻습니다 (일부 검색 문자열에 공백이 있기 때문에 따옴표를 사용함).

Truthy: "Lorem", "mine", "uma bop", "tuetdod", "snol,a", "texas", "pii.d  v", "vexta"
Falsy:  "lorem", "wordsearch", "pii.d v", "mute"

답변:


7

CJam, 46 37 바이트

qN%{_zW%__,N**2$2$+,)/z\}4*]:+N*eas#)

STDIN에서 그리드를 읽고 단어를 명령 행 인수로 읽습니다. 일치하는 경우 양의 정수를 인쇄하고 일치하지 않는 경우 0을 인쇄합니다.

2 바이트의 추가 비용으로 STDIN에서 두 문자열 (워드, 줄 바꿈, 그리드)을 읽을 수 있습니다.

qN%(\{_zW%__,N**2$2$+,)/z\}4*](\:+N*\#)

CJam 인터프리터를 사용하여이 버전을 온라인으로 사용해 볼 수 있습니다 .

예제 실행

$ for W in Lorem mine uma\ bop tuetdod snol,a texas pii.d\ \ v vexta WordSearch CODEGOLF UNICORN; do echo -e "$(cjam wordsearch.cjam "$W" < grid)\t$W"; done
1       Lorem
3085    mine
2055    uma bop
5142    tuetdod
3878    snol,a
1426    texas
5371    pii.d  v
2536    vexta
0       WordSearch
0       CODEGOLF
0       UNICORN

배경

입력 값이 다음 표라고 가정하십시오.

ABCD
EFGH
IJKL

줄 바꿈에서 분할하면 다음 배열을 얻습니다.

A := [
         "ABCD"
         "EFGH"
         "IJKL"
     ]

그것은 동쪽 단어 (왼쪽에서 오른쪽으로가는 단어)를 다룹니다.

이제 줄 바꿈 A문자열을 len(A)구분 기호로 사용하는 요소를 결합합니다 .

"ABCD⏎⏎⏎EFGH⏎⏎⏎IJKL"

그런 다음 결과 문자열을 길이 단위로 자릅니다 len(A) + len(A[0]) + 1.

[
    "ABCD⏎⏎⏎E"
    "FGH⏎⏎⏎IJ"
    "KL"
]

배열을 "압축"하면 (행과 열을 바꿈) 다음을 얻습니다.

[
    "AFK"
    "BGL"
    "CH"
    "D⏎"
    "⏎⏎"
    "⏎⏎"
    "I⏎"
    "EJ"
]

그것은 동남아시아 단어를 다룹니다.

A를 압축하고 결과 행의 순서를 반대로 바꾸면 다음을 얻습니다.

[
    "DHL"
    "CGK"
    "BFJ"
    "AEI"
]

그것은 남쪽과 대각선에 대한 과정을 반복 한 후에 남서 단어를 포함합니다.

다시 압축하고 뒤집 으면 다음과 같은 이점이 있습니다.

[
    "LKJI"
    "HGFE"
    "DCBA"
]

그것은 서구와 대각선에 대한 과정을 반복 한 후에 북서 단어를 포함합니다.

다시 한 번 압축하고 뒤집 으면 다음과 같은 이점이 있습니다.

[
    "IEA"
    "JFB"
    "KGC"
    "LHD"
]

북과 북에 대한 과정을 반복 한 후 북동 단어를 다룬다.

작동 원리

코드는 이전 섹션에서 설명한대로 약간의 차이점이 있습니다.

  • 처음에는 한 번 압축하고 뒤집습니다.
  • 로 계산 len(A) + len(A[0])됩니다 len(A + zip(A)).

마지막으로 줄 바꿈을 구분 기호로 사용하여 생성 된 모든 배열의 모든 행을 결합하고 결과 문자열에서 단어를 검색합니다.

qN%                                   " A := split(input(),'\n')                          ";
   {                    }4*           " Do 4 times:                                       ";
    _zW%                              "   B := reverse(zip(A))                            ";
        __,N**                        "   C := B.join(len(B) * '\n')                      ";
              2$2$+,)/z               "   D := zip(C.chunks(len(A + B) + 1))              ";
                       \              "   A := B                                          ";
                           ]          " Collect all values of A and D in an array R.      ";
                            :+        " R := flatten(R)                                   ";
                              N*      " R := R.join('\n')                                 ";
                                eas   " I := flatten(ARGV)                                ";
                                   #) " print R.index(I) + 1                              ";

7

자바 : 183 (211) (321)

boolean s(char[]w,char[]s){int j,z,a=s.length,i=a*9,f=1,q=0;for(;s[q++]>10;);for(;i-->0;)for(j=w.length,z=i/9;i%9!=4&j-->0&z>=0&z<a&&s[z]==w[j];z+=q*(i/3%3)+i%3-q-1)f*=j;return f==0;}

기본적인 무차별 대입 할 말이 많지 않다고 생각합니다. 입력은 바늘 우선, 건초 더미 둘째입니다. grid가 개행 종료라고 가정합니다 .

테스트 케이스가 표시된 약간 더 읽기 쉬운 버전 :

public class WordSearch {
    static String grid = "WVERTICALL\nROOAFFLSAB\nACRILIATOA\nNDODKONWDC\nDRKESOODDK\nOEEPZEGLIW\nMSIIHOAERA\nALRKRRIRER\nKODIDEDRCD\nHELWSLEUTH";
    static String search = "RANDOM";

    public static void main(String[] args) {
        System.out.println(new WordSearch().s(search.toCharArray(),grid.toCharArray()));
    }

    boolean s(char[]w,char[]s){
        int j,z,a=s.length,i=a*9,f=1,q=0;
        for(;s[q++]>10;);
        for(;i-->0;)
            for(j=w.length,z=i/9;
                i%9!=4&j-->0&z>=0&z<a&&s[z]==w[j];
                z+=q*(i/3%3)+i%3-q-1)
                f*=j;
        return f==0;
    }
}

if(e<1)return 1>0;return e<1;그것을 할 수 없었다?
FryAmTheEggman

@FryAmTheEggman 아니요, 첫 번째 실패를 찾은 후에 반환되므로 전체 그리드를 검색하지 않습니다.
Geobits

1
아 죄송합니다.
FryAmTheEggman

4
당신이 할 것 대신에, 그래서 루프 두 밖으로 하나에 축소 할 수 i=a*9,for(;i-->0;)다음과 z=i/9;i%a!=4&에 그래서?
Will

1
와우, 이것은 내 것과 너무 비슷합니다. 그리고 이미 시작한 후에 만 ​​봤습니다. 나는 그것이 어떻게 작동하는지 보는 데 시간이 걸리지 않았다. +1.
Level River St

6

자바 스크립트 (E6) 111116

모든 방향에서 모든 캐릭터에 대한 무차별 대입-가능한 한 골프

F=(b,w)=>
  [1,-1,r=b.search('\n'),-r,++r,-r,++r,-r].some(d=>
    [...b].some((_,p)=>
      [...w].every(c=>c==b[p+=d],p-=d)
    )
  )

FireFox / Firebug 콘솔에서 테스트

;["RANDOM", "VERTICAL", "HORIZONTAL", "WORDSEARCH", "WIKIPEDIA", "TAIL",
"WordSearch", "CODEGOLF", "UNICORN"]
.forEach(w=>console.log('\n'+ w +' -> '+
  F("WVERTICALL\nROOAFFLSAB\nACRILIATOA\nNDODKONWDC\nDRKESOODDK\nOEEPZEGLIW\nMSIIHOAERA\nALRKRRIRER\nKODIDEDRCD\nHELWSLEUTH",w)))

산출

RANDOM -> true
VERTICAL -> true
HORIZONTAL -> true
WORDSEARCH -> true
WIKIPEDIA -> true
TAIL -> true
WordSearch -> false
CODEGOLF -> false
UNICORN -> false

5

파이썬, 175

그다지 영감을 얻지는 않았지만 여기에 간다.

def s(h,n):
 l=h.find('\n')+2;h+='\n'*l;L=i=len(h)
 while i>0:
  i-=1
  for d in[-l,1-l,2-l,-1,1,l-2,l-1,l]:
    j=i;m=len(n)
    for c in n:m-=c==h[j%L];j+=d
    if m<1:i=-1
 return-i

첫 번째 주장은 건초 더미이고, 두 번째 주장은 바늘입니다.


난 당신이 사용하여 6 개 문자를 저장할 수 있다고 생각 h,n=input()하고 print. 또한 이것은 사각형이 아닌 입력에서 작동합니까? (m = len (n)? 나는 당신이하고있는 일을 완전히 이해하지 못한다는 것을 인정하므로 완전히 틀릴 수도 있습니다!)
FryAmTheEggman

@FryAmTheEggman : 예, 사각형이 아닌 입력에서 작동합니다.
Ell

1
일부 표준 Python 최적화 : while i>0to while i:( i음수가 될 수 없으므로) if m<1:i=-1to i-=m<1.
xnor

1
@xnor 난 당신이 오독이있을 수 있습니다 생각 if m<1:i=-1으로 if m<1:i-=1자신이 설정되어 있기 때문에 그 중 어느 것도 작동으로 i음수가 될 수 있습니다.
FryAmTheEggman

@FryAmTheEggman 오, 그래, 나는 그것을 완전히 읽지 않았다.
xnor

5

배쉬 +로 coreutils, (214) 169 바이트

r()(tee >(rev) $@)
t()(eval paste -d'"\0"' `sed 's/.*/<(fold -1<<<"&")/'`)
d()(while IFS= read l;do echo "$a$l";a+=_;done|t)
r<<<"$2"|r >(d) >(r|t) >(r|d)|r|grep -q "$1"

용도도 3은 변환 함수 r, td모든 필요한 조합, 전치 대각선 이동을 반대로.

업데이트-이 r기능은 이제 추가적인 골프를 위해 역전 및 역전 출력을 생성합니다.

명령 줄 인수를 통한 입력-검색 문자열 다음에 (개행으로 구분 된) 직사각형 wordsearch 블록.

출력은 관용적으로 올바른 쉘 종료 상태 코드-0은 TRUE를 의미하고 1은 FALSE를 의미합니다.

산출:

$ for w in "Lorem" "mine" "uma bop" "tuetdod" "snol,a" "texas" "pii.d  v" "vexta" ; do ./ws.sh "$w" "Lorem ipsum dolor sit amet consectetu
r adipisicing elit sed do eiusmod tem
por incididunt ut labore et dolore ma
gna aliqua. Ut enim ad minim veniam, 
quis nostrud exercitation ullamco lab
oris nisi ut aliquip ex ea commodo co
nsequat. Duis aute irure dolor in rep
rehenderit in voluptate velit esse ci
llum dolore eu fugiat nulla pariatur."; echo $?; done
0
0
0
0
0
0
0
0
$ for w in WordSearch CODEGOLF UNICORN ; do ./ws.sh "$w" "Lorem ipsum dolor sit amet consectetu
r adipisicing elit sed do eiusmod tem
por incididunt ut labore et dolore ma
gna aliqua. Ut enim ad minim veniam, 
quis nostrud exercitation ullamco lab
oris nisi ut aliquip ex ea commodo co
nsequat. Duis aute irure dolor in rep
rehenderit in voluptate velit esse ci
llum dolore eu fugiat nulla pariatur."; echo $?; done
1
1
1
$ 

1.을 제안 T()(tee >(r) $@)하려고했지만 더 좋습니다. 2. 그 함수 구문을 본 적이 없다고 생각합니다. 3. 비어 있지 않은 문자열 진실하고 빈 문자열이 잘못된 것을 고려하면 생략 할 수 있다고 생각합니다 -q.
Dennis

당신이 정의하는 경우 r()(tee >(rev) $@), r<<<"$2"|r >(d) >(r|t) >(r|d)|r|grep "$1"잘 작동합니다.
Dennis

나는 다른 것을 테스트하지 않았지만, 시도했을 때 질문의 두 가지 테스트 사례가 체크 아웃되었습니다.
Dennis

@ 데니스 니스-네, 지금 작동합니다. 나는 Martin과 확인했다-그는 -q남아 있기 를 원한다 .
Digital Trauma

5

C, 163

f(char*h,char*n){int i,j,d,p,y=0,l=strlen(h),w=strchr(h,10)-h+1;for(i=l*9;i--;y+=d&&!n[j]){p=i/9;d=i%9/3*w-w+i%3-1;for(j=0;p>=0&p<l&h[p]==n[j];j++)p+=d;}return y;}

그리드를 재 배열하지 않고 단순히 모든 방향으로 모든 시작 문자를 시도하고 그리드를 벗어나거나 불일치를 찾을 때까지 걷습니다.

C 문자열이 0 바이트로 끝나는 사실을 이용합니다. 그리드에 0 바이트가 없으므로 항상 불일치가 발생합니다. 그러나 0 바이트에서 불일치가 발생하면 검색 할 문자열의 끝을 발견하고 일치로 기록합니다.

테스트 프로그램에서 풀리지 않은

char h[]="WVERTICALL\nROOAFFLSAB\nACRILIATOA\nNDODKONWDC\nDRKESOODDK\nOEEPZEGLIW\nMSIIHOAERA\nALRKRRIRER\nKODIDEDRCD\nHELWSLEUTH\n";

f(char*h,char*n){                                   //haystack,needle
  int i,j,d,p,y=0,l=strlen(h),w=strchr(h,10)-h+1;   //l=length of whole grid. w=width of row, including terminal newline ASCII 10
  for(i=l*9;i--;){                                  //for each start letter and direction
    p=i/9;                                          //pointer to start letter
    d=i%9/3*w-w+i%3-1;                              //9 possible values of direction vector {-w,0,w}+{-1,0,1}
    for(j=0;p>=0&p<l&h[p]==n[j];j++)p+=d;           //walk p in the direction defined by d until we walk off the top or bottom of the grid or a mismatch is fount
    y+=d&&!n[j];                                    //if we got all the way to the terminal 0, record it as a hit. If d=0, don't record as this is an invalid direction.
  }
  return y;   
}

main(int c, char**v){
  printf("%d",f(h,v[1]));  
}

산출

이 함수는 그리드에서 검색된 문자열의 총 발생 횟수를 반환합니다. 따라서 OD발생률이 6 인 경우 C에서 유일하게 잘못된 값인 0을 반환합니다. 변경 y|=d*!n[j]하면 한 문자 만 저장하지만이 기능은 손실됩니다.

$ ./a UNICORN
0

$ ./a CODEGOLF
0

$ ./a WordSearch
0

$ ./a RANDOM
1

$ ./a WORDSEARCH
1

$ ./a VERTICAL
1

$ ./a HORIZONTAL
1

$ ./a WIKIPEDIA
1

$ ./a TAIL
1

$ ./a OD
6

5

C 번호 - 218 197 186 바이트

C # 함수는 두 개의 문자열 (첫 번째로 검색 할 단어)을, 나중에는 줄 \n사이에 줄 바꿈 ( )이 있는 그리드를 가져옵니다 . 상황이 지금 절박 해지고 있습니다 ... 사실 필사적으로 이전 편집 이 작동하지 않았습니다!

골프 코드 :

bool F(string D,string S){int l=S.Length,i=l*13,r,p;for(S+="\n";i-->l*5;i=r<0?r:i)for(r=D.Length,p=i%l;p>-1&p<l&r-->0&&D[r]==S[p];p+=(S.IndexOf('\n')+1)*(i/l%9/3-1)+i/l%3-1);return i<0;}

테스트 코드로 골프를 덜하세요 :

class P
{
    static void Main()
    {
        System.Console.WriteLine(new P().F(System.Console.ReadLine(),System.Console.In.ReadToEnd())?"Truthy":"Falsy"); // because why not
    }

    bool F(string D,string S)
    {
        int l=S.Length,i=l*13,r,p;

        for(S+="\n";i-->l*5;i=r<0?r:i) // for each cell/direction
            for(r=D.Length,p=i%l;p>-1&p<l&r-->0&&D[r]==S[p];p+=(S.IndexOf('\n')+1)*(i/l%9/3-1)+i/l%3-1); // test against string (backwards)

        return i<0;
    }
}

4

하스켈-173

그리드에서 직접 검색하는 대신 그리드를 다른 방식으로 변환하고 단어를 새 그리드의 각 행과 일치시킵니다.

예를 들어

G1    G2    G3       G4   G5

abcd  aA1   abcd     a..  ..1
ABCD  bB2   .ABCD    bA.  .A2
1234  cC3   ..1234   cB1  aB3
      dD4            dC2  bC4
                      D3  cD
                       4  d

G1, G2, G4 및 G5의 각 행에서 단어를 검색하면 완료됩니다. G3는 사용되지 않았으므로 여기서는 설명을 위해 게시했습니다.

앞뒤 검색에도 비슷한 아이디어가 적용됩니다. 원래 단어와 반대 단어 만 검색하면됩니다.

이제 8 개의 방향을 검색했습니다. 다음은 다른 스크립트에 의해 정확성이 검증 된 코드 입니다.

import Data.List
v=reverse
t=transpose
y=any
d r=zipWith(++)(scanr(\_->('\n':))[]r)r
g r w=y(y$y((==w).take(length w)).tails)[r,t r,t.d$r,t.d.v$r]
f r w=y(g(lines r))[w,v w]

함수 f는 우리가 원하는 것이고 그 인수 r는 사각형 문자열이며 w검색 할 단어입니다.


4

파이썬 2-246 259 275 308 298 297 294 313 322

w,s=input()
r=range
d='\n'
I=''.join
w=w.split(d)
t,u=len(w),len(w[0])
v=d.join([I(x)for x in zip(*w)]+[d]+[I([w[i+j][i]for i in r(min(u,t-j))])+d+I([w[i][i+j]for i in r(min(t,u-j))])for j in r(max(t,u))]+[d]+w)
print s in v or s[::-1]in v

인쇄 및 조인 정의를 처리하는 데 도움을 주신 Will에게 감사드립니다.

골프장을 올바르게 상기시켜주는 지하 철도 덕분에; p

구분 기호로 ','를 사용하여 일치하지 않는 문제를 해결했습니다.

골프를하는 가장 좋은 방법은 수 많은 수평 스크롤을 추가하는 것입니다.

등의 입력 공백의 줄 바꿈은 따옴표 라인을 구분 : "WVERTICALL \ nROOAFFLSAB \ nACRILIATOA \ nNDODKONWDC \ nDRKESOODDK \ nOEEPZEGLIW \ nMSIIHOAERA \ nALRKRRIRER \ nKODIDEDRCD \ nHELWSLEUTH", "RANDOM"


1
L=len;J=''.joinprint any(s in(v,d,w,r...))? 내가 당신을 게시했을 때 나는 같은 줄을 따라 가고 있었다 :)
Will

@Will 감사합니다! len을 정의하는 것은 절약하는 문자 수만큼 비용이 들며, 조인을 최적으로 정의하는 방법 (일부 쉼표가 있음)을 잘 모르겠으므로 조금만 살펴 보겠습니다.
FryAmTheEggman

공간 이 )있거나 ]그 뒤에 공간이 있으면 공간을 꺼낼 수 있습니다.
undergroundmonorail

2

APL (Dyalog Classic) , 44 바이트

1∊⍞⍷↑{⍉0,⍵,↑(0,⊢)\↓0,⍵}¨{⍉⌽⍵}\4⍴⊂↑a⊆⍨a≠⊃⌽a←⎕

온라인으로 사용해보십시오!


음, 죄송합니다. 여기에서 이와 같은 입력을받을 수없는 것 같습니다 . 분리 해야합니다 \n(즉 ⎕TC[2], 구분자로 사용).
Outgolfer Erik

@EriktheOutgolfer oh crap ... 나중에 고칠 게요. 감사.
ngn

불행히도 훨씬 더 긴 지금 수정
ngn

0

J , 60 53 바이트

<@[e.[:,[:(;|.)@>[:<\\.@>[:(<"1,</.)@>@(;|.@|:)[;.2@]

온라인으로 사용해보십시오!

첫 번째 입력에 줄 바꾸기가 없어야합니다.

설명:

linkrotate=: ;|.@|:     NB. link with itself rotated 90° ccw
infixes   =: <\\.       NB. list of boxes containing the infixes
lines     =: <"1 , </.  NB. horizontal and diagonal lines, boxed
linkrev   =: ;|.        NB. link with itself reversed
appearin  =: <@[ e. [: , [: linkrev@> [: infixes@> [: lines@>@linkrotate [;.2@]

온라인으로 사용해보십시오!

후크가 유용합니다.


것 같습니다 너무 작동합니다. (51 바이트)
user202729

0

젤리 , 16 바이트

해결 관련 (아마도 중복) 문제를 코드의 핵심으로 이들 16 바이트의 15 ...

ỴZU$3С;ŒD$€Ẏw€Ẹ

왼쪽에있는 문자 목록과 오른쪽에있는 문자 목록을 허용하는 이진 링크는 발견되면 1을, 그렇지 않으면 0을 리턴합니다.

온라인으로 사용해보십시오!

방법?

ZU$3С;ŒD$€Ẏw€Ẹ - Link: words, grid
   3С          - repeat three times and collect the results (inc input):
  $             -   last two links as a monad:
Z               -     transpose
 U              -     upend     (together these rotate by a quarter)
          €     - for €ach:
         $      -   last two links as a monad:
       ŒD       -     get forward-diagonals
      ;         -     concatenate
           Ẏ    - tighten (to get all the runs across the grid) 
             €  - for €ach run:
            w   -   sublist-index (0 if not found)
              Ẹ - any truthy? (i.e. was the word found?)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.