计数交叉词


10

考虑以下标准的15×15 填字游戏拼图网格。

填字游戏网格

我们可以通过将#方块和(空格)用于白方块来用ASCII艺术表示。

     #    #    
     #    #    
          #    
   #   #       
###     ##   ##

     ##   #    
   #       #   
    #   ##     

##   ##     ###
       #   #   
    #          
    #    #     
    #    #     

给定上述ASCII艺术格式的填字游戏网格,请确定其包含多少个单词。(以上表格有78个字。碰巧是上周一的《纽约时报》难题。)

单词是垂直或水平延伸的两个或两个以上连续空间的组。单词以块或网格边缘开始和结束,并且始终从上到下或从左到右运行,从不对角或向后。请注意,单词可以跨越拼图的整个宽度,就像上面拼图的第六行一样。一个单词不必与另一个单词相连。

细节

  • 输入将始终是包含字符#(空格)的矩形,并且行之间用换行符(\n)分隔。您可以假定网格由任意2个不同的可打印ASCII字符(而不是#和)组成
  • 您可以假定存在可选的尾随换行符。尾随空格字符确实会计数,因为它们会影响单词的数量。
  • 网格并不总是对称的,它可能是所有空格或所有块。
  • 从理论上讲,您的程序应该可以在任何大小的网格上工作,但是对于这一挑战,它永远不会大于21×21。
  • 您可以将网格本身作为输入或包含网格的文件的名称。
  • 从stdin或命令行参数获取输入,然后输出到stdout。
  • 如果愿意,可以使用命名函数而不是程序,将网格作为字符串参数,然后通过stdout或function return输出整数或字符串。

