Pecahkan permainan Accordion

13

Accordion adalah permainan kartu solitaire yang baru-baru ini saya temui di mana hampir setiap tata letak dipecahkan, tetapi sangat sulit. Anda bisa memainkannya di sini .

Aturan

52 kartu wajah ditempatkan menghadap ke atas dalam urutan acak. Setiap belokan, Anda mengganti kartu dengan kartu yang lebih baru, di mana kedua kartu :

  • Bagikan setelan atau nomor dan
  • Berada pada jarak 1 (berdekatan) atau 3 (dua kartu di antaranya).

Permainan dimenangkan ketika hanya ada 1 kartu yang tersisa . Anda dapat mengasumsikan bahwa setiap input dapat dipecahkan. Kartu yang diganti harus selalu mendahului kartu yang diganti.

Contoh

Sebagai contoh, pertimbangkan tata letak berikut:

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

Ada 3 kemungkinan gerakan di sini:

  1. Ganti 2Hdengan yang berdekatan 2S, jadi kita berakhir dengan2S,1S,2D
  2. Ganti 2Sdengan yang berdekatan 1S, jadi kita berakhir dengan2H,1S,2D
  3. Ganti 2Hdengan 2D(pada jarak 3), jadi kita berakhir dengan2D,2S,1S

Dari 3 gerakan itu, hanya yang terakhir yang memiliki kemungkinan menang (Anda menang dengan mengganti 2D <- 2S, lalu 2S <- 1S).

Input output

Tugas Anda adalah menulis pemecah Accordion . Anda diberikan daftar kartu, dan Anda harus mengembalikan daftar gerakan untuk menyelesaikan permainan.

Anda diberikan daftar kartu sebagai string yang dibatasi koma, di mana setiap kartu dilewatkan sebagai bilangan bulat yang mewakili nilai numeriknya, lalu karakter yang mewakili suit mereka.

Anda harus mengembalikan daftar penggantian sebagai string yang dibatasi koma, di mana setiap penggantian dalam format Card <- Card(mengikuti format kartu yang dijelaskan di atas). Kartu pertama dalam setiap pasangan adalah kartu yang sedang diganti.

Kasus uji:

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

Meskipun kompetisi ini adalah , saya sangat tertarik pada solusi yang efisien waktu, dan saya cenderung memberi solusi cerdas dengan hadiah. Yang mengatakan, solusi yang mengambil jumlah waktu astronomi masih dapat diterima (saya akan merekomendasikan pengujian dengan deck yang lebih kecil, seperti 16-card, 4 suit deck).

Nathan Merrill
sumber
Apakah aturan Anda menyebutkan bahwa gerakan hanya dapat dilakukan dalam satu arah?
feersum
6
Setiap kartu di atas meja memiliki rata-rata sekitar 0,25 + 0,25 = 0,5 langkah hukum. Karena itu ruang pencarian sekitar 52! * 0,5 = 4E67. Tantangan seperti yang tertulis (dengan kode golf tag) hanya dapat diartikan sebagai diperlukan untuk mencari seluruh ruang ini dan melaporkan solusi apa pun (atau "tidak ada" jika habis), yang menyisakan sedikit ruang untuk kecerdikan dan membutuhkan rentang waktu astronomi. Saya sarankan Anda menjadikan ini tantangan kode, mempertimbangkan tingkat keberhasilan dan waktu, dan mengurangi pengaruh panjang kode pada skor atau menghilangkannya sama sekali.
Level River St
1
@ Pietu1998 dan di situlah letak masalahnya. Saya berasumsi bahwa memorizer dikenakan biaya byte, jadi Anda harus mengirimkan versi tanpa memorizer sebagai versi golf, tetapi kemudian menjadi mustahil untuk menguji pada kartu 52 kartu. Codegolf tidak berfungsi dengan baik sebagai sistem penilaian pada masalah dengan ruang pencarian yang besar.
Level River St
3
Saya setuju dengan runtime astronomi bagi mereka yang ingin menjadi kompetitif kode-golf. Namun, orang-orang tentu mampu (dan didorong) untuk mengirim jawaban yang tidak kompetitif, dan hanya tentang waktu berjalan.
Nathan Merrill
4
Selain itu, jika Anda ingin menguji solusi kode-golf, kartu 52-kartu tidak diperlukan. Dek 16 kartu (4 suit) harus memberikan runtime pendek, dan memverifikasi kebenaran.
Nathan Merrill

Jawaban:

5

Python 3, 274 272 271 byte

2 byte disimpan berkat @orlp .

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

Ini sangat lambat. Namun, Anda dapat mencobanya dengan memoize . Ini memiliki beberapa tambahan list- tuplekonversi, tetapi jika tidak setara.

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

Bahkan yang satu ini secara astronomis lambat dengan input tertentu.

Kode menggunakan string, bukan angka, sehingga juga mendukung notasi seperti KH bukan 13H.

Contoh:

$ 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
PurkkaKoodari
sumber
Gunakan functools.lru_cachealih-alih menulis sendiri.
orlp
@ Atlp saya akan, tetapi karena tidak listdapat diguncang itu tidak bekerja.
PurkkaKoodari
Kemudian gunakan tuple.
orlp
@ orl OK, tapi itu akan membutuhkan perubahan pada kode (mis. str.splitmengembalikan list). Saya lebih suka kedua program menjadi setara secara fungsional.
PurkkaKoodari
Anda bisa melakukannya h=lambda p:lru_cache(None)(g)(''.join(p)).
orlp