这个单词在防呆板上吗?


38

介绍

经过一天的饮酒和看世界杯之后,您可以坐下来进行友谊赛。脾气暴躁,因为您被指控浪费甚至连板子上都没有的废话!您可能会看到两倍,但可以肯定的是,您正在思考的足够直截了当,可以编写一个程序来验证您的话语是否正确。

你的任务

编写一个程序,脚本或函数,该程序需要一个防呆板和一个单词作为输入,如果单词在板上,则返回True;否则,则返回False。

输入将采用六\n行分隔线的形式。前五行将由5x5防漏板组成,每行包含五个大写字母。第六行还将包含所有大写字母中的疑问词。

输入样例:

AJNES
TNFTR
LSAIL
UDNEX
EQGMM
DAFTER

输出可以是在您选择的编程语言中明确表示True或False并遵循零,null和空表示False的标准约定的任何内容。

以上输入的样本输出:

1

I / O准则

  • 可以从stdin读取输入,然后将输出应答到stdout。

要么

  • 输入可以是函数的单个字符串参数,答案是该函数的返回值。

僵局规则

  • 如果您可以通过板上连续的,相邻的,非重复的图块的路径构造单词,则该单词为“板上”。
  • 一个图块被认为与其周围的八个图块相邻(允许使用对角线路径)。木板边缘的瓷砖仅与五个瓷砖相邻。角落中的瓷砖仅相邻三个。
  • 单词中的连续字母必须相邻,单词中的ith字母必须相邻于i-1th和i+1th。
  • 一个单词中的一个字母可能会出现多次,但是每个单词中您不能在防虫板上使用相同的正方形。
  • 如果您以前从未玩过Boggle,但想了解这些规则,则在线Boggle网站wordsplay.net可能会有用。

与普通的boggle不同:

  • 您不必担心该单词是有效的英语单词。
  • 不会有Qu单个图块。
  • 疑问词的长度可以> 0

在董事会

AJNES
TNFTR
LSAIL
UDNEX
EQGMM

这些单词应返回True:FATE,DATING,STANDS,LIFTS。

这些单词应返回False:SADDEN,SULTANS,EXIST,SUEDE,QUEST

这是一个代码挑战,所以最短的代码胜出!


木板会绕吗?我不记得了
Claudiu 2014年

不,它没有包装,我更新了有关邻接的说明以反映这一点。
turbulencetoo

路径可以自己交叉(对角线)吗?
Martin Ender 2014年

@ m.buettner是
turbulencetoo

Boggle通常是4x4的主板。
mbomb007 '18

Answers:


11

GolfScript,74个字符

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

输入必须在STD​​IN上给出。在板上打印有效路径的数量,即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

的Javascript(E6)137 160 175 190

少于2 * Golfscript。道德上的胜利...

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)

编辑 Golfed代码重组。一次又一次

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第一版,应该更清晰

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 2014年

它应该是w = a.pop()(golfed)还是w = b.pop()(unolfeded,第2行)?(我想可能是后者)
2014年

@androyd在重组后,为了清晰起见,我留下了较旧的未编码代码。但这不是100%同步。我会尝试澄清
edc65 2014年

我的糟糕,没有看到您将其更改a=a.pop()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))

替换... (b[i]==w[0])*any ...... b[i]==w[0]and any ...可获得更好的性能,而只需2个字符。


1
当空格介于数字和命令之间时,可以删除空格;0<=i<25and
seequ 2014年

3

J-75字符

恩,这个人看起来很讨厌。甚至不跟Golfscript捆绑!这是一个以字符串为唯一参数的函数。您可以使用任何一个字符分隔符,只要在每行的末尾都可以找到它,包括最后一行。

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

解释如下。请注意,该函数可以分为5个不同的顶层部分,每个部分之间用分隔@,因此我们将从右到左分别处理每个部分。

  • (<;._2)-这将换行符/分隔符上的行分开。它使用字符串末尾的字符作为要分割的字符。我们将所有内容都放在方框(<)中,因为如果不这样做,当J将结果返回给我们时,我们会遇到一些填充问题。

  • (((<@#:i.)5 5)<@#~&,"2{:=/&:>}:) -对于要检查的单词中的每个字母,在Boggle面板中创建一个索引列表,您可以在其中找到该字母。

    • {:是最后一块(要检查的单词),除了最后一块(}:Buggle面板)以外的所有东西。

    • &:>打开我们之前制作的盒子,并将其}:变成二维字符数组的有用副产品。=/然后为单词中的每个字母制作此Boggle董事会的副本,并根据董事会中的字母是否与单词中的该字母匹配将位置转换为布尔值。

    • ((<@#:i.)5 5)是表示5x5索引数组的一种简短方法。x#:y将转换y为基本x表示形式的数组。(嗯,几乎。事实更复杂,但这对我们有用。)

    • <@#~&,"2-对于每个字母的布尔布尔矩阵,将所有相应的真实索引收集在一起。"2使所有工作都按正确的结果进行,#~&,进行选择,然后<@将每个结果收集到一个框中,为下一步做准备。

  • {-这个动词,通常用于单数形式,称为Catalogue,它以一个列表框作为参数。它以各种可能的方式结合了每个盒子的内部。因此,例如,在某些包含字符串“ AB”和“ abc”的盒子上的目录将给出结果“ Aa”,“ Ab”,“ Ac”,“ Ba”,“ Bb”,“ Bc”。

    在我们的索引列表的装箱列表中运行此选项,可以进行索引的所有可能组合。如果单词很长并且有很多重复的字母,这可能是一个很大的组合,但是如果黑板上没有任何字母,这可能是空的。我们还注意到,我们在其中一些路径中重用了图块:稍后我们将对此进行说明。

  • ([:*/"1^:2(2(=*)@-/\>@~.)S:1) -在这里,我们检查每条路径是否有效。

    • (...)S:1将应用于(...)每个路径,并将结果收集到一个平面列表中。这是至关重要的,因为的结果{是一个多维数组,我们不关心该数组的结构,而只关心每个框中的内容。

    • 2(=*)@-/\>如果每个索引的每个坐标距离其后一个坐标最多为1,则给出1,否则为0。在2/\负责做这个配对。

    • */"1^:2最后将所有这些逻辑与。该[:部分是J中的结构性事物,不必担心。

    • 添加@~.>实际上是一种排除重复条目路径的聪明方法。~.接受列表的唯一项,因此如果列表自相交,则会缩短列表,并且将较短的列表放在一起时会自动用0填充,就像结果从中出来时的合并方式一样S:。最终比明确排除自相交路径短。

  • +/-最后,我们只需在最后添加所有内容即可。结果是使单词在板上的有效路径数,0表示没有路径,即该单词不在板上。对于一个字符的代价,我们可以改写+./(将所有内容进行逻辑或运算),这将明确给出布尔值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 2014年

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 Prolog。

取消高尔夫:

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, _, []).
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.