一尘不染

用手找到街道和同类的算法

algorithm

这实际上是一个基于麻将的问题,但是基于Romme或什至基于扑克的背景也很容易理解。

在麻将中,将14张磁贴(瓷砖就像扑克中的纸牌一样)排列成4套和一对。街道(“ 123”)始终只使用3个图块,数量不多也不少。一组相同的集合(“
111”)也恰好由3个图块组成。这导致3 * 4 + 2 = 14个图块的总和。

这里有许多与“坎”或“十三孤儿”无关的例外。颜色和值范围(1-9)对算法也不重要。

我正在尝试确定是否可以按照上述方式布置一只手。由于某些原因,它不仅应该能够处理14个而且可以处理任意数量的瓷砖。(下一步将是找出需要交换多少张方砖才能完成一手操作。)

例子:

11122233344455-足够简单,4套和一对。
12345555678999- 123,456,789,555,99
11223378888999- 123,123,789,888,99
11223344556789-不是一个有效的手

我目前尚未实现的想法是:对于每个磁贴,尝试使a)一条街道b)一组c)一对。如果没有一个有效(或者会有一对以上),请返回上一个迭代并尝试下一个选项,或者,如果这是最高级别,则失败。否则,从剩余图块列表中删除使用过的图块,然后继续下一个迭代。

我相信这种方法行之有效,并且也将相当快(性能是“不错的奖励”),但是我对您对此的观点感兴趣。您能想到其他解决方案吗?这个或类似的东西已经存在吗?

(不是功课,我正在学习打麻将。


阅读 256

收藏
2020-07-28

共1个答案

一尘不染

街道和集合中的值之和可以除以3:

  • n + n + n = 3n
  • (n-1)+ n +(n + 1)= 3n

因此,如果将所有数字加到一个已求解的手中,则将得到3N + 2M形式的数字,其中M是该对中磁贴的值。total % 3对于M的每个值,除以三()的余数为:

total % 3 = 0  -> M = {3,6,9}
total % 3 = 1  -> M = {2,5,8}
total % 3 = 2  -> M = {1,4,7}

因此,不必测试九对可能的对,您只需要根据一个简单的加法尝试三对。对于每个可能的对,删除具有该值的两个图块,然后继续进行算法的下一步以确定是否可能。

一旦有了这个,就从最低的值开始。如果该值少于3个图块,则表示它们必定是一条街的第一个元素,因此请删除该条街(如果不能,则因为缺少n + 1或n +
2图块,则表示该手无效),然后移至下一个最小值。

如果至少有三个具有最低值的图块,请将它们作为一个集合删除(如果您询问“它们是否是街道的一部分?”,请考虑是否存在),那么还有三个图块n + 1和三个n +
2的像素数,也可以将其转换为集合)并继续。

如果您的手空了,则该手有效。

例如,对于您的无效手牌,总数为60,这意味着M = {3,6,9}:

Remove the 3: 112244556789
 - Start with 1: there are less than three, so remove a street
   -> impossible: 123 needs a 3

Remove the 6: impossible, there is only one

Remove the 9: impossible, there is only one

在第二个示例中12345555678999,总数为78,这意味着M = {3,6,9}:

Remove the 3: impossible, there is only one

Remove the 6: impossible, there is only one

Remove the 9: 123455556789
 - Start with 1: there is only one, so remove a street
   -> 455556789
 - Start with 4: there is only one, so remove a street
   -> 555789
 - Start with 5: there are three, so remove a set
   -> 789
 - Start with 7: there is only one, so remove a street
   -> empty : hand is valid, removals were [99] [123] [456] [555] [789]

您的第三个示例11223378888999也共有78个,这会导致回溯:

Remove the 3: 11227888899
 - Start with 1: there are less than three, so remove a street
   -> impossible: 123 needs a 3

Remove the 6: impossible, there are none

Remove the 9: 112233788889
 - Start with 1: there are less than three, so remove streets
   -> 788889
 - Start with 7: there is only one, so remove a street
   -> 888
 - Start with 8: there are three, so remove a set
   -> empty, hand is valid, removals were : [99] [123] [123] [789] [888]
2020-07-28