测试用例

  1. 输入:

        #
        #
        #
    

    输出:(7每个空格之前有四个空格#。如果删除每个数字符号,结果将是相同的,但是Markdown将从其他空行中删除空格。)

  2. 输入:

    ##
     #
    ##
    

    输出:(0一个字母的单词不计算在内。)

  3. 输入:

    ######
    #    #
      ####
    # ## #
    # ## #
    #### #
    

    输出: 4

  4. 输入:(5月10日的纽约时报难题)

       #    ##   #       
       #    #    #       
       #         #       
           #     ###   ##
        #       #        
    ##   #   #           
            #       ##   
          #   ##         
       #        ##      #
             #   ###   ##
    #   ##         ##   #
    ##   ###   #         
    #      ##        #   
             ##   #      
       ##       #        
               #   #   ##
            #       #    
    ##   ###     #       
           #         #   
           #    #    #   
           #   ##    #   
    

    输出: 140

计分

字节为单位的最短代码获胜。Tiebreaker是最早的帖子。

Answers:


7

CJam,18 17 13 11字节

Dennis保存了2个字节。

对填充的单元格和1空的单元格使用空格:

qN/_z+:~1-,

在这里测试。

说明

q    e# Read the entire input.
N/   e# Split into lines.
_z   e# Make a copy and transpose it.
+    e# Add the lines of the two grids together.
:~   e# Evaluate each line which will push a rep-digit number for each empty-cell chunk.
1-   e# Remove all the 1s as these correspond to individual empty cells.
,    e# Get the length of the array.

9

滑动 18 + 3 = 21字节

>? ( +(X|$^)<<){2}

与标志一起运行no(因此为+3),并使用space / X代替space / #。令人讨厌的是,它的长度比CJam / Pyth长,但我想Slip并不是专门针对高尔夫运动而设计的。

在线尝试。请注意,第一个示例缺少几行空格。

说明

>?           Optionally turn right, hence matching either horizontally or vertically
[space]      Match a space
(    ){2}    Group, twice:
[space]+       Match 1+ spaces
(X|$^)         Either an X or the boundary of the grid
<<             Reverse the match pointer by turning left twice

n标志使输出打印匹配的数目,并且该o标志允许从相同的正方形开始的重叠匹配。来回移动的原因是因为Slip尝试从每个正方形开始进行匹配,因此我们要确保仅匹配整行而不是部分行。滑动仅返回唯一的匹配项,即使它们从不同的位置开始也是如此。

注意:最初我有>?( +(X|$^)<<){2},里面有第一个空格。由于指针将如下所示,这会丢失某些在边缘处有2个空格长的单词的情况:

XXX       XXX       XXX       XXX
X>        X >       X<        <
XXX       XXX       XXX       XXX

[sp]    [sp]+$^    <<[sp]    [sp]+   (uh oh match fails)

为什么两个标志为三个字节?
lirtosiast 2015年

@ThomasKwa我认为当前带有命令行标志的策略是此meta post,它计算字节数作为与通常调用代码的差。所以这里的区别是py -3 slip.py regex.txt input.txt和之间py -3 slip.py regex.txt input.txt no,这是三个字节(包括之前的空格n
Sp3000 2015年

这就说得通了。我从熵的角度思考它;有时我忘记了我们计数的字符。
lirtosiast 2015年

4

Haskell,81个字节

import Data.List
m x=sum[1|(_:_:_)<-words x]
f x=m x+m(unlines$transpose$lines x)

将空格用作块字符,并将任何其他(非空格)字符用作空单元格。

工作原理:将输入拆分为空格处的单词列表。1对于每个带有至少2个字符的单词取a 并将这些1s 相加。\n对输入的转置(在处分割)应用相同的过程。将两个结果相加。


4

的JavaScript(ES6)87 121 147

构建输入字符串的转置并将其附加到输入,然后计算2个或更多空格的字符串。

在Firefox中运行代码段进行测试。

感谢@IsmaelMiguel,这是ES5的解决方案(122字节):

function F(z){for(r=z.split(/\n/),i=0;i<r[j=0][L='length'];i++)for(z+='#';j<r[L];)z+=r[j++][i];return~-z.split(/  +/)[L]};

F=z=>
(
  r=z.split(/\n/),
  [r.map(r=>z+=r[i],z+='#')for(i in r[0])],
  ~-z.split(/  +/).length
)

// TEST
out=x=>O.innerHTML += x + '\n';

[
'     #    #    \n     #    #    \n          #    \n   #   #       \n###     ##   ##\n               \n     ##   #    \n   #       #   \n    #   ##     \n               \n##   ##     ###\n       #   #   \n    #          \n    #    #     \n    #    #     ', '##\n #\n##', '    #\n    #\n    #',
 '######\n#    #\n  ####\n# ## #\n# ## #\n#### #',
 '   #    ##   #       \n   #    #    #       \n   #         #       \n       #     ###   ##\n    #       #        \n##   #   #           \n        #       ##   \n      #   ##         \n   #        ##      #\n         #   ###   ##\n#   ##         ##   #\n##   ###   #         \n#      ##        #   \n         ##   #      \n   ##       #        \n           #   #   ##\n        #       #    \n##   ###     #       \n       #         #   \n       #    #    #   \n       #   ##    #   '  
].forEach(x=>out(x.replace(/ /g,'.')+'\n'+F(x)+'\n'))
<pre id=O></pre>


1
F=z=>{for(r=z.split(/\n/),i=0;i<r[j=0][L='length'];i++)for(z+='#';j<r[L];)z+=r[j++][i];return~-z.split(/ +/)[L]}呢 它长113个字节。将您的正则表达式替换为/ +/(2个空格),将j=0其添加到“父” for循环中,而不是使用语法obj.length,我改为使用L='length'; ... obj[L],它重复了3次。
Ismael Miguel

我在es6fiddle.net/iakdcpdh运行它(而不是F=z=>必须使用var F=(z,i,L,j,r)=>)。我在IE11上进行了测试,并且可以正常工作!
Ismael Miguel

@IsmaelMiguel做得好!最适合ES5。再次查看它,我发现了一些ES6ish或更短的东西。也许您可以发布ES5解决方案。
edc65

不,没关系。这是您的解决方案,我只是简化了一下。我觉得好像我自己回答那样并不公平。
Ismael Miguel

现在,我考虑了一下,您可以将/\n/模板字符串替换为之间的真实换行符。这样就节省了1个字节,因为您不必编写转义序列。
Ismael Miguel

3

Pyth,15 14 13字节

lftTcjd+.zC.z

我使用的是分隔符和#填充字符,而不是OP中相反的含义。在线试用:演示

除了#接受填充字符,它还接受字母。因此,您实际上可以采用已解决的填字游戏,并且可以打印单词数。如果删除该l命令,它甚至会打印所有单词。在此处进行测试:5月10日的纽约时报难题

说明

        .z      all input rows
          C.z   all input columns (C transposes)
       +        add them (all rows and columns)
     jd         join by spaces
    c           split by spaces
 f              filter for pieces T, which satisfy:
  tT              len(T) > 1
l               length, implicitly printed
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.