Apakah kata ini ada di papan boggle?

38

pengantar

Setelah seharian minum dan menonton piala dunia, Anda duduk untuk bermain game ramah boggle. Kemarahan meningkat ketika Anda dituduh membuang waktu semua orang dengan kata-kata yang tidak masuk akal yang bahkan tidak ada di papan tulis! Anda mungkin melihat ganda, tetapi pasti Anda berpikir jernih untuk menulis sebuah program yang akan memverifikasi bahwa kata-kata Anda ada di papan tulis.

Tugas Anda

Tulis program, skrip, atau fungsi yang menggunakan papan ganti dan kata sebagai input, dan mengembalikan True jika kata itu ada di papan tulis dan Salah jika kata itu tidak ada.

Input akan berupa enam \nbaris terbatas. Lima baris pertama akan terdiri dari papan boggle 5x5 dan masing-masing akan berisi lima huruf kapital. Baris keenam akan berisi kata-dalam-pertanyaan, juga dalam semua huruf kapital.

Masukan sampel:

AJNES
TNFTR
LSAIL
UDNEX
EQGMM
DAFTER

Outputnya bisa berupa apa saja yang secara jelas menandakan Benar atau Salah dalam bahasa pemrograman pilihan Anda dan mematuhi konvensi standar nol, nol, dan kosong yang menandakan False.

Contoh output untuk input di atas:

1

Pedoman I / O

  • Input dapat dibaca dari stdin, dan jawab output ke stdout.

Atau

  • Input mungkin berupa argumen string tunggal ke suatu fungsi, dan jawabannya adalah nilai balik dari fungsi itu.

Aturan Pertarungan

  • Sebuah kata 'on the board' jika Anda dapat membuat kata melalui jalur ubin yang berturut-turut, berdekatan, dan tidak berulang di papan tulis.
  • Ubin dianggap berdekatan dengan delapan ubin yang mengelilinginya (jalur diagonal diizinkan). Ubin di tepi papan berdekatan dengan hanya lima ubin. Ubin di sudut berdekatan dengan hanya tiga.
  • Huruf berurutan dalam kata harus bersebelahan, ihuruf ke dalam kata harus bersebelahan dengan huruf i-1th dan i+1th.
  • Sebuah huruf mungkin muncul dalam sebuah kata lebih dari satu kali, tetapi Anda tidak dapat menggunakan kotak yang sama pada papan boggle lebih dari sekali per kata.
  • Situs boggle online wordsplay.net mungkin berguna jika Anda belum pernah bermain boggle sebelumnya, tetapi ingin merasakan aturan ini.

Tidak seperti boggle biasa:

  • Anda TIDAK perlu khawatir tentang kata yang menjadi kata bahasa Inggris yang valid.
  • Tidak akan ada Quubin tunggal.
  • Kata-dalam-pertanyaan bisa panjang> 0

Contoh

Di papan tulis

AJNES
TNFTR
LSAIL
UDNEX
EQGMM

Kata-kata ini harus mengembalikan True: FATE, DATING, STANDS, LIFTS.

Kata-kata ini seharusnya menghasilkan False: SADDEN, SULTANS, EXIST, SUEDE, QUEST

Ini adalah tantangan kode-golf, jadi kode terpendek menang!

turbulencetoo
sumber
Apakah papan membungkus? Saya tidak ingat
Claudiu
Tidak tidak membungkus, saya memperbarui klarifikasi tentang kedekatan untuk mencerminkan ini.
turbulencetoo
Bisakah jalan itu melintas dengan sendirinya (secara diagonal)?
Martin Ender
@ m.buettner Yep
turbulencetoo
Boggle biasanya papan 4x4.
mbomb007

Jawaban:

11

GolfScript, 74 karakter

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

Masukan harus diberikan pada STDIN. Mencetak jumlah jalur yang valid di papan tulis, yaitu0 untuk tidak ada dan angka positif (benar) lain.

Anda dapat menguji contoh secara online .

Kode dengan beberapa komentar:

:^              # 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
Howard
sumber
12

Javascript (E6) 137 160 175 190

Kurang dari 2 * Golfscript. Kemenangan moral ...

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)

Edit reorganisasi kode golf. Lagi dan lagi

Ungolfed Versi terakhir, agak sulit untuk diikuti

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
  ) 

Versi Ungolfed First, harus lebih jelas

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
)

Pemakaian

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

Uji

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

Keluaran:

[["DAFTER", true], ["STANDS", true], ["LIFTS", true], ["FATE", true], ["DATING", true], 
["SADDEN", false], ["SULTANS", false], ["EXIST", false], ["SUEDE", false], ["QUEST", false]]
edc65
sumber
1
beberapa optimasi kecil: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
Apakah itu seharusnya (golf w = a.pop()) atau w = b.pop()(ungolfed, baris 2)? (mungkin yang terakhir, saya kira)
hlt
@androyd Saya meninggalkan kode ungolfed lama untuk kejelasan, setelah mengatur ulang. Tapi ini tidak 100% sinkron. Saya akan mencoba mengklarifikasi
edc65
Buruk saya, tidak melihat Anda berubah ke a=a.pop()bukannya b=a.pop()...
HLT
4

Python, 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))

Mengganti ... (b[i]==w[0])*any ...dengan ... b[i]==w[0]and any ...memberikan kinerja yang jauh lebih baik dengan biaya 2 karakter.

kotak kardus
sumber
1
Anda dapat memangkas spasi saat berada di antara angka dan perintah; 0<=i<25and
seequ
3

J - 75 char

