【问题标题】:Algorithm: Solve crossword puzzle given a list of words算法:在给定单词列表的情况下解决填字游戏
【发布时间】:2017-12-18 20:24:16
【问题描述】:

我查看了类似问题的先前问题,但我有一个与此算法相关的具体问题。问题陈述(https://www.hackerrank.com/challenges/crossword-puzzle/problem)如下:

为您提供了一个 10x10 的填字游戏网格,以及一组需要填入网格的单词(或地名)。 网格中的单元格最初是 + 符号或 - 符号。 标有 + 的单元格必须保持原样。标有 - 的单元格需要用适当的字符填充。

示例输入:

+-++++++++
+-++++++++
+-++++++++
+-----++++
+-+++-++++
+-+++-++++
+++++-++++
++------++
+++++-++++
+++++-++++
LONDON;DELHI;ICELAND;ANKARA

对应的输出:

+L++++++++
+O++++++++
+N++++++++
+DELHI++++
+O+++C++++
+N+++E++++
+++++L++++
++ANKARA++
+++++N++++
+++++D++++

我犯了一个错误,在没有完全理解问题的情况下编写了一个算法,我只是将下一个可用的字母放在一个空白处并以这种方式解决迷宫(这是我的代码):

 def populate_grid(maze, locations)
     maze.each_index do |row|
         maze[row].each_index do |col|
             if maze[row][col] == "-"
                 maze[row][col] = locations.first[0]
                 if locations.first.length == 1
                     locations.shift # remove this location altogether
                 else
                    locations[0] = locations[0][1...locations.first.length]
                 end
                 populate_grid(maze, locations)
             end
         end
     end
 end

不幸的是,没有针对此问题提供的解决方案,我想知道如何为每个单词构建一致的方向性(例如,仅在水平/垂直方向上)。我考虑过使用 3 参数作为布尔值来判断单词是上升还是下降,但这对我来说似乎不可行。

有人对如何保持方向性有想法吗?

【问题讨论】:

  • 你可以使用递归来解决这个问题。将第一个单词放在每个可行的位置。对于每个,将第二个单词放在每个可行位置。对于第一个和第二个配对,将第三个单词放在每个可行位置。你的递归方法可以写成recurse(partially_filled_crossword, remaining_words),两个参数都是数组,返回一个代表一个完整填字游戏(数组)的数组,或者nil,如果搜索树的那部分不存在有效的完整填字游戏。

标签: ruby algorithm recursion multidimensional-array


【解决方案1】:

一般来说,您需要将词典视为 单词 单元,并使用例程将整个单词作为一个单元插入来处理网格(这是十字路口对您的maze 的术语)。

您需要“解析”网格以识别所有可用位置。 写一个函数到match一个字到一个可用的位置,反之亦然。位置由起始方格(行、列)、方向(布尔值)和字母模式(空格,除非已经填写了交叉词)组成。 match 会考虑字长和任何已经填好的方块。

现在,您可以迭代地依次放置每个单词,或填充每个网格位置。致电match,直到找到可以填写单词的地方。如果没有找到,则当前的网格填充不会导致解决方案;回溯一个词,然后再试一次。当你找到一个点时,填写单词(另一个函数),用现在填充的字母更新任何交叉位置,然后转到迭代中的下一个单词或位置。

如果你成功到达终点,你就有一个完整的谜题。

这会让你感动吗?

【讨论】:

  • 代码将使这成为一个更有用的答案。
  • @CarySwoveland:我觉得设计数据结构和提供工作代码将远远超出 SO 的一般用途。我同意 OP 的观点,即发布的代码是无效攻击;一个适当的改变就是一个大的重写。
  • 我不是在批评你的回答,只是指出代码对 OP 和其他读者更有帮助。人们经常看到可能被视为“远远超出 SO 的一般目的”的答案,但仍然受到赞赏。
  • 能否再详细介绍一下 match 方法?
  • @Sunny:此时,您已经解析了网格以找到所有位置。您可以方便地存储这些内容,例如一个数组,其条目中的每个条目都包含一个长度和当前的字母模式。您现在必须编写一个 match 方法,该方法将返回与给定单词匹配的所有位置:长度相同,并且没有冲突的字母。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多