解决手风琴游戏


13

我最近碰到过手风琴纸牌游戏,几乎所有布局都可以解决,但是难以置信。你可以在这里玩。

规则

52张脸部卡以随机顺序正面朝上放置。 每回合,您用一张新卡替换一张卡,其中两张卡

  • 分享西服或号码,然后
  • 的距离为1(相邻)或3(之间为两张卡)。

仅剩1张卡时赢得比赛。您可以假定每个输入都是可解的。更换的卡必须始终在更换的卡之前。

例如,请考虑以下布局:

2H,2S,1S,2D  (H: Hearts, S: Spades, D: Diamonds)

这里有3种可能的动作:

  1. 将其替换为2H相邻的2S,这样我们最终得到2S,1S,2D
  2. 将其替换为2S相邻的1S,这样我们最终得到2H,1S,2D
  3. 更换2H2D(以3的距离),所以我们结了2D,2S,1S

在这3个动作中,只有最后一个有获胜的可能(您先替换2D <- 2S,然后获胜2S <- 1S)。

输入输出

您的工作是编写手风琴求解器。您会收到一张纸牌列表,并且需要返回一个动作列表来解决游戏。

您以逗号分隔的字符串形式传递卡片列表,其中,每张卡片均以代表其数值的整数传递,然后以代表其西装的字符传递。

您必须以逗号分隔的字符串形式返回替换列表,其中每个替换均采用以下格式Card <- Card(遵循上述卡格式)。每对中的第一张卡是要更换的卡。

测试用例:

5H,1C,12S,9C,9H,2C,12C,11H,10C,13S,3D,8H,1H,12H,4S,1D,7H,1S,13D,13C,7D,12D,6H,10H,4H,8S,3H,5D,2D,11C,10S,7S,4C,2H,3C,11S,13H,3S,6C,6S,4D,11D,8D,8C,6D,5C,7C,5S,9D,10D,2S,9S
5H,9C,11H,7S,7D,12D,6H,10S,3H,4D,12C,2S,3C,5C,7H,6S,1H,8S,2H,11S,4C,10D,12H,9H,2D,4H,6C,13H,11C,2C,10H,8C,1S,11D,3S,12S,7C,5D,13S,8D,4S,6D,13C,3D,8H,13D,1D,9D,9S,1C,5S,10C
7H,11C,8C,7S,10D,13H,4S,10C,4D,2C,4H,13D,3C,2H,12C,6C,9H,4C,12H,11H,9S,5H,8S,13S,8H,6D,2S,5D,11D,10S,1H,2D,5C,1C,1S,5S,3H,6S,7C,11S,9C,6H,8D,12S,1D,13C,9D,12D,3D,7D,10H,3S

尽管这场比赛是一场竞赛,但我对省时的解决方案特别感兴趣,并有可能通过赏金来奖励巧妙的解决方案。即便如此,花费天文数字的解决方案仍然可以接受(我建议您在较小的纸牌上进行测试,例如16张卡,4套西装的纸牌)。


您的规则是否提到只能朝一个方向进行移动?
feersum

6
桌上的每张牌平均大约有0.25 + 0.25 = 0.5个合法动作。因此,搜索空间约为52!* 0.5 = 4E67。所写的挑战(带有代码高尔夫标签)只能解释为搜索整个空间并报告任何解决方案(如果精疲力竭,则为“无”),这是极少有创造力的余地,并且需要天文学的时间尺度。考虑到成功率和时间,我建议您将此挑战变成代码挑战,并减少代码长度对得分的影响或完全消除它。
水平河圣

1
@ Pietu1998和其中存在问题。我认为该存储器消耗了您的字节数,因此您应该提交不带存储器的版本作为高尔夫球版本,但是这样就不可能在52张卡座上进行测试。Codegolf不适用于大型搜索空间问题的评分系统。
级圣河

3
对于那些希望与代码高尔夫竞争的人来说,天文运行时我可以。但是,人们当然能够(并鼓励)发布与竞争无关并且与运行时有关的答案。
弥敦道·美林

4
此外,如果您想测试代码高尔夫解决方案,则不需要52张卡组。16张卡(4套)的卡座应能缩短运行时间并验证正确性。
弥敦道·美林

Answers:


5

Python 3中,274个 272 271字节

@orlp节省了2个字节

def g(p):
 q=lambda a:[[i,a]for i in range(len(p)-a)if p[i][:-1]==p[i+a][:-1]or p[i][-1]in p[i+a]]
 for n in q(1)+q(3):
  s=sum(n);c=p[:s]+p[s+1:];c[n[0]]=p[s]
  if g(c):return p[n[0]]+' <- '+p[s]+','+g(c)
 return' 'if len(p)<2else[]
print(g(input().split(','))[:-2]or'')

这非常慢。但是,您可以尝试使用备忘录。这有一些额外的list- tuple转换,但在其他方面是等效的。

import functools
@functools.lru_cache(maxsize=None)
def g(p):
 q=lambda a:[[i,a]for i in range(len(p)-a)if p[i][:-1]==p[i+a][:-1]or p[i][-1]in p[i+a]]
 for n in q(1)+q(3):
  s=sum(n);c=list(p[:s]+p[s+1:]);c[n[0]]=p[s]
  if g(tuple(c)):return p[n[0]]+' <- '+p[s]+','+g(tuple(c))
 return' 'if len(p)<2else[]
print(g(tuple(input().split(',')))[:-2]or'')

对于某些输入,即使是这一天文运算也很慢。

该代码使用的是字符串,而不是数字,因此它也支持KH代替的符号13H

例:

$ python accordion.py
5H,9C,11H,7S,7D,12D,6H,10S,3H,4D,12C,2S,3C,5C,7H,6S,1H,8S,2H,11S,4C,10D,12H,9H,2D,4H,6C,13H,11C,2C,10H,8C,1S,11D,3S,12S,7C,5D,13S,8D,4S,6D,13C,3D,8H,13D,1D,9D,9S,1C,5S,10C
7S <- 7D,7D <- 12D,3C <- 5C,12H <- 9H,11C <- 2C,3S <- 12S,13D <- 1D,1D <- 9D,9D <- 9S,2S <- 6S,7H <- 1H,6S <- 8S,1H <- 2H,8S <- 11S,2H <- 9H,10D <- 2D,9H <- 4H,4H <- 4C,5C <- 4C,4D <- 4C,4C <- 12C,10S <- 11S,11H <- 11S,6H <- 3H,12D <- 2D,12C <- 2C,2C <- 6C,6C <- 8C,12S <- 13S,5D <- 6D,6D <- 8D,8D <- 3D,4S <- 9S,13S <- 9S,11D <- 3D,7C <- 1C,1S <- 1C,1C <- 13C,8C <- 13C,13C <- 13H,13H <- 10H,2D <- 3D,3D <- 3H,3H <- 8H,8H <- 10H,11S <- 5S,5H <- 10H,5S <- 9S,10H <- 10C,10C <- 9C,9C <- 9S

使用functools.lru_cache而不是自己编写。
orlp

@orlp我会的,但是由于无list法哈希,所以它不起作用。
PurkkaKoodari

然后使用元组。
orlp 2015年

@orlp OK,但这需要更改代码(例如str.split收益list)。我希望这两个程序在功能上是等效的。
PurkkaKoodari

你可以做的h=lambda p:lru_cache(None)(g)(''.join(p))
orlp
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.