Là từ này trên bảng boggle?


38

Giới thiệu

Sau một ngày uống rượu và xem cúp thế giới, bạn ngồi xuống chơi trò chơi thân thiện của boggle. Nhiệt độ tăng lên khi bạn bị buộc tội lãng phí thời gian của mọi người với những từ vô nghĩa thậm chí không có trên bảng! Bạn có thể đang nhìn thấy gấp đôi, nhưng chắc chắn bạn đang suy nghĩ đủ để viết một chương trình sẽ xác minh rằng các từ của bạn có trên bảng.

Nhiệm vụ của bạn

Viết chương trình, tập lệnh hoặc hàm lấy bảng boggle và từ làm đầu vào và trả về True nếu từ nằm trên bảng và Sai nếu từ đó không.

Đầu vào sẽ ở dạng sáu \ndòng phân cách. Năm dòng đầu tiên sẽ bao gồm bảng boggle 5x5 và mỗi dòng sẽ chứa năm chữ in hoa. Dòng thứ sáu sẽ chứa từ trong câu hỏi, cũng trong tất cả các chữ in hoa.

Đầu vào mẫu:

AJNES
TNFTR
LSAIL
UDNEX
EQGMM
DAFTER

Đầu ra có thể là bất cứ điều gì biểu thị rõ ràng Đúng hoặc Sai trong ngôn ngữ lập trình bạn chọn và tuân thủ các quy ước chuẩn về 0, null và rỗng biểu thị Sai.

Đầu ra mẫu cho đầu vào trên:

1

Hướng dẫn I / O

  • Đầu vào có thể được đọc từ stdin và trả lời đầu ra cho thiết bị xuất chuẩn.

Hoặc là

  • Đầu vào có thể là một đối số chuỗi đơn cho một hàm và câu trả lời là giá trị trả về của hàm đó.

Quy tắc

  • Một từ là 'trên bảng' nếu bạn có thể tạo từ thông qua một đường dẫn liên tiếp, liền kề, không lặp lại trên bảng.
  • Một ô được coi là liền kề với tám ô bao quanh nó (đường chéo được cho phép). Gạch trên cạnh của bảng được liền kề chỉ năm gạch. Gạch trong góc liền kề chỉ có ba.
  • Các chữ cái liên tiếp trong từ phải liền kề, ichữ thứ trong từ phải liền kề với i-1th và i+1th.
  • Một chữ cái có thể xuất hiện trong một từ nhiều lần, nhưng bạn không thể sử dụng cùng một hình vuông trên bảng boggle nhiều hơn một lần cho mỗi từ.
  • Trang web boggle trực tuyến wordsplay.net có thể hữu ích nếu bạn chưa bao giờ chơi boggle trước đây, nhưng muốn cảm nhận về các quy tắc này.

Không giống như boggle thông thường:

  • Bạn KHÔNG phải lo lắng về từ này là một từ tiếng Anh hợp lệ.
  • Sẽ KHÔNG có Qugạch đơn.
  • Từ trong câu hỏi có thể có độ dài bất kỳ> 0

Thí dụ

Trên bảng của

AJNES
TNFTR
LSAIL
UDNEX
EQGMM

Những từ này sẽ trả về True: FATE, DATING, STANDS, LIFTS.

Những từ này sẽ trả về Sai: SADDEN, SULTans, EXIST, SUEDE, QUEST

Đây là một thử thách chơi gôn, vì vậy mã ngắn nhất sẽ thắng!


Bảng có bao quanh không? Tôi không thể nhớ
Claudiu

Không, nó không bao bọc, tôi đã cập nhật làm rõ về sự phụ thuộc để phản ánh điều này.
turbulencetoo

Đường dẫn có thể tự đi qua (theo đường chéo) không?
Martin Ender

@ m.buettner Yep
turbulencetoo

Boggle thường là một bảng 4 x 4.
mbomb007

Câu trả lời:


11

GolfScript, 74 ký tự

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

