接続4:偽物を見つけよう!


35

銀行は破られ、地元のマフィアの凶悪犯は皆、異常なアリバイを持っています。彼らは自宅でConnect 4をプレイしていました!調査を支援するために、押収されたすべてのConnect 4ボードを検証するプログラムを作成して、位置が実際に有効なConnect 4ゲームからの位置であり、急いで組み立てられていないことを確認するように求められます警察がドアをノックするとすぐに。

接続4のルール:プレーヤーRY 7x6グリッドの列にその色のタイルをドロップするように順番にそれを取ります。プレイヤーが列にタイルをドロップすると、その列の一番下の空いている位置を占めるために倒れます。プレイヤーがボード上で自分の色の4タイルの水平、垂直、または斜めのランを獲得した場合、彼らは勝ち、ゲームはすぐに終了します。

たとえば(R開始時)、次の接続4の位置は不可能です。

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | |R| | | | |
| | |Y| | | | |
|R| |Y| | | | |

プログラムまたは機能は、Connect 4ボードを受け取り、いずれかを返す必要があります

  • 位置が不可能であることを示す偽の値、または
  • 1から7までの数字の文字列は、その位置に至る移動の可能なシーケンスを示します(列には左から右に番号が付けられ1ている7ため、112たとえば、列は列の赤い移動1とそれに続く黄色の移動を示します列1、続いて列に赤の移動2)。ソリューションで指定する限り、必要に応じて1234567以外の列番号を選択できます。他の形式でリストを返したい場合; たとえば、配列[2, 4, 3, 1, 1, 3]としては、動きが何であるかが簡単にわかる限り、それでも問題ありません。

あなたは以外の文字の使用を含む任意の賢明な形式で、ボードを読み取るために選択することができますRし、Yプレーヤーのために、しかし、あなたが最初に行くどのプレイヤーを指定する必要があります。ボードは常に6x7で、2人のプレイヤーがいると仮定できます。

受け取るポジションは、標準のConnect 4ボードで少なくとも物理的に作成できると想定できます。つまり、「フローティング」ピースはありません。ボードが空でないと仮定できます。

これはコードゴルフなので、最短の回答が勝ちます。標準の抜け穴が適用されます。

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | | --> 1234567 (one possible answer)
| | | | | | | |
|R|Y|R|Y|R|Y|R|

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | |R| | | | | --> false
| | |Y| | | | |
|R| |Y| | | | |

| | | | | | | |
| | |Y| | | | |
| | |R| | | | |
| | |Y| | | | | --> 323333 (only possible answer)
| | |R| | | | |
| |Y|R| | | | |

| | | | | | | |
| | | | | | | |
| | | | | | | |     
| | | | | | | | --> false (this is the position arising after
| |Y|Y|Y|Y| | |     the moves 11223344, but using those moves
| |R|R|R|R| | |     the game would have ended once R made a 4)

| | | | | | | |
| | | | | | | |
|Y| | | | | | |     
|R|Y| | | | | | --> 2134231211 (among other possibilities)
|R|R|Y| | | | |
|Y|R|R|Y| | | |

| | | | | | | |
| | | | | | | |
|Y| | | | | | |     
|R|Y| | | | | | --> false (for example, 21342312117 does not
|R|R|Y| | | | |     work, because Y has already made a diagonal 4)
|Y|R|R|Y| | |R|

| | | | | | | |
| | | | | | | |
| | | | | | | |     
| | | | | | | | --> 112244553 or similar
|Y|Y| |Y|Y| | |
|R|R|R|R|R| | |

好奇心からジョンは、非総当たりアルゴリズムが存在するかどうか知っていますか?
ヨナ

回答:


9

ゼリー、57 バイト

ŒṪŒ!µ0ịŒṬ¬a³ZU,Ɗ;ŒD$€Ẏṡ€4Ḅo1%15;Ḋ€ṢṚ$Ƒƙ$Ȧȧœị³$2R¤ṁ$ƑµƇṪṪ€

塗りつぶさ0れていない、1最初に再生され、22番目に再生されるマトリックスを取得します。1インデックスの列のリストを生成します。偽の列が見つかった場合は空になります。

オンラインでお試しください!(1分未満で実行するには7個を超えると非効率的)

注意:

  1. 「フローティング」ピースが存在しないと仮定します(ZṠṢ€Ƒȧ+6バイトの前に追加することでこれを修正します)
  2. 空のボードは偽物であると仮定します

11

JavaScript(ES6)、 202 194 187  183バイト

入力を行列として受け取ります2を赤、4 黄色と 0空のため。0インデックス付きの移動の文字列を返します(解決策がない場合は空の文字列)。レッズはゲームを開始します。

m=>(p=[...'5555555'],g=(c,s=o='')=>/2|4/.test(m)?['',0,2,4].some(n=>m.join``.match(`(1|3)(.{1${n}}\\1){3}`))?o:p.map((y,x)=>m[m[y][x]--^c||p[g(c^6,s+x,p[x]--),x]++,y][x]++)&&o:o=s)(2)

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

どうやって?

再帰関数 g すべてを置き換えようとします 2'砂 4の入力行列に 1'砂 3それぞれ。

その間、すべての偶数値が消えるまで(つまり、サイドが勝った場合、最後の動きでなければなりません)、4つの連続した奇数値が連続して実行されないようにします。

y 各列で次に利用可能なスロットの バツ に格納されています p[バツ]

コメント済み

m => (                            // m[] = input matrix
  p = [...'5555555'],             // p[] = next row for each column
  g = (c,                         // g = recursive function taking c = color,
          s = o = '') =>          //     s = current solution, o = final output
    /2|4/.test(m) ?               // if the matrix still contains at least a 2 or a 4:
      ['', 0, 2, 4]               //   see if we have four consecutive 1's or 3's
      .some(n =>                  //   by testing the four possible directions
        m.join``                  //   on the joined matrix, using
        .match(                   //   a regular expression where the number of characters
          `(1|3)(.{1${n}}\\1){3}` //   between each occurrence is either 1, 10, 12 or 14
        )                         //   (horizontal, diagonal, vertical, anti-diagonal)
      ) ?                         //   if we have a match:
        o                         //     abort and just return the current value of o
      :                           //   else:
        p.map((y, x) =>           //     for each cell at (x, y = p[x]):
          m[                      // 
            m[y][x]--             //       decrement the value of the cell
            ^ c ||                //       compare the original value with c
            p[                    //       if they're equal:
              g(                  //         do a recursive call with:
                c ^ 6,            //           the other color
                s + x,            //           the updated solution
                p[x]--            //           the updated row for this column
              ),                  //         end of recursive call
              x                   //         then:
            ]++,                  //         restore p[x]
            y                     //         and restore m[y][x]
          ][x]++                  //         to their initial values
        ) && o                    //     end of map(); yield o
    :                             // else:
      o = s                       //   we've found a solution: copy s to o
)(2)                              // initial call to g() with c = 2

注:「空のボードが入力として与えられないと仮定してもよいですか?」-これを処理する必要がある場合は、コードを微調整する必要があります。
ジョナサンアラン

理由はわかりませんが、f([ [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,2,0,2,0,0], [0,2,2,0,2,2,0], [1,1,1,1,1,1,1] ])終了し0f([ [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,2,0,2,0,0], [2,2,2,0,2,2,1], [1,1,1,1,1,1,1] ])真実でなければなりません
Nahuel Fouilleul

@NahuelFouilleulこれを報告してくれてありがとう。これらのテストケースを追加するコードを修正しました。
アーナウド

2

Python 2 295の 285バイト

def f(a):
 if 1-any(a):return[]
 p=sum(map(len,a))%2
 for i in R(7):
	if a[i][-1:]==`p`:
	 b=a[:];b[i]=b[i][:-1];L=f(b)
	 if L>1>(`1-p`*4in','.join([J((u[j]+' '*14)[n-j]for j in R(7))for n in R(12)for u in[b,b[::-1]]]+b+map(J,zip(*[r+' '*7for r in b])))):return L+[i]
R=range;J=''.join

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

-10番目から ジョー・キング

入力は、列を表す文字列のリストです。赤は「1」、黄色は「0」です。文字列は ''で埋められません。(偽の)ケース:

| | | | | | | |
| | | | | | | |
|Y| | | | | | |
|R|Y| | | | | |
|R|R|Y| | | | |
|Y|R|R|Y| | |R|

次のように入力されます:

[
  '0110',
  '110',
  '10',
  '0',
  '',
  '',
  '1'
]

出力は、ボードを作成できる列インデックスのリストであり、0インデックスが付けられています。またはNoneそれが有効でない場合。

空のボードを有効として受け入れます(空のリストを返します []代わりにNone)。

このアプローチは、最後の動きから最初の動きまで再帰的です:行われた動きの合計数のパリティに基づいて、最後の赤の動きまたは最後の黄色の動きのいずれかを削除します(または不可能な場合は失敗します)。結果のボードをチェックして、対戦相手に4列があるかどうかを確認します(この場合、ゲームは既に停止しているはずなので失敗します)。それ以外の場合は、ボードが空になるまで再帰します(これは有効です)。

4-in-a-rowコードは最も肥大化した部分です。マトリックスのすべての対角文字列は、次bによって生成されます。

[
    ''.join(
        (u[j]+' '*14)[n-j] for j in range(7)
    )
    for u in[b,b[::-1]]for n in range(12) 
]

最初に「下向き」の対角線をリストし、次に「上向きの」対角線をリストします。

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