Mari kita mainkan Peg Solitaire

8

Peg solitaire adalah game populer yang biasanya dimainkan sendiri. Gim ini terdiri dari sejumlah pasak dan papan yang dibagi menjadi kisi - biasanya papan tidak berbentuk persegi panjang tetapi untuk tantangan ini kami akan menganggapnya demikian.

Setiap gerakan yang valid memungkinkan seseorang untuk menghapus pasak tunggal dan tujuannya adalah untuk bermain sedemikian rupa, sehingga ada satu pasak tersisa. Sekarang, langkah yang valid harus berada dalam satu arah (utara, timur, selatan atau timur) dan melompati satu pasak yang dapat dihapus.

Contohnya

Membiarkan .ruang kosong di papan dan angka adalah pasak, langkah berikut akan memindahkan 1satu ke kanan dan menghapus 2dari papan:

.....     .....
.12..  -> ...1.
.....     .....

Suatu langkah harus selalu melompati satu pasak, sehingga yang berikut ini tidak valid:

......    ......
.123.. -> ....1.
......    ......

Berikut adalah beberapa konfigurasi yang valid setelah setiap gerakan:

...1...        ...1...        ..71...        ..71...
.2.34.5  --->  .24...5  --->  .2....5  --->  ......5
.678...  (4W)  .678...  (7N)  .6.8...  (2S)  ...8...
.......        .......        .......        .2.....

Tantangan

Diberikan konfigurasi papan awal dan beberapa konfigurasi lainnya, keluaran apakah konfigurasi lainnya dapat dicapai dengan memindahkan pasak secara berurutan seperti dijelaskan di atas.

Aturan

  • Input akan berupa matriks n×m / daftar daftar / ... dari nilai-nilai yang menunjukkan ruang kosong (mis. Nol atau salah) atau pasak (mis. Tidak nol atau benar)
    • Anda dapat mengasumsikan n3 dan m3
    • Anda dapat menggunakan true / non-zero untuk menunjukkan ruang kosong dan sebaliknya jika itu membantu
  • Output akan berupa dua nilai yang berbeda (salah satu nilainya mungkin berbeda) yang mengindikasikan apakah konfigurasi akhir dapat dicapai (mis. Falsy / truthy , []/ [list of moves]..)

Uji kasus

initial  goal -> output
[[1,0,0],[1,1,0],[0,1,0]]  [[0,0,0],[0,1,0],[1,1,0]] -> True
[[1,0,0],[1,1,0],[0,1,0]]  [[0,0,1],[0,1,1],[0,0,0]] -> False
[[0,0,0],[1,0,0],[0,0,0]]  [[0,0,0],[0,0,1],[0,0,0]] -> False
[[0,0,0],[1,1,0],[0,0,0]]  [[0,0,0],[0,1,1],[0,0,0]] -> False
[[0,0,0,0],[1,1,1,0],[0,0,0,0]]  [[0,0,0,0],[0,0,0,1],[0,0,0,0]] -> False
[[1,0,0],[1,1,0],[1,1,1],[1,1,1]]  [[0,0,1],[0,1,0],[1,0,0],[0,0,1]] -> True
[[1,0,0],[1,1,0],[1,1,1],[1,1,1]]  [[1,0,0],[0,0,0],[0,0,0],[0,0,0]] -> False
[[1,0,1,1],[1,1,0,0],[1,1,1,0],[1,0,1,0]]  [[0,0,1,0],[1,0,0,0],[1,0,1,0],[1,0,0,1]] -> True
[[1,0,1,1],[1,1,0,0],[1,1,1,0],[1,0,1,0]]  [[0,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,0]] -> False
[[1,0,0,0],[1,1,0,0],[1,1,1,0],[1,0,1,0]]  [[0,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,0]] -> True
[[0,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,0]]  [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,1]] -> False
[[0,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,0]]  [[1,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]] -> False
[[0,0,0,1,0,0,0],[0,1,0,1,1,0,1],[0,1,1,1,0,0,0],[0,0,0,0,0,0,0]]  [[0,0,0,1,0,0,0],[0,1,0,1,1,0,1],[0,1,1,1,0,0,0],[0,0,0,0,0,0,0]] -> True
[[0,0,0,1,0,0,0],[0,1,0,1,1,0,1],[0,1,1,1,0,0,0],[0,0,0,0,0,0,0]]  [[0,0,0,1,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0]] -> True
[[0,0,1,1,1,0,0],[0,0,1,1,1,0,0],[1,1,1,1,1,1,1],[1,1,1,0,1,1,1],[1,1,1,1,1,1,1],[0,0,1,1,1,0,0],[0,0,1,1,1,0,0]]  [[0,0,1,1,1,0,0],[0,0,1,1,1,0,0],[1,1,1,1,1,1,1],[1,1,1,1,0,0,1],[1,1,1,1,1,1,1],[0,0,1,1,1,0,0],[0,0,1,1,1,0,0]] -> True
[[0,0,1,1,1,0,0],[0,0,1,1,1,0,0],[1,1,1,1,1,1,1],[1,1,1,0,1,1,1],[1,1,1,1,1,1,1],[0,0,1,1,1,0,0],[0,0,1,1,1,0,0]]  [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,1,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0]] -> True
ბიმო
sumber
1
Apa yang terjadi dengan pasak 7dalam contoh Anda? Mengapa hilang setelah 2pindah ke selatan?
Οurous
@Ourous: Itu hanya kesalahan ketik, memperbaikinya.
ბიმო

Jawaban:

2

JavaScript (ES6),  184 178  173 byte

(initial_board)(target_board)01

a=>g=b=>a+''==b|a.some((r,y)=>r.some((v,x,A,X,R)=>[-1,0,1,2].some(h=>(A=a[y+(R=~-h%2)]||0)[X=x+(h%=2)]&v>(R=a[y+R*2]||0)[h+=x+h]&&g(b,A[X]=r[x]=R[h]++)&(A[X]=r[x]=R[h]--))))

Cobalah online!

(menghapus dua kasus uji terakhir yang terlalu banyak waktu untuk TIO)

Berkomentar

a =>                             // main function taking the initial board a[]
  g = b =>                       // g = recursive function taking the target board b[]
    a + '' == b |                // yield a truthy result if a[] is matching b[]
    a.some((r, y) =>             // for each row r[] at position y in a[]:
      r.some((v, x, A, X, R) =>  //   for each value v at position x in r[]:
        [-1, 0, 1, 2]            //     list of directions (West, North, East, South)
        .some(h =>               //     for each direction h:
          ( A =                  //       A = a[y + dy]
            a[y + (R = ~-h % 2)] //       R = dy
            || 0                 //       use a dummy row if we're out of the board
          )[X = x + (h %= 2)]    //       h = dx, X = x + dx
          &                      //       yield 1 if there's a peg on the skipped cell
          ( R =                  //       R = target row
            a[y + R * 2]         //         = a[y + 2 * dy]
            || 0                 //       use a dummy row if we're out of the board
          )[h += x + h]          //       h = x + 2 * dx = target column
          < v                    //       yield 1 if there's no peg on the target cell
          &&                     //       and there's a peg on the source cell (0 < 1)
          g(                     //       if the above result is true, do a recursive call:
            b,                   //         pass b[] unchanged
            A[X] = r[x] =        //         clear the source and skipped cells
            R[h]++               //         set the target cell
          ) & (                  //       and then restore the board to its initial state:
            A[X] = r[x] =        //         set the source and skipped cells
            R[h]--               //         clear the target cell
          )                      //
        )                        //     end of some() over directions
      )                          //   end of some() over columns
    )                            // end of some() over rows
Arnauld
sumber
1

Bersih , 232 byte

import StdEnv,Data.List
r=reverse
@[a:t=:[b,c:u]]=[[a:v]\\v<- @t]++take(a*b-c)[[0,0,1:u]];@l=[]

flip elem o\c=limit(iterate(nub o concatMap\l=[l]++[f(updateAt i p(f l))\\f<-[id,transpose],q<-f l&i<-[0..],p<- @q++(map r o@o r)q])[c])

Cobalah online!

Ini adalah salah satu kesempatan langka di mana saya dapat memanfaatkan komposisi dan kari sambil menghemat byte.

Dijelaskan:

@ :: [Int] -> [[Int]]adalah fungsi pembantu yang digunakan untuk menghasilkan berbagai potensi baru baris / kolom yang dapat hasil dari langkah yang dibuat. Ini menghindari perlu kasus khusus [1,1,0:_]dengan memperhatikan bahwa a*b-c>0hanya ketika [a,b,c]=[1,1,0], dan take(a*b-c)...memberi []dengan mengambil -1atau 0elemen untuk semua konfigurasi yang bukan langkah yang valid.

flip elem o...membalik urutan argumen ke elem(menjadikannya "tidak berisi y" bukan "adalah anggota x y") dan menerapkan fungsi anonim cke argumen pertama.

\c=limit(iterate(nub o concatMap ...)[c])menghasilkan setiap papan potensial yang dapat dihasilkan dari cdengan bergabung dengan set papan saat ini dengan semua gerakan yang dapat terjadi pada semua papan dan menghapus duplikat, sampai hasilnya berhenti berubah.

\l=[l]++...menambahkan papan lke daftar semua papan baru yang potensial, satu langkah jarak jauhnya, yang dihasilkan dengan menerapkan @ke setiap baris orientasi papan (0, 90, 180, 270 derajat rotasi) dan mengganti baris yang diubah sesuai dengan yang baru baris.

Suram
sumber