Đầu vào phải được đưa ra trên STDIN. In số lượng đường dẫn hợp lệ trên bảng, tức là 0không có và một số dương (đúng) khác.

Bạn có thể kiểm tra ví dụ trực tuyến .

Mã với một số ý kiến:

:^              # 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

Javascript (E6) 137 160 175 190

Ít hơn 2 * Golfscript. Chiến thắng đạo đức ...

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)

Chỉnh sửa sắp xếp lại mã Golfed. Lặp đi lặp lại

Ungolfed Phiên bản cuối cùng, một chút khó khăn để làm theo

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 Phiên bản đầu tiên, nên rõ ràng hơn

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
)

Sử dụng

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

Kiểm tra

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

Đầu ra:

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

1
một số tối ưu hóa nhỏ: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

Nó được cho là w = a.pop()(đánh gôn) hay w = b.pop()(không có tên, dòng 2)? (có lẽ là cái sau, tôi nghĩ vậy)
hlt

@androyd Tôi để lại mã không rõ ràng cũ hơn cho rõ ràng, sau khi tổ chức lại. Nhưng nó không đồng bộ 100%. Tôi sẽ cố gắng làm rõ
edc65

Thật tệ, tôi đã không thấy bạn thay đổi nó thành a=a.pop()thay vì b=a.pop()...
hlt

4

Con trăn, 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))

Thay thế ... (b[i]==w[0])*any ...bằng ... b[i]==w[0]and any ...cho hiệu suất tốt hơn nhiều với chi phí 2 ký tự.


1
Bạn có thể tắt khoảng trắng khi chúng nằm giữa số và lệnh; 0<=i<25and
xem

3

J - 75 char

Eugh, cái này có vẻ khó chịu. Và thậm chí không buộc với Golfscript! Đây là một hàm lấy một chuỗi làm đối số duy nhất của nó. Bạn có thể sử dụng bất kỳ dấu phân cách một ký tự nào miễn là nó được tìm thấy ở cuối mỗi dòng, bao gồm cả dòng cuối cùng.

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