Eugh, yang ini terlihat jahat. Dan bahkan tidak mengikat dengan Golfscript! Ini adalah fungsi yang mengambil string sebagai satu-satunya argumen. Anda dapat menggunakan pembatas satu karakter apa saja selama ditemukan di akhir setiap baris, termasuk yang terakhir.

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

Penjelasan berikut. Perhatikan bahwa fungsi dapat dibagi menjadi 5 bagian tingkat atas yang berbeda, masing-masing dipisahkan oleh @, jadi kami akan memperlakukan masing-masing bagian secara terpisah, dari kanan ke kiri.

  • (<;._2)- Ini membagi garis pada baris baru / karakter pemisah. Ini menggunakan karakter di akhir string sebagai karakter yang akan dibagi. Kami memasukkan semuanya ke dalam kotak ( <) karena jika tidak, kami akan mendapatkan beberapa masalah padding ketika J mengembalikan hasilnya.

  • (((<@#:i.)5 5)<@#~&,"2{:=/&:>}:) - Untuk setiap huruf dalam kata yang akan diperiksa, buat daftar indeks di papan Boggle tempat seseorang dapat menemukan surat itu.

    • {:adalah bagian split terakhir (kata untuk memeriksa) dan }:adalah segalanya tetapi yang terakhir (papan Boggle).

    • &:>membuka kotak yang kami buat sebelumnya, dengan produk sampingan yang berguna berubah }:menjadi array karakter 2D. =/kemudian buat salinan papan Boggle ini untuk setiap huruf dalam kata, dan ubah posisi menjadi boolean tergantung pada apakah huruf di papan cocok dengan huruf dalam kata.

    • ((<@#:i.)5 5)adalah cara singkat untuk mengekspresikan array indeks 5x5. x#:ydikonversi ymenjadi array xrepresentasi dasar . (Yah, hampir. Kebenarannya lebih kompleks, tetapi ini bekerja untuk tujuan kita.)

    • <@#~&,"2- Untuk matriks boolean yang dihasilkan setiap huruf, kumpulkan semua indeks yang sesuai yang benar bersama-sama. "2membuat semuanya bekerja pada hasil yang benar, #~&,melakukan pemilihan, dan <@mengumpulkan setiap hasil ke dalam kotak untuk mempersiapkan langkah selanjutnya.

  • {- Kata kerja ini, digunakan secara monadik, disebut Katalog, dan dibutuhkan daftar kotak sebagai argumen. Ini menggabungkan bagian dalam setiap kotak dengan segala cara yang mungkin. Jadi mis. Katalog pada beberapa kotak yang berisi string "AB" dan "abc" akan memberikan hasil "Aa", "Ab", "Ac", "Ba", "Bb", "Bc".

    Menjalankan ini pada daftar indeks kotak kami yang ada membuat setiap kemungkinan kombinasi indeks. Ini bisa menjadi set besar jika ada kata yang panjang dan ada banyak huruf yang diulang, tetapi juga kosong jika ada huruf yang tidak ada di papan tulis. Kami juga mencatat bahwa kami menggunakan kembali ubin di beberapa jalur ini: kami akan menjelaskannya nanti.

  • ([:*/"1^:2(2(=*)@-/\>@~.)S:1) - Di sini kita memeriksa setiap jalur untuk melihat apakah itu valid.

    • (...)S:1berlaku (...)untuk setiap jalur dan mengumpulkan hasilnya ke daftar datar. Ini sangat penting karena hasilnya {adalah array multi-dimensi, dan kami tidak peduli dengan struktur array itu, hanya isinya di setiap kotak.

    • 2(=*)@-/\>memberikan 1 jika setiap koordinat dari setiap indeks paling banyak berjarak satu dari yang mengikutinya, dan 0 sebaliknya. The 2dan /\yang bertanggung jawab untuk melakukan ini berpasangan.

    • */"1^:2logis-ANDs ini semua bersama-sama di akhir. Itu[: adalah hal struktural dalam J, jangan khawatir tentang hal itu.

    • Menambahkan @~.ke >sebenarnya adalah cara cerdas untuk mengecualikan jalur dengan entri berulang. ~.mengambil item unik dari daftar, jadi daftar ini dipersingkat jika berpotongan sendiri, dan daftar yang lebih pendek secara otomatis diisi dengan 0 ketika mereka disatukan, seperti cara hasilnya digabungkan saat keluar S:. Ini pada akhirnya lebih pendek daripada secara eksplisit mengecualikan jalur berpotongan sendiri.

  • +/- Akhirnya, kita cukup menambahkan semuanya bersama di akhir. Hasilnya adalah jumlah jalur yang valid yang membuat kata di papan tulis, dengan 0 yang berarti tidak ada jalur, artinya kata ini tidak ada di papan tulis. Untuk biaya satu karakter, kita dapat menulis +./(logis-ORing semuanya bersama-sama), yang secara eksplisit akan memberikan boolean 1 atau 0.

Berikut ini beberapa contoh run. Anda bisa mendapatkan juru J di jsoftware.com atau mencobanya online di 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
algoritme hiu
sumber
1
+1 untuk detailnya. Saya ingin melihat lebih banyak jawaban seperti ini!
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).

Saya pikir Prolog mungkin bahasa yang bagus untuk yang satu ini, dengan dukungan backtracking bawaan, tapi saya kira itu lebih cacat dengan membutuhkan variabel untuk hampir setiap nilai yang dihitung.

Diuji dengan GNU Prolog; harus sesuai dengan ISO Prolog.

Tidak Disatukan:

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, _, []).
aschepler
sumber