Code Golf:单词搜索求解器

发布于 2024-08-27 16:49:59 字数 1606 浏览 5 评论 0 原文

注意:这是我的第一个 Code Golf 挑战/问题,因此我可能没有使用下面的正确格式。我不太确定如何标记这个特定问题,这应该是社区维基吗?谢谢!

这个 Code Golf 挑战是关于解决单词搜索的!

根据维基百科的定义,单词搜索是:

单词搜索,单词查找,单词查找, 单词侦探或神秘单词拼图是 一个单词游戏,是一个单词的字母 在网格中,通常有一个 长方形或正方形。这 这个谜题的目标是找到 并标记所有隐藏在里面的单词 盒子。这些话可能是 水平、垂直或 对角线。通常是隐藏的列表 提供了文字,但更多 具有挑战性的谜题可以让玩家 弄清楚它们。多词搜索 谜题有一个主题,所有的 隐藏的单词是相关的。

本次挑战的单词搜索将全部是矩形网格,其中包含要查找的单词列表。这些单词可以垂直、水平或对角书写


输入/输出

用户输入他们的单词搜索,然后输入要在网格中找到的单词。这两个输入将传递给您将要编写的函数。由您决定如何声明和处理这些对象。

使用下面描述的策略或您自己的策略之一,该函数在搜索中查找特定单词并输出其起始坐标(简单地行号和列号)和结束坐标。如果找到该单词两次出现,则必须输出两组坐标。如果该单词是回文,您可以任意选择一个末端作为该单词的“开始”。


示例

输入:

A I Y R J J Y T A S V Q T Z E 
X B X G R Z P W V T B K U F O 
E A F L V F J J I A G B A J K 
R E S U R E P U S C Y R S Y K 
F B B Q Y T K O I K H E W G N 
G L W Z F R F H L O R W A R E 
J A O S F U E H Q V L O A Z B 
J F B G I F Q X E E A L W A C 
F W K Z E U U R Z R T N P L D 
F L M P H D F W H F E C G W Z 
B J S V O A O Y D L M S T C R 
B E S J U V T C S O O X P F F 
R J T L C V W R N W L Q U F I 
B L T O O S Q V K R O W G N D 
B C D E J Y E L W X J D F X M 

要查找的单词:codegolf

输出:

row 12, column 8 --> row 5, column 1

策略

以下是您可以考虑使用的一些策略。您完全可以决定要使用什么策略;它不必在此列表中。

  • 寻找单词的第一个字母;每次出现时,查看周围的八个字母,看看该单词的下一个字母是否存在。
  • 与上面相同,只是查找单词中两个并排的相同字母的部分。
  • 计算字母表中每个字母在整个网格中出现的频率,然后从要查找的单词中选择出现次数最少的字母之一并搜索该字母。每次出现该字母时,您都会查看其周围的八个字母,以查看该单词的下一个和上一个字母是否存在。

Note: This is my first Code Golf challenge/question, so I might not be using the correct format below. I'm not really sure how to tag this particular question, and should this be community wiki? Thanks!

This Code Golf challenge is about solving word searches!

A word search, as defined by Wikipedia, is:

A word search, word find, word seek,
word sleuth or mystery word puzzle is
a word game that is letters of a word
in a grid, that usually has a
rectangular or square shape. The
objective of this puzzle is to find
and mark all the words hidden inside
the box. The words may be
horizontally, vertically or
diagonally. Often a list of the hidden
words is provided, but more
challenging puzzles may let the player
figure them out. Many word search
puzzles have a theme to which all the
hidden words are related.

The word searches for this challenge will all be rectangular grids with a list of words to find provided. The words can be written vertically, horizontally, or diagonally.


Input/Output

The user inputs their word search and then inputs a word to be found in their grid. These two inputs are passed to the function that you will be writing. It is up to you how you want to declare and handle these objects.

Using a strategy described below or one of your own, the function finds the specific word in the search and outputs its starting coordinates (simply row number and column number) and ending coordinates. If you find two occurrences of the word, you must output both sets of coordinates. If the word is a palindrome, you may arbitrarily choose one end to be the "start" of the word.


Example

Input:

A I Y R J J Y T A S V Q T Z E 
X B X G R Z P W V T B K U F O 
E A F L V F J J I A G B A J K 
R E S U R E P U S C Y R S Y K 
F B B Q Y T K O I K H E W G N 
G L W Z F R F H L O R W A R E 
J A O S F U E H Q V L O A Z B 
J F B G I F Q X E E A L W A C 
F W K Z E U U R Z R T N P L D 
F L M P H D F W H F E C G W Z 
B J S V O A O Y D L M S T C R 
B E S J U V T C S O O X P F F 
R J T L C V W R N W L Q U F I 
B L T O O S Q V K R O W G N D 
B C D E J Y E L W X J D F X M 

Word to find: codegolf

Output:

row 12, column 8 --> row 5, column 1

Strategies

Here are a few strategies you might consider using. It is completely up to you to decide what strategy you want to use; it doesn't have to be in this list.

  • Looking for the first letter of the word; on each occurrence, looking at the eight surrounding letters to see whether the next letter of the word is there.
  • Same as above, except looking for a part of a word that has two of the same letter side-by-side.
  • Counting how often each letter of the alphabet is present in the whole grid, then selecting one of the least-occurring letters from the word you have to find and searching for the letter. On each occurrence of the letter, you look at its eight surrounding letters to see whether the next and previous letters of the word is there.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

陌若浮生 2024-09-03 16:49:59

Python - 186 个字符

def f(g,W):w=g.find("\n")+1;L=len(W);print" --> ".join("row %s, column %s"%(x/w+1
,x%w+1)for i in range(len(g))for j in(-w-1,-w,-w+1,-1,1,w-1,w,w+1)for x in(i,i+(L
-1)*j)if g[i::j][:L]==W)

测试代码:

grid="""A I Y R J J Y T A S V Q T Z E 
X B X G R Z P W V T B K U F O 
E A F L V F J J I A G B A J K 
R E S U R E P U S C Y R S Y K 
F B B Q Y T K O I K H E W G N 
G L W Z F R F H L O R W A R E 
J A O S F U E H Q V L O A Z B 
J F B G I F Q X E E A L W A C 
F W K Z E U U R Z R T N P L D 
F L M P H D F W H F E C G W Z 
B J S V O A O Y D L M S T C R 
B E S J U V T C S O O X P F F 
R J T L C V W R N W L Q U F I 
B L T O O S Q V K R O W G N D 
B C D E J Y E L W X J D F X M """.lower().replace(" ","")
f(grid,"codegolf")
f(grid,"serverfault")
f(grid,"superuser")

此版本为 196 个字符,接受网格,无需进行任何额外的调整

def f(g,W):w=g.find("\n")+1;L=len(W);print" --> ".join("row %s, column %s"%(x/w+1,x%w/2+1)for i in range(len(g))for j in(-w-2,-w,-w+2,-2,2,w-2,w,w+2)for x in(i,i+(L-1)*j)if g[i::j][:L].lower()==W)

测试代码:

grid="""A I Y R J J Y T A S V Q T Z E 
X B X G R Z P W V T B K U F O 
E A F L V F J J I A G B A J K 
R E S U R E P U S C Y R S Y K 
F B B Q Y T K O I K H E W G N 
G L W Z F R F H L O R W A R E 
J A O S F U E H Q V L O A Z B 
J F B G I F Q X E E A L W A C 
F W K Z E U U R Z R T N P L D 
F L M P H D F W H F E C G W Z 
B J S V O A O Y D L M S T C R 
B E S J U V T C S O O X P F F 
R J T L C V W R N W L Q U F I 
B L T O O S Q V K R O W G N D 
B C D E J Y E L W X J D F X M """
f(grid,"codegolf")
f(grid,"serverfault")
f(grid,"superuser")

Python - 186 chars

def f(g,W):w=g.find("\n")+1;L=len(W);print" --> ".join("row %s, column %s"%(x/w+1
,x%w+1)for i in range(len(g))for j in(-w-1,-w,-w+1,-1,1,w-1,w,w+1)for x in(i,i+(L
-1)*j)if g[i::j][:L]==W)

testing code:

grid="""A I Y R J J Y T A S V Q T Z E 
X B X G R Z P W V T B K U F O 
E A F L V F J J I A G B A J K 
R E S U R E P U S C Y R S Y K 
F B B Q Y T K O I K H E W G N 
G L W Z F R F H L O R W A R E 
J A O S F U E H Q V L O A Z B 
J F B G I F Q X E E A L W A C 
F W K Z E U U R Z R T N P L D 
F L M P H D F W H F E C G W Z 
B J S V O A O Y D L M S T C R 
B E S J U V T C S O O X P F F 
R J T L C V W R N W L Q U F I 
B L T O O S Q V K R O W G N D 
B C D E J Y E L W X J D F X M """.lower().replace(" ","")
f(grid,"codegolf")
f(grid,"serverfault")
f(grid,"superuser")