Một lời giải thích sau đây. Lưu ý rằng chức năng có thể được phân tách thành 5 phần cấp cao nhất riêng biệt, mỗi phần được phân tách bằng nhau @, vì vậy chúng tôi sẽ xử lý riêng từng phần đó, từ phải sang trái.

  • (<;._2)- Điều này phân chia các dòng lên trên các dòng mới / ký tự phân cách. Nó sử dụng ký tự ở cuối chuỗi làm ký tự phân chia. Chúng tôi đặt mọi thứ vào các hộp ( <) bởi vì nếu chúng tôi không gặp phải một số vấn đề về đệm khi J trả lại kết quả cho chúng tôi.

  • (((<@#:i.)5 5)<@#~&,"2{:=/&:>}:) - Đối với mỗi chữ cái trong từ cần kiểm tra, hãy tạo một danh sách các chỉ mục trong bảng Boggle nơi người ta có thể tìm thấy chữ cái đó.

    • {:là phần tách cuối cùng (từ để kiểm tra) và }:là tất cả mọi thứ trừ phần cuối cùng (bảng Boggle).

    • &:>mở ra các hộp chúng ta đã tạo trước đây, với sản phẩm phụ hữu ích là biến }:thành một mảng các ký tự 2D. =/sau đó tạo một bản sao của bảng Boggle này cho mỗi chữ cái trong từ và biến các vị trí thành booleans tùy thuộc vào việc chữ cái trong bảng có khớp với chữ cái đó trong từ hay không.

    • ((<@#:i.)5 5)là một cách ngắn để thể hiện một mảng 5x5 của các chỉ số. x#:yđược chuyển đổi ythành một mảng của xbiểu diễn cơ sở . (Chà, gần như vậy. Sự thật phức tạp hơn, nhưng điều này hoạt động cho mục đích của chúng tôi.)

    • <@#~&,"2- Đối với ma trận boolean kết quả của mỗi chữ cái, thu thập tất cả các chỉ số đúng tương ứng với nhau. "2làm cho mọi thứ hoạt động trên kết quả đúng, #~&,thực hiện việc chọn và <@thu thập từng kết quả vào một hộp để chuẩn bị cho bước tiếp theo.

  • {- Động từ này, được sử dụng một cách đơn điệu, được gọi là Danh mục và nó lấy danh sách các hộp làm đối số. Nó kết hợp bên trong của mỗi hộp theo mọi cách có thể. Vì vậy, ví dụ một danh mục trên một số hộp chứa các chuỗi "AB" và "abc" sẽ cho kết quả "Aa", "Ab", "Ac", "Ba", "Bb", "Bc".

    Chạy này trên danh sách các danh sách các chỉ số được đóng hộp của chúng tôi làm cho mọi sự kết hợp có thể có của các chỉ mục. Đây có thể là một tập hợp lớn nếu có từ dài và có nhiều chữ cái lặp đi lặp lại, nhưng cũng trống nếu có bất kỳ chữ nào không có trên bảng. Chúng tôi cũng lưu ý rằng chúng tôi sử dụng lại các ô trong một số đường dẫn sau: chúng tôi sẽ tính đến việc này sau.

  • ([:*/"1^:2(2(=*)@-/\>@~.)S:1) - Ở đây chúng tôi kiểm tra từng đường dẫn để xem nó có hợp lệ không.

    • (...)S:1áp dụng (...)cho từng đường dẫn và thu thập các kết quả vào một danh sách phẳng. Điều này rất quan trọng vì kết quả của {một mảng đa chiều và chúng tôi không quan tâm đến cấu trúc của mảng đó, chỉ nội dung của nó ở mỗi hộp.

    • 2(=*)@-/\>cho 1 nếu mỗi tọa độ của mỗi chỉ số nhiều nhất là một tọa độ theo sau nó và 0 khác. Các 2/\có trách nhiệm làm điều này theo cặp.

    • */"1^:2logic-VÀ tất cả những thứ này cùng nhau ở cuối. Phần [:này là một thứ cấu trúc trong J, đừng lo lắng về nó.

    • Thêm @~.vào >thực sự là một cách thông minh để loại trừ các đường dẫn với các mục lặp lại. ~.lấy các mục duy nhất của danh sách, do đó, danh sách được rút ngắn nếu nó tự giao nhau và các danh sách ngắn hơn sẽ tự động được đệm bằng 0 khi chúng được đặt cùng nhau, giống như cách kết quả được kết hợp khi chúng xuất hiện S:. Điều này cuối cùng ngắn hơn so với việc loại trừ rõ ràng các đường dẫn tự giao nhau.

  • +/- Cuối cùng, chúng tôi chỉ đơn giản là thêm mọi thứ vào cuối. Kết quả là số lượng đường dẫn hợp lệ tạo ra từ trên bảng, với 0 có nghĩa là không có đường dẫn, nghĩa là từ này không có trên bảng. Đối với chi phí của một ký tự, chúng ta có thể viết +./(logic-ORing mọi thứ cùng nhau), điều này sẽ đưa ra một giá trị boolean 1 hoặc 0 rõ ràng.

Dưới đây là một số ví dụ chạy. Bạn có thể lấy thông dịch J tại jsoftware.com hoặc dùng thử trực tuyến tại 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 để biết chi tiết. Tôi muốn xem thêm câu trả lời như thế này!
edc65

2

Prolog - 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).

Tôi nghĩ Prolog có thể là một ngôn ngữ tốt cho ngôn ngữ này, với sự hỗ trợ quay lui tích hợp, nhưng tôi đoán nó bị khuyết tật hơn khi cần một biến cho hầu hết mọi giá trị được tính toán.

Đã thử nghiệm với GNU Prolog; phải tuân thủ ISO Prolog.

Ung dung:

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, _, []).
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.