이 단어가 boggle board에 있습니까?


38

소개

하루를 마시고 월드컵을 본 후에, 당신은 친절한 boggle 게임을하기 위해 앉습니다. 보드에 있지 않은 말도 안되는 단어로 모든 사람의 시간을 낭비한다고 비난하면서 성미가 높아집니다! 당신은 두 배로 보일지 모르지만 분명히 당신은 당신의 단어가 칠판에 있는지 확인하는 프로그램을 작성하기에 충분히 똑바로 생각하고 있습니다.

당신의 작업

boggle 보드와 단어를 입력으로 사용하고 단어가 보드에 있으면 True를, 단어가 없으면 False를 반환하는 프로그램, 스크립트 또는 함수를 작성하십시오.

입력은 6 개의 \n구분 된 줄 형식입니다 . 처음 5 줄은 5x5 boggle 보드로 구성되며 각각 5 개의 대문자를 포함합니다. 여섯 번째 줄에는 모든 대문자로 된 질문이 포함됩니다.

샘플 입력 :

AJNES
TNFTR
LSAIL
UDNEX
EQGMM
DAFTER

출력은 선택한 프로그래밍 언어에서 True 또는 False를 명확하게 나타내며 0, null 및 비어있는 False를 나타내는 표준 규칙을 준수합니다.

위 입력에 대한 샘플 출력 :

1

I / O 지침

  • stdin에서 입력을 읽고 stdout에 출력에 응답 할 수 있습니다.

또는

  • 입력은 함수에 대한 단일 문자열 인수 일 수 있으며 응답은 해당 함수의 리턴 값입니다.

보글 규칙

  • 보드에서 연속적이고 인접한 반복되지 않는 타일의 경로를 통해 단어를 구성 할 수있는 경우 단어는 '보드에 있습니다'.
  • 타일은 타일을 둘러싸고있는 8 개의 타일에 인접 해있는 것으로 간주됩니다 (대각선 경로가 허용됨). 보드 가장자리의 타일은 5 개의 타일에만 인접합니다. 모퉁이의 타일은 3 개에만 인접합니다.
  • 단어의 연속 문자는 인접해야하며 단어의 문자 ii-1th와 i+1th에 인접해야합니다 .
  • 글자에 단어가 두 번 이상 나타날 수 있지만 boggle 보드에서 같은 사각형을 단어 당 두 번 이상 사용할 수 없습니다.
  • 온라인 boggle 사이트 wordsplay.net 은 전에 boggle 을 해 본 적이 없지만 이러한 규칙에 대해 알고 싶을 때 유용 할 수 있습니다.

일반 boggle과 달리 :

  • 유효한 영어 단어라는 단어에 대해 걱정할 필요가 없습니다.
  • Qu단일 타일 은 없습니다 .
  • 질문에 포함 된 단어의 길이는 0보다 길 수 있습니다.

보드에

AJNES
TNFTR
LSAIL
UDNEX
EQGMM

이 단어는 FATE, DATING, STANDS, LIFTS로 True를 반환해야합니다.

이 단어는 False를 반환해야합니다. SADDEN, SULTANS, EXIST, SUEDE, QUEST

이것은 코드 골프 도전이므로 가장 짧은 코드가 승리합니다!


보드가 감겨 있습니까? 기억이 안나요
Claudiu

랩핑되지 않습니다.이를 반영하기 위해 인접성에 대한 설명을 업데이트했습니다.
turbulencetoo

경로가 (대각선으로) 교차 할 수 있습니까?
Martin Ender

@ m.buettner Yep
난기류

Boggle은 일반적으로 4x4 보드입니다.
mbomb007

답변:


11

GolfScript, 74 자

:^n%5>)]){{^@==}+29,\,{{+}+1$/}%\;}/{:s$..&=[s{.@-\}*;]1567`{7&.~)}%-!&},,

입력은 STDIN에 제공되어야합니다. 보드에 유효한 경로 수를 인쇄합니다. 즉 0, 없음과 양수 (true)입니다.

온라인 에서 예제를 테스트 할 수 있습니다 .

몇 가지 주석이있는 코드 :

:^              # assign the input to variable ^
n%              # split at newlines
5>              # truncate array such that [WORD] remains
)])             # prepares [[]] and WORD on the stack

# the following loop generates all possible paths (valid and invalid ones)
# by looking up all index combinations which yield the correct word
{               # loop over all characters
  {^@==}+29,\,  # get all indices of current character in the board
  {{+}+1$/}%\;  # append any index to all lists in the result set
}/              # end loop

# filter the results list for valid paths
{               # {...}, -> apply filter
  :s            # save path to variable s
  $..&=         # check if all numbers in path are unique
  [s{.@-\}*;]   # calculate differences along the path
  1567`{7&.~)}% # generate the array [1 -1 5 -5 6 -6 7 -7] of valid
                # differences
  -!            # check if all differences were valid
  &             # are both conditions fulfilled?
},              # end of filter block

