アコーディオンのゲームを解く


13

アコーディオンは、私が最近出会ったソリティアカードゲームで、ほぼすべてのレイアウトが解けるが、信じられないほど難しい。ここでプレイできます

ルール

52枚の顔カードがランダムな順序で表向きに配置されます。 ターンごとに、カードを新しいカードに交換します

  • スーツまたは番号共有し、
  • 1(隣接)または3(間に2枚のカード)の距離にあります。

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つの動きのうち、最後の1つだけが勝つ可能性があります(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スーツ)のデッキは、短いランタイムを提供し、正確性を検証する必要があります。
ネイサンメリル

回答:


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'')

これは非常に遅いです。ただし、memoizeで試すことができます。これは、いくつかの余分を持っている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

@orlp OK。ただし、コードを変更する必要があります(例:をstr.split返しますlist)。2つのプログラムが機能的に同等であることを望みます。
-PurkkaKoodari

できますh=lambda p:lru_cache(None)(g)(''.join(p))
orlp
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.