Temukan gerakan langsung terbaik dalam game "match-3"

11

Tantangan Anda hari ini adalah mengambil masukan seperti ini:

fbcfbee
ffcabbe
debceec
bccabbe
edcfbcd
daeaafc
eebcbeb

Dan hasilkan langkah terbaik yang mungkin ada dalam game seperti Bejeweled yang akan cocok dengan tiga atau lebih huruf, seperti ini (perhatikan ibukota Bdan C):

fbcfbee
ffcabbe
deBCeec
bccabbe
edcfbcd
daeaafc
eebcbeb

Spesifikasi lengkap:

  • Masukan akan berupa nbaris nhuruf kecil masing-masing (di mana nbisa nomor apa saja).
  • Outputnya akan menjadi langkah terbaik yang bisa Anda lakukan dalam pertandingan-3, dengan dua huruf yang ingin Anda tukarkan dengan huruf besar.
  • Kecocokan harus memiliki prioritas berikut (dalam contoh ini, .menunjukkan kotak yang tidak masalah):

    1. Lima berturut-turut

      xxYxx
      ..X..
      
    2. Rusak lima berturut-turut

      X..
      Yxx
      x..
      x..
      

      atau

      .X.
      xYx
      .x.
      .x.
      
    3. Empat berturut-turut

      xYxx
      .X..
      
    4. Tiga berturut-turut

      xYx
      .X.
      

    Anda harus menemukan kecocokan prioritas tertinggi dan menghasilkannya.

  • Jika ada beberapa kecocokan dengan prioritas yang sama, Anda dapat mengeluarkan salah satu dari mereka.
  • Akan selalu ada setidaknya satu pertandingan (program Anda dapat rusak jika tidak ada pertandingan, atau melakukan apa pun yang Anda inginkan).
  • I / O dapat dalam format apa pun yang masuk akal (stdin / out, membaca dan menulis file, argumen fungsi / nilai pengembalian, kotak dialog, dll.) Tetapi TIDAK di-hardcode (seperti x="[insert input here]").
  • Ini adalah sehingga kode terpendek dalam byte menang. Jika Anda menggunakan akses jaringan apa pun karena beberapa alasan, semua byte yang diunduh dari jaringan dihitung berdasarkan skor Anda.
Gagang pintu
sumber
1
+1, tapi saya memprotes judulnya; mungkin ada langkah yang lebih baik. Misalnya, satu yang membuat dua balita, atau satu yang menyebabkan drop untuk membuat lebih banyak barang.
Justin
Apakah patah lima-dalam-baris juga menutupi ..x.\nxxYX\n..x.?
Peter Taylor
@ Peter Ya, benar.
Gagang Pintu
Ada 2 patah 5 dalam pola baris: pola L dan pola T. Apakah Anda membutuhkan keduanya untuk dicocokkan?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
@nhahtdh Ya, saya akan mengedit untuk mengklarifikasi itu.
Gagang Pintu

Jawaban:

2

Python3.4, 772

(Menggunakan tab untuk indentasi, bukan spasi.)

import sys,itertools as I
B=[]
for l in sys.stdin:
    l=l.rstrip()
    B.append(list(l))
Z=len(B[0])
F=T=None
R=range
N=min
X=max
P=I.product
S=0
def C(I,J,K,L):
    global F,T,S
    if K<0 or K>=Z or L<0 or L>=Z: return
    B[I][J],B[K][L]=B[K][L],B[I][J]
    h=v=1
    m=B[K][L]
    for i in R(K+1,N(Z,K+5)):
        if B[i][L]!=m:break
        v+=1
    for i in R(K-1,X(0,K-5),-1):
        if B[i][L]!=m:break
        v+=1
    for j in R(L+1,N(Z,L+5)):
        if B[K][j]!=m:break
        h+=1
    for j in R(L-1,X(0,L-5),-1):
        if B[K][j]!=m:break
        h+=1
    c=X(h,v)*2
    if N(h,v)>=3:c+=N(h,v)
    if c>S:S=c;F=I,J;T=K,L
    B[I][J],B[K][L]=B[K][L],B[I][J]
for i,j in P(reversed(R(Z)),R(Z)):
    for d,e in (1,0),(0,-1),(0,1),(-1,0):
        C(i,j,i+d,j+e)
for i,j in P(R(Z),R(Z)):
    c=B[i][j]
    if (i,j)in(F,T):c=c.upper()
    print(c,end=('',"\n")[j==Z-1])
Austin Hastings
sumber
Alih-alih [c for c in l], Anda bisa melakukannya list(l).
Gagang pintu
Gunakan (i, j) dalam (F, T) alih-alih dua perbandingan - 778
Austin Hastings
F = (i, j) -> F = i, j. Mendelegalkan 2 r / o syms - 770
Austin Hastings
Fixed bug: broken-5 seharusnya tidak mengalahkan true-5.
Austin Hastings