This version is 196 chars and accepts the grid without doing any extra tweaking

def f(g,W):w=g.find("\n")+1;L=len(W);print" --> ".join("row %s, column %s"%(x/w+1,x%w/2+1)for i in range(len(g))for j in(-w-2,-w,-w+2,-2,2,w-2,w,w+2)for x in(i,i+(L-1)*j)if g[i::j][:L].lower()==W)

testing code:

grid="""A I Y R J J Y T A S V Q T Z E 
X B X G R Z P W V T B K U F O 
E A F L V F J J I A G B A J K 
R E S U R E P U S C Y R S Y K 
F B B Q Y T K O I K H E W G N 
G L W Z F R F H L O R W A R E 
J A O S F U E H Q V L O A Z B 
J F B G I F Q X E E A L W A C 
F W K Z E U U R Z R T N P L D 
F L M P H D F W H F E C G W Z 
B J S V O A O Y D L M S T C R 
B E S J U V T C S O O X P F F 
R J T L C V W R N W L Q U F I 
B L T O O S Q V K R O W G N D 
B C D E J Y E L W X J D F X M """
f(grid,"codegolf")
f(grid,"serverfault")
f(grid,"superuser")
淡写薰衣草的香 2024-09-03 16:49:59

Perl,226 字符

sub h($){"row ",$%=1+($x=pop)/$W,", column ",1+$x%$W}
@S=map/[^ ]/g,<STDIN>;
B:for(@ARGV){
 for$d(map{$_,-$_}1,$W=@S/$.,$W-1,$W+1){
  A:for$s(0..$#S){
   $t=$s-$d;for(/./g){next A if$S[$t+=$d]ne$_||$t<0}
   print h$s,' --> ',h$t,$/;
   next B
}}}

字符计数不包括换行符和缩进,包括这些是为了提高可读性。
我假设字母矩阵是用标准输入指定的,目标单词是命令行参数。

第一行(在 sub h 定义之后)将所有非空格字符映射到单个数组 @S 中。然后迭代所有目标单词、单词可能出现的方向($W 是拼图的宽度)以及当前目标单词中的所有字母,直到匹配为止成立。

$ perl wordsearch.pl CODEGOLF RACECAR BYKLHQU <<EOF
A I Y R J J Y T A S V Q T Z E 
X B X G R Z P W V T B K U F O 
E A F L V F J J I A G B A J K 
R E S U R E P U S C Y R S Y K 
F B B Q Y T K O I K H E W G N 
G L W Z F R F H L O R W A R E 
J A O S F U E H Q V L O A Z B 
J F B G I F Q X E E A L W A C 
F W K Z E U U R Z R T R A C E 
C A R P H D F W H F E C G W Z 
B J S V O A O Y D L M S T C R 
B E S J U V T C S O O X P F F 
R J T L C V W R N W L Q U F I 
B L R A C E C A R R O W G N D 
B C D E J Y E L W X J D F X M 
EOF
row 12, column 8 --> row 5, column 1
row 14, column 3 --> row 14, column 9
row 3, column 12 --> row 9, column 6

Perl, 226 char

sub h($){"row ",$%=1+($x=pop)/$W,", column ",1+$x%$W}
@S=map/[^ ]/g,<STDIN>;
B:for(@ARGV){
 for$d(map{$_,-$_}1,$W=@S/$.,$W-1,$W+1){
  A:for$s(0..$#S){
   $t=$s-$d;for(/./g){next A if$S[$t+=$d]ne$_||$t<0}
   print h$s,' --> ',h$t,$/;
   next B
}}}

Character count excludes newlines and indentation, which are included for readability.
I assume the matrix of letters is specified with standard input and the target words are command-line arguments.

First line (after the sub h definition) maps all non-space characters into a single array @S. Then iterate over all the target words, over the possible directions that words may appear in ($W is the width of the puzzle), and over all of the letters in the current target word until a match is found.