,               # count the number of remaining paths

12

자바 (E6) 137 160 175 190

2 * 골프 스크립트 미만 도덕적 승리 ...

F=a=>[...a].some((e,p,b)=>(Q=(p,n)=>p>29||b[p]!=b[n]||(b.r|=!b[++n])||(b[p]=b[n+~[1,5,6,7].map(q=>Q(p+q,n)|Q(p-q,n),b[p]=0)]))(p,30)&b.r)

골프 코드 재구성을 편집하십시오 . 또 다시

Ungolfed 마지막 버전, 따라하기 까다로운

F = a => 
  [...a] // input string to array, 30 chars of board then the target word
  .some ( // use some to scan the board, return true when found
      (e,p,b)=> // params to callback: element, position, complete array 
      (         // NB array b has no .r property, so use it for return value (it's undefined at start) 
        Q = (p,n) =>         // Scan function, p=position in board, n=nth char of target word
          p > 29 ||          // Chaek if going outside the board to the target word
          b[p] != b[n] ||    // if invalid char at current position, return
          (b.r |= !b[++n]) ||  // if at end of target, set r to 1 and return (also increment n )
          (                  // else... (NB next tree lines are coalesced in golfed code)
            b[p] = 0,        // remove current char (to avoid reusing) 
            [1,5,6,7].map( q => Q(p+q,n)|Q(p-q,n)), // recursive call for + - 1,5,6,7
            b[p] = b[n-1]    // put current char into array again 
          )
      )(p,30) & b.r // initial position 0 in target word is 30 in the array
  ) 

Ungolfed First 버전은 더 명확해야합니다.

F = a => (
  b = a.split('\n'),
  w = b.pop(),
  r = 0,
  Q = (p, n) => 
    (r |= !w[n]) || 
    (
      b[p] = 0,
      [1,5,6,7,-1,-5,-6,-7].map( q => b[q+=p]==w[n] && Q(q,n+1)),
      b[p] = w[n-1]
    ),
  b = [...b+''],
  b.map((e, p) => e==w[0] && Q(p,1)),
  r
)

용법

F("AJNES\nTNFTR\nLSAIL\nUDNEX\nEQGMM\nLIFTS\nDAFTER")

테스트

['DAFTER', 'STANDS', 'LIFTS', 'FATE', 'DATING' ,
 'SADDEN','SULTANS', 'EXIST', 'SUEDE', 'QUEST']
.map(w => [w, F("AJNES\nTNFTR\nLSAIL\nUDNEX\nEQGMM\n" +w)])

산출:

[["DAFTER", true], ["STANDS", true], ["LIFTS", true], ["FATE", true], ["DATING", true], 
["SADDEN", false], ["SULTANS", false], ["EXIST", false], ["SUEDE", false], ["QUEST", false]]

1
약간의 최적화 :F=a=>(b=a.split('\n'),w=b.pop(Q=(p,n)=>((R|=!w[n])||(b[p]=0)||[1,5,6,7,-1,-5,-6,-7].map(q=>b[q+=p]==w[n]&&Q(q,n+1,b[q]=w[n])))),[Q(~~p,1)for(p in b=[...b.join(R=0)])if(b[p]==w[0])],R)
nderscore

이 있어야하는데 w = a.pop()(golfed) 또는 w = b.pop()(은, 2 호선을 ungolfed)? (아마도 후자라고 생각합니다)
hlt

@androyd 재구성 후 명확하지 않게 이전의 ungolfed 코드를 남겼습니다. 그러나 100 % 동기화 된 것은 아닙니다. 내가 명확히하려고합니다
edc65

내 나쁜, 당신이 a=a.pop()대신에 그것을 변경 보지 않았다 b=a.pop()...
hlt

4

파이썬 207 204 203

g=raw_input
r=range
b=''.join(g()for _ in r(5))
w=g()
s=lambda b,w,i:0<=i<25and(not w or(b[i]==w[0])*any(s(b[:i]+'_'+b[i+1:],w[1:],i+j+k*5-6)for j in r(3)for k in r(3)))
print any(s(b,w,i)for i in r(25))

대체 하면 2 자 비용으로 훨씬 더 나은 성능 ... (b[i]==w[0])*any ...... b[i]==w[0]and any ...제공합니다.


1
숫자와 명령 사이에있을 때 공백을 제거 할 수 있습니다. 0<=i<25and
seequ

3

J-75 자

어, 이건 불쾌 해 보인다 그리고 Golfscript 와도 관계가 없습니다! 이것은 문자열을 유일한 인수로 취하는 함수입니다. 마지막을 포함하여 각 줄의 끝에있는 한 문자 분리 문자를 사용할 수 있습니다.

+/@([:*/"1^:2(2(=*)@-/\>@~.)S:1)@{@(((<@#:i.)5 5)<@#~&,"2{:=/&:>}:)@(<;._2)

다음은 설명입니다. 함수는 각각으로 구분 된 5 개의 별개의 최상위 부분으로 나눌 수 있으므로 @각 부분을 오른쪽에서 왼쪽으로 개별 처리합니다.

  • (<;._2)-줄 바꿈 / 분리 문자로 줄을 나눕니다. 문자열 끝의 문자를 분할 할 문자로 사용합니다. 모든 것을 상자에 넣습니다 ( <). J가 결과를 돌려 줄 때 패딩 문제가 발생하지 않기 때문입니다.

  • (((<@#:i.)5 5)<@#~&,"2{:=/&:>}:) -확인할 단어의 각 문자에 대해 Boggle 보드에서 해당 문자를 찾을 수있는 색인 목록을 만듭니다.

    • {:마지막 분할 조각 (확인할 단어)이며 }:마지막 (Boggle 보드)을 제외한 모든 것입니다.

    • &:>}:2D 문자 배열로 전환하는 유용한 부산물과 함께 이전에 만든 상자를 엽니 다 . =/그런 다음 단어의 각 문자에 대해이 Boggle 보드의 사본을 만들고 보드의 문자가 단어의 해당 문자와 ​​일치하는지 여부에 따라 위치를 부울로 바꿉니다.

    • ((<@#:i.)5 5)5x5 인덱스 배열을 표현하는 짧은 방법입니다. x#:yy기본 x표현 의 배열 로 변환 됩니다 . (거의. 진실 은 더 복잡하지만 이것은 우리의 목적을 위해 작동합니다.)

    • <@#~&,"2-각 문자의 결과 부울 행렬에 대해 해당하는 실제 인덱스를 모두 수집합니다. "2올바른 결과를 위해 모든 작업을 #~&,수행하고 선택을 수행하고 <@각 결과를 상자에 수집하여 다음 단계를 준비합니다.

  • {-모나 딕 방식으로 사용되는이 동사는 카탈로그라고하며 상자 목록을 인수로 사용합니다. 각 박스의 내부를 가능한 모든 방식으로 결합합니다. 따라서 "AB"및 "abc"문자열을 포함하는 일부 상자의 카탈로그는 "Aa", "Ab", "Ac", "Ba", "Bb", "Bc"결과를 제공합니다.

    박스형 인덱스 목록에서 이것을 실행하면 가능한 모든 인덱스 조합을 만들 수 있습니다. 단어가 길고 반복되는 글자가 많으면 큰 세트가 될 수 있지만 보드에 글자가 없으면 비어 있습니다. 또한 이러한 경로 중 일부에서 타일을 재사용한다는 점을 참고하십시오. 나중에이를 설명하겠습니다.

  • ([:*/"1^:2(2(=*)@-/\>@~.)S:1) -여기서 각 경로가 유효한지 확인합니다.

    • (...)S:1(...)를 각 경로에 적용하고 결과를 플랫 목록으로 수집합니다. 결과는 {다차원 배열 이기 때문에 중요 합니다. 배열의 구조는 신경 쓰지 않고 각 상자의 내용 만 신경 쓰고 있습니다.

    • 2(=*)@-/\>각 인덱스의 각 좌표가 그 뒤에 오는 좌표에서 최대 1만큼 떨어져 있으면 1을, 그렇지 않으면 0을 제공합니다. 2과는 /\이 페어를 수행 할 책임이 있습니다.

    • */"1^:2논리 AND는 모두 마지막에 함께 모입니다. 이 [:부분은 J의 구조적 요소이므로 걱정하지 마십시오.

    • 에 추가 @~.하는 >것은 실제로 반복 된 항목이있는 경로를 제외하는 영리한 방법입니다. ~.는 목록의 고유 한 항목을 취하므로 목록이 자체 교차하면 목록이 단축되고 더 짧은 목록은 구성시 결과가 조합되는 방식과 같이 조합 될 때 자동으로 0으로 채워집니다 S:. 이는 자체 교차 경로를 명시 적으로 제외하는 것보다 궁극적으로 짧습니다.

  • +/-마지막으로 모든 것을 마지막에 함께 추가합니다. 결과는 보드에 단어를 만드는 유효한 경로의 수입니다. 0은 경로가 없음을 의미합니다. 즉,이 단어는 보드에 없습니다. 한 캐릭터의 비용을 +./대신하여 (논리 OR 모든 것을 함께 작성) 대신 부울 1 또는 0을 제공 할 수 있습니다.

다음은 몇 가지 예제 실행입니다. jsoftware.com 에서 J 인터프리터를 거나 tryj.tk 에서 온라인으로 시험해 볼 수 있습니다 .

   NB. the  0 : 0 ... )  thing is how you do multiline strings in J
   +/@([:*/"1^:2(2(=*)@-/\>@~.)S:1)@{@(((<@#:i.)5 5)<@#~&,"2{:=/&:>}:)@(<;._2) 0 : 0
AJNES
TNFTR
LSAIL
UDNEX
EQGMM
DAFTER
)
1
   b =: +/@([:*/"1^:2(2(=*)@-/\>@~.)S:1)@{@(((<@#:i.)5 5)<@#~&,"2{:=/&:>}:)@(<;._2)
   b 'AJNES TNFTR LSAIL UDNEX EQGMM FATE '    NB. any separator will do
1
   b 'AJNES TNFTR LSAIL UDNEX EQGMM SADDEN '  NB. not on the board
0
   b 'AJNES TNFTR LSAIL UDNEX EQGMM SANDS '   NB. self-intersecting path
0
   b 'AJNES TNFTR LSAIL UDNEX EQGMM MEND '    NB. multiple paths
2

1
자세한 내용은 +1입니다. 이런 식으로 더 많은 답변을보고 싶습니다!
edc65

2

프롤로그-315

r(L):-get_char(C),(C='\n',!,L=[];r(T),L=[C|T]).
b(0,[]):-!.
b(N,[R|T]):-M is N-1,r(R),b(M,T).
d(-1). d(0). d(1).
d([A,B],[C,D]):-d(X),C is A+X,d(Y),D is B+Y.
f([L|W],B,P,U):-P=[X,Y],nth(Y,B,R),nth(X,R,L),\+member(P,U),(W=[];d(P,Q),f(W,B,Q,[P|U])).
m:-b(5,B),r(W),f(W,B,_,[]),write(t);write(f).
:-initialization(m).

내장 된 역 추적 지원을 통해 Prolog가이 언어에 적합한 언어라고 생각했지만 거의 모든 계산 된 값에 대해 변수가 필요하므로 더 많은 장애가있는 것 같습니다.

GNU Prolog로 테스트했습니다. ISO 프롤로그를 준수해야합니다.

언 골프 드 :

get_line(Line) :-
    get_char(C),
    (   C='\n', !, Line=[]
    ;   get_line(Tail), Line=[C|Tail]
    ).

% The cut prevents recursion to help_get_board(-1, MoreRows)
% (and golfs one character shorter than putting N>0 in the second rule).
help_get_board(0, []) :- !.
help_get_board(N, [Row|Tail]) :-
    M is N-1, get_line(Row), help_get_board(M, Tail).

% The golfed version doesn't define an equivalent to get_board/1.
% help_get_board(5,Board) is used directly instead.
get_board(Board) :- help_get_board(5,Board).

small(-1). small(0). small(1).
step([X1,Y1],[X2,Y2]) :-
    small(DX), X2 is X1+DX,
    small(DY), Y2 is Y1+DY.

% The golfed version doesn't define an equivalent to letter_at/3.
% See find_word/4.
letter_at([X,Y], Letter, Board) :-
    nth(Y, Board, Row),
    nth(X, Row, Letter).

find_word([Letter|Word], Board, Pos1, Used) :-
%    letter_at(Pos1, Letter, Board),  % "inlined" to next three lines:
    ( Pos1 = [X,Y],
      nth(Y, Board, Row),
      nth(X, Row, Letter) ),
    \+member(Pos1, Used),
    (   Word=[]
    ;
        step(Pos1, Pos2),
        find_word(Word, Board, Pos2, [Pos1|Used])
    ).

main :-
    get_board(Board),
    get_line(Word),
    % Begin at any position. Initially no positions are "Used".
    find_word(Word, Board, _, []).
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.