ペグソリティアを遊ぼう


8

ペグソリティアは、通常一人でプレイされる人気のゲームです。ゲームはいくつかのペグとグリッドに分割されたボードで構成されます。通常、ボードは長方形ではありませんが、この課題ではこれを想定します。

有効な各移動により、1つのペグを削除することができ、目標は、1つのペグが残るような方法でプレイすることです。現在、有効な移動は単一の方向(北、東、南、または東)で、削除可能な1つのペグを飛び越える必要があります。

させる.ペグあり、以下の移動が移動します空のボード上のスペースや数字も1右と削除するには1を2ボードから:

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

この動きは、常に単一のペグを飛び越えるする必要がありますので、次のようになりません有効。

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

それぞれが1移動した後の有効な構成をいくつか次に示します。

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

チャレンジ

初期のボード構成とその他の構成を前提として、上記のようにペグを連続的に移動することで他の構成に到達できるかどうかを出力します。

ルール

  • 入力は、×メートルマトリックス/リストのリスト/ ...空白(例:ゼロまたは偽)またはペグ(例:非ゼロまたは真)を示す値のリスト
    • あなたが取ることができるメートル
    • true / 0以外を使用して空のスペースを示すことができます。
  • 出力は、最終構成に到達できるかどうかを示す2つの異なる(値の1つが異なる場合があります)値になります(例: / 真実[]/ [list of moves]..)

テストケース

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

1
7あなたの例でペグはどうなりましたか?なぜ2南に移動した後に消えるのですか?
–Οurous、

@ウロ:それは単なるタイプミスでした、それを修正しました。
ბიმო

回答:


2

JavaScript(ES6)、 184 178  173バイト

(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]--))))

オンラインでお試しください!

(TIOに時間がかかりすぎる最後の2つのテストケースを削除)

コメントしました

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

1

クリーン、232バイト

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

オンラインでお試しください!

これは、バイトを節約しながら、コンポジションとカレーを利用できるまれなケースの1つです。

説明:

@ :: [Int] -> [[Int]]移動の結果として発生する可能性のあるさまざまな新しい行/列を生成するために使用されるヘルパー関数です。これは、の場合にのみ[1,1,0:_]気づくことで特殊なケースを必要としないため、有効な移動ではないすべての構成のまたは要素を取得することで得られます。a*b-c>0[a,b,c]=[1,1,0]take(a*b-c)...[]-10

flip elem o...引数の順序を逆にしてelem(「xはyを含む」の代わりに「xはyを含む」にし)、無名関数をc最初の引数に適用します。

\c=limit(iterate(nub o concatMap ...)[c])c結果の変化が止まるまで、現在のボードのセットをすべてのボードで発生する可能性のあるすべての移動と結合し、重複を削除することにより、から発生する可能性のあるすべてのボードを生成します。

\l=[l]++...ボードの各方向の行にl適用@し(0、90、180、270度回転)、対応する変更された行を新しいもので置き換えることによって生成される、1移動距離離れたすべての潜在的な新しいボードのリストにボードを追加します行。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.