$ perl wordsearch.pl CODEGOLF RACECAR BYKLHQU <<EOF
A I Y R J J Y T A S V Q T Z E 
X B X G R Z P W V T B K U F O 
E A F L V F J J I A G B A J K 
R E S U R E P U S C Y R S Y K 
F B B Q Y T K O I K H E W G N 
G L W Z F R F H L O R W A R E 
J A O S F U E H Q V L O A Z B 
J F B G I F Q X E E A L W A C 
F W K Z E U U R Z R T R A C E 
C A R P H D F W H F E C G W Z 
B J S V O A O Y D L M S T C R 
B E S J U V T C S O O X P F F 
R J T L C V W R N W L Q U F I 
B L R A C E C A R R O W G N D 
B C D E J Y E L W X J D F X M 
EOF
row 12, column 8 --> row 5, column 1
row 14, column 3 --> row 14, column 9
row 3, column 12 --> row 9, column 6
浅紫色的梦幻 2024-09-03 16:49:59

Perl - 243

(不包括换行符,所有这些都是可选的)

大部分 de-golfed 代码都可以在这里找到.

$/="";@w=split//,pop;($b=<>)=~y/ //d;$W=1+index$b,"\n";
for(1,2){for(0,$W-2..$W){$p=join"."x$_,@w;
push@m,[$-[0],$+[0]-1]while$b=~/$p/sg}
@w=reverse@w;@m=map[reverse@$_],@m}
$t="row %d, column %d";
printf"$t --> $t\n",map{1+$_/$W,1+$_%$W}@$_ for@m;

用法:作为脚本运行。从文件中读取的 wordsearch.pl boardfile searchword 或从 STDIN 读取板的 wordsearch.pl searchword (嘿,pop 是两个比 shift 短的字符!)

这个想法是我们将棋盘读入一个字符串(扔掉字母之间的额外空格),并记下它的宽度(通过计算字符直到第一个字符)换行)。然后,我们进行一系列正则表达式匹配来查找单词,使用 s 正则表达式修饰符允许匹配跨行。给定一个 4 个字母宽的板(因此每行有 5 个字符,包括换行符)和搜索词“CAR”,我们可以使模式 /CAR/ 向前匹配,/C ...A...R/ 匹配向西南方向,/C....A....R/ 匹配向下方向,/C。 ....A.....R/ 匹配东南方向。对于每场比赛,我们都会记录比赛的开始和结束位置。

然后我们反转搜索词(“CAR”->“RAC”)并再次执行,这让我们可以匹配向左、向上、西北和东北的单词。当然,我们要确保开始/结束位置也交换。为了节省代码,我交换了匹配位置两次;前向单词的匹配项会交换两次(因此它们不会被交换),而后向单词的匹配项只会交换一次,因此它们会被交换。

最后,只需将匹配偏移量放入棋盘字符串中并将它们转换为行/列对,然后按照问题所需的方式格式化输出即可。

Perl - 243

(Not including linebreaks, all of which are optional)

Mostly de-golfed code can be found here.

$/="";@w=split//,pop;($b=<>)=~y/ //d;$W=1+index$b,"\n";
for(1,2){for(0,$W-2..$W){$p=join"."x$_,@w;
push@m,[$-[0],$+[0]-1]while$b=~/$p/sg}
@w=reverse@w;@m=map[reverse@$_],@m}
$t="row %d, column %d";
printf"$t --> $t\n",map{1+$_/$W,1+$_%$W}@$_ for@m;

Usage: run as a script. Either wordsearch.pl boardfile searchword to read from a file, or wordsearch.pl searchword to read the board from STDIN (hey, pop is two characters shorter than shift!)

The idea is that we read the board into a string (throwing away the extra spaces between letters), and also make note of how wide it is (by counting characters until the first newline). Then we do a series of regex matches to find the word, using the s regex modifier to allow a match to span lines. Given a board that's 4 letters wide (so each line is 5 chars including newline), and the search word "CAR", we can make the patterns /CAR/ to match forwards, /C...A...R/ to match going southwest, /C....A....R/ to match going downwards, and /C.....A.....R/ to match going southeast. For each match, we record the starting and ending positions of the match.

Then we reverse the search word ("CAR" -> "RAC") and do it again, which lets us match the word going left, up, northwest, and northeast. Of course, we want to make sure that the start/end positions are also swapped. To save code, I swap the match positions twice; the matches for the forward word are swapped both times (so they come out un-swapped), while the matches for the backward word are only swapped once, so they will come out swapped.

Finally, it's just a matter of taking the match offsets into the board string and turning them into row/column pairs, and formatting the output how the problem wants it.

雾里花 2024-09-03 16:49:59

AWK - 252 255

NF<2{l=split($1,w,"")}NF>1{for(i=1;i<=NF;)t[x=i++,y=NR]=$i}END{
for(i=1;i<=x;++i)for(j=0;++j<=y;)for(a=0;a<9;++a)if(t[I=i,J=j]==w[1])
for(k=1;k<l;){if(!(T=t[I+=int(a/3)-1,J+=a%3-1])||T!=w[++k])break;if(k==l)
print"row "j (B=", column ")i" --> row "J B I}}

输入应采用以下形式

....
B L T O O S Q V K R O W G N D 
B C D E J Y E L W X J D F X M 
CODEGOLF

AWK - 252 255

NF<2{l=split($1,w,"")}NF>1{for(i=1;i<=NF;)t[x=i++,y=NR]=$i}END{
for(i=1;i<=x;++i)for(j=0;++j<=y;)for(a=0;a<9;++a)if(t[I=i,J=j]==w[1])
for(k=1;k<l;){if(!(T=t[I+=int(a/3)-1,J+=a%3-1])||T!=w[++k])break;if(k==l)
print"row "j (B=", column ")i" --> row "J B I}}

The input should be in the form

....
B L T O O S Q V K R O W G N D 
B C D E J Y E L W X J D F X M 
CODEGOLF
谢绝鈎搭 2024-09-03 16:49:59

Python,318笔画。

from itertools import*
f=lambda x,y,i,j,n:(x-i+1,y-j+1)*(not n)or all((2*i+j,x+1,y+1,x<c,y<d))and a[x][y*2]==n[0]and f(x+i,y+j,i,j,n[1:])
w=raw_input
a=list(iter(w,''))
c=len(a)
d=len(a[0])/2
r=range
z=r(-1,2)
s='row %d, column %d'
for x in product(r(c),r(d),z,z,[w()]):
 if f(*x):print s%(x[0]+1,x[1]+1),'-->',s%f(*x)


Sample input:

A I Y R J J Y T A S V Q T Z E 
X C O D E G O L F B K U F O Z
E A F L V F J J I A G B A J K 
R E S U R E P U S C Y R S Y K 
F B B Q Y T K O I K H E W G N 
G L W Z F R F H L O R W A R E 
J A O S F U E H Q V L O A Z B 
J F B G I F Q X E E A L W A C 
F W K Z E U U R Z R T N P L D 
F L M P H D F W H F E C G W Z 
B J S V O A O Y D L M S T C R 
B E S J U V T C S O O X P F F 
R J T L C V W R N W L Q U F I 
B L T O O S Q V K R O W G N D 
B C D E J Y E L W X J D F X M 

CODEGOLF

输出:

$ python wordsearch < wordsearchinput.txt
row 2, column 2 --> row 2, column 9
row 12, column 8 --> row 5, column 1

根据“编辑答案而不是评论如何我应该修复此问题”许可证发布。

Python, 318 strokes.

from itertools import*
f=lambda x,y,i,j,n:(x-i+1,y-j+1)*(not n)or all((2*i+j,x+1,y+1,x<c,y<d))and a[x][y*2]==n[0]and f(x+i,y+j,i,j,n[1:])
w=raw_input
a=list(iter(w,''))
c=len(a)
d=len(a[0])/2
r=range
z=r(-1,2)
s='row %d, column %d'
for x in product(r(c),r(d),z,z,[w()]):
 if f(*x):print s%(x[0]+1,x[1]+1),'-->',s%f(*x)


Sample input:

A I Y R J J Y T A S V Q T Z E 
X C O D E G O L F B K U F O Z
E A F L V F J J I A G B A J K 
R E S U R E P U S C Y R S Y K 
F B B Q Y T K O I K H E W G N 
G L W Z F R F H L O R W A R E 
J A O S F U E H Q V L O A Z B 
J F B G I F Q X E E A L W A C 
F W K Z E U U R Z R T N P L D 
F L M P H D F W H F E C G W Z 
B J S V O A O Y D L M S T C R 
B E S J U V T C S O O X P F F 
R J T L C V W R N W L Q U F I 
B L T O O S Q V K R O W G N D 
B C D E J Y E L W X J D F X M 

CODEGOLF

Output:

$ python wordsearch < wordsearchinput.txt
row 2, column 2 --> row 2, column 9
row 12, column 8 --> row 5, column 1

Released under the "edit-the-answer-instead-of-commenting-on-how-I-should-fix-this" license.

寄居者 2024-09-03 16:49:59

C++ C,411 400 388 367 个字符

我第一次尝试代码高尔夫。

#include<stdio.h>
main(){char m[999],w[99];int r,c,l=-1,x=-1,y=-1,i=0,j,k;scanf("%s %d %d"
,w,&r,&c);for(;w[l+1];++l);for(;i<r*c;scanf("%s",&m[i++]));for(;y<2;++y)
for(;x<2;++x)if(x|y)for(i=(y<0)*l;i<r-(y>0)*l;++i)for(j=(x<0)*l;j<c-(x>0
)*l;++j)for(k=0;k<=l&&w[k++]==m[(i+k*y)*c+j+k*x];)k>l?printf(
"row %i, column %i --> row %i, column %i\n",i+1,j+1,i+y*l+1,j+x*l+1):0;}

它在 gcc 上编译时不会发出警告,也没有附加标志。

这是带有空格的版本:

#include<stdio.h>
main() {
    char m[999], w[99];
    int r, c, l = -1, x = -1, y = -1, i = 0, j, k;

    scanf("%s %d %d", w, &r, &c);
    for (; w[l+1]; ++l);
    for (; i < r*c; scanf("%s", &m[i++]));
    for (; y < 2; ++y)
        for (; x < 2; ++x)
            if (x | y)
                for (i = (y<0) * l; i < r - (y>0) * l; ++i)
                    for (j = (x<0) * l; j < c - (x>0) * l; ++j)
                        for (k = 0; k <= l && w[k++] == m[(i+k*y) * c + j+k*x];)
                            k > l ? printf("row %i, column %i --> row %i, column %i\n",
                                    i + 1, j + 1, i + y*l + 1, j + x*l + 1)
                                  : 0;
}

标准输入上的预期输入如下所示:

CODEGOLF 15 15
A I Y R J J Y T A S V Q T Z E
X B X G R Z P W V T B K U F O
...

其中 15 15 分别是行数和列数。

由于这是我的第一轮高尔夫球,并且我可以在网上找到一些宝贵的常见技巧,因此我将列出一些我发现的:

  • 尝试将循环体保留在单个语句中以节省胡须(2 个字符) .
    示例:使用逗号运算符的任何内容。

  • 尽可能使用条件表达式 (?:) 代替 if(1 个字符)。
    示例:代替 if(x)printf("");,编写 x?printf(""):0;。这是有效的,因为 printf 返回 int

  • 使用布尔值作为 int(?字符)时为 01 的事实。
    示例:用 r-(y>0)*l 代替 (y>0?rl:r)。这里的节省在括号中,这在这种情况下是必要的。

  • while 循环绝不会比 for 循环短,而且大多数情况下会更长(>= 0 个字符)。
    示例while(x)y;for(;x;y); 一样长,但带有 for 您也可以使用循环体,而无需支付额外的 ; 费用。

  • 将循环增量放入使用循环计数器(1 个字符)的最后一个表达式中。
    示例:代替 for(;x,编写 for(;x ;)printf("%i",x++);.

  • 保留main的返回类型(4个字符)。

  • 保留mainreturn语句(9个字符)。

  • 尽可能使用 &| 而不是 &&||(1 个字符).
    示例:用 if(x||y) 代替 if(x||y)。仅当您不依赖 &&|| 的短路行为时,这才有效。

  • 内联 strlen 函数并删除 #include(11 个字符)。

如果您不关心编译器警告:

  • 请勿包含任何标头(许多字符)。

C++ C, 411 400 388 367 characters

My first attempt ever at a code golf.

#include<stdio.h>
main(){char m[999],w[99];int r,c,l=-1,x=-1,y=-1,i=0,j,k;scanf("%s %d %d"
,w,&r,&c);for(;w[l+1];++l);for(;i<r*c;scanf("%s",&m[i++]));for(;y<2;++y)
for(;x<2;++x)if(x|y)for(i=(y<0)*l;i<r-(y>0)*l;++i)for(j=(x<0)*l;j<c-(x>0
)*l;++j)for(k=0;k<=l&&w[k++]==m[(i+k*y)*c+j+k*x];)k>l?printf(
"row %i, column %i --> row %i, column %i\n",i+1,j+1,i+y*l+1,j+x*l+1):0;}

It compiles without warnings on gcc with no additional flags.

Here's the version with whitespace:

#include<stdio.h>
main() {
    char m[999], w[99];
    int r, c, l = -1, x = -1, y = -1, i = 0, j, k;

    scanf("%s %d %d", w, &r, &c);
    for (; w[l+1]; ++l);
    for (; i < r*c; scanf("%s", &m[i++]));
    for (; y < 2; ++y)
        for (; x < 2; ++x)
            if (x | y)
                for (i = (y<0) * l; i < r - (y>0) * l; ++i)
                    for (j = (x<0) * l; j < c - (x>0) * l; ++j)
                        for (k = 0; k <= l && w[k++] == m[(i+k*y) * c + j+k*x];)
                            k > l ? printf("row %i, column %i --> row %i, column %i\n",
                                    i + 1, j + 1, i + y*l + 1, j + x*l + 1)
                                  : 0;
}

Expected input on stdin looks like:

CODEGOLF 15 15
A I Y R J J Y T A S V Q T Z E
X B X G R Z P W V T B K U F O
...

where 15 15 are the numbers of rows and columns, respectively.

Since this is my first round of golf, and I could find precious little common tricks on the web, I'll list some that I found:

  • Try to keep loop bodies to a single statement to save on moustaches (2 chars).
    Example: anything using the comma operator.

  • Use a conditional expression (?:) instead of an if when you can (1 char).
    Example: instead of if(x)printf("");, write x?printf(""):0;. This works because printf returns int.

  • Use the fact that booleans are 0 or 1 when used as an int (? chars).
    Example: instead of (y>0?r-l:r), write r-(y>0)*l. The savings here are in the parentheses, which were necessary in this situation.

  • while loops are never shorter than for loops, and longer most of the time (>= 0 chars).
    Example: while(x)y; is just as long as for(;x;y); but with for you get the loop body to play with as well, without paying for the extra ;.

  • Put your loop increments into the last expression that uses the loop counter (1 char).
    Example: instead of for(;x<b;++x)printf("%i",x);, write for(;x<b;)printf("%i",x++);.

  • Leave off main's return type (4 chars).

  • Leave off main's return statement (9 chars).

  • Use & and | instead of && and || whenever possible (1 char).
    Example: instead of if(x||y), write if(x|y). This only works if you don't depend on the short-circuit behaviour of && and ||.

  • Inline the strlen function and remove #include<string.h> (11 chars).

If you don't care about compiler warnings:

  • Do not include any headers (many chars).
软糯酥胸 2024-09-03 16:49:59

Python: 491 - 353 个字符

我想仍然有很大的改进空间,欢迎所有评论。

策略:找到第一个字母的所有出现,然后尝试从各个方向获取该单词。

import sys;r=range(-1,2);k=''.join;q="row %s, column %s"
a=[l[:-1:2]for l in sys.stdin]
b=sys.argv[1];c=len(a[0])
for x,y in[(x/c,x%c)for x,h in enumerate(k(map(k,a)))]:
 for i,j in[(i,j)for i in r for j in r if i or j<>0]:
  if k([a[x+z*i][y+z*j]for z in range(len(b))if 0<=x+z*i<c and 0<=y+z*j<len(a)])==b:print q%(x+1,y+1)+" --> "+q%(x+z*i+1,y+z*j+1)

用法示例:

猫输入.txt | python test.py CODEGOLF

示例输出:

第 12 行,第 8 列 -->第 5 行,第 1 列

Python: 491 - 353 characters

Still quite some room for improvement I guess, all comments welcome.

Strategy: finding all occurences of the first letter, and then trying to fetch the word in all directions.

import sys;r=range(-1,2);k=''.join;q="row %s, column %s"
a=[l[:-1:2]for l in sys.stdin]
b=sys.argv[1];c=len(a[0])
for x,y in[(x/c,x%c)for x,h in enumerate(k(map(k,a)))]:
 for i,j in[(i,j)for i in r for j in r if i or j<>0]:
  if k([a[x+z*i][y+z*j]for z in range(len(b))if 0<=x+z*i<c and 0<=y+z*j<len(a)])==b:print q%(x+1,y+1)+" --> "+q%(x+z*i+1,y+z*j+1)

Example usage:

cat input.txt | python test.py CODEGOLF

Example output:

row 12, column 8 --> row 5, column 1

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文