Bağlayın 4: Sahte Nokta!


35

Banka çöktü ve tüm yerel mafya haydutlarının alışılmadık bir mazereti vardı: evde Connect 4 oynuyorlardı! Soruşturmaya yardımcı olmak için, pozisyonların gerçekten geçerli bir Connect 4 oyunundan pozisyonları olup olmadığını kontrol etmek için ele geçirilen tüm Connect 4 panolarını doğrulamak için bir program yazmanız istenir ve aceleyle bir araya getirilmedi Polis kapıyı çaldığı anda.

Connect 4 için kurallar: oyuncuları Rve Ysırayla renklerini döşemek için bir 7x6 ızgara sütunlarına bırakın. Bir oyuncu koluna bir kiremit düşürdüğünde, o sütunda doldurulmamış en düşük pozisyonu işgal etmek için aşağı düşer. Bir oyuncu, tahtadaki renginden dört taştan oluşan yatay, dikey veya çapraz bir koşu yapmayı başarırsa, o zaman kazanır ve oyun hemen biter.

Örneğin ( Rbaşlangıç ile birlikte ), aşağıdakiler mümkün olmayan bir Connect 4 pozisyonudur.

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

Programınız veya işleviniz bir Connect 4 panosuna binmeli ve geri dönmeli

  • Konumun imkansız olduğunu belirten bir sahte değer veya
  • Bu pozisyona gelen hamle olası bir dizi (gösteren, 1 ila 7 arasındaki bir sayı ve bir dizi kolonlar sayılı 1için 7soldan sağa ve sekansın bu nedenle 112, örneğin, kolonun içinde kırmızı bir hareket gösterir 1san bir hareket, ardından sütununda 1, ardından sütununda kırmızı bir hareket 2). Çözümünüzde belirttiğiniz sürece, isterseniz 1234567'den başka bir sütun numarası seçebilirsiniz. Listeyi başka bir biçimde göndermek isterseniz; örneğin, bir dizi olarak, [2, 4, 3, 1, 1, 3]o zaman bu da iyidir, hamlelerin ne olduğunu görmek kolay olduğu sürece.

Sen dışındaki harfleri kullanarak dahil olmak üzere herhangi mantıklı bir biçimde de kurulu okumayı tercih edebilirsiniz Rve Yoyuncular için, ancak ilk sırayı alacağını oyuncu belirtmelisiniz. Tahtanın her zaman 6x7 olacağını, iki oyuncuyla olduğunu varsayabilirsiniz.

Aldığınız pozisyonların, standart bir Connect 4 panosunda yaratılmasının en azından fiziksel olarak mümkün olduğunu varsayabilirsiniz; yani, 'yüzen' parça olmayacak. Tahtanın boş olmadığını kabul edebilirsiniz.

Bu kod golf, bu yüzden en kısa cevap kazanır. Standart boşluklar uygulanır.

Örnekler

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

John, meraktan, kaba kuvvet olmayan bir algoritmanın var olup olmadığını biliyor musun?
Jonah

Yanıtlar:


9

Jöle , 57 bayt

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

0Doldurulan, 1ilk 2oynanan ve ikinci oynanan bir matris alır . Sahte tanımlandıysa boş, 1 indeksli sütunların bir listesini verir.

Çevrimiçi deneyin! (7 dakikadan daha fazla bir dakika içinde çalışacak kadar verimsiz)

Not:

  1. "Yüzen" parça bulunmadığını varsayar (bunu ZṠṢ€Ƒȧ+6 bayt için hazırlayarak düzeltin )
  2. Boş tahtanın sahte olduğunu varsayar

11

JavaScript (ES6),  202 194 187  183 bayt

240

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)

Çevrimiçi deneyin!

Nasıl?

g2413

Bunu yaparken, tüm çiftler kaybolana kadar ardışık dört tek değer çalışmamamızın olmamasını sağlar (yani, eğer bir taraf kazanırsa, son hamle olmalı).

yxp[x]

Yorumlananlar

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

Not "Boş panonun girdi olarak verilmeyeceğini varsayabilir miyiz?" - Bununla başa çıkmak zorunda kalırsak, kodunuzun bir ince ayar yapması gerekir.
Jonathan Allan,

neden bilmiyorum, 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] ])sona erer 0 ve 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], [2,2,2,0,2,2,1], [1,1,1,1,1,1,1] ])doğru olmalı
Nahuel Fouilleul

@NahuelFouilleul Bunu bildirdiğiniz için teşekkür ederiz. Kod ekleme düzeltildi bu test vakaları eklendi.
Arnauld

2

Python 2 , 295 285 bayt

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

Çevrimiçi deneyin!

-10 Jo King’e .

Giriş, sütunları temsil eden dizelerin bir listesidir; Kırmızı için '1' ve Sarı için '0'. Dizeler '' -padded değildir. Yani (falsey) davası:

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

giriş olarak:

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

Çıktı, pano oluşturabilen 0 dizinli sütun dizinleri listesidir; veya Nonegeçerli değilse.

Boş kartı geçerli olarak kabul eder ( []bunun yerine boş listeyi döndürür None).

Bu yaklaşım, son hamleden ilk hamleye kadar özyinelemelidir: alınan toplam hamle sayısının paritesine bağlı olarak, son Kırmızı hamleyi veya son Sarı hamleyi kaldırırız (veya mümkün değilse başarısız olur); rakibin üst üste 4 sıra halinde olup olmadığını görmek için ortaya çıkan tahtayı kontrol edin (bu durumda başarısız, çünkü oyun zaten durmalıydı); Aksi takdirde, tahta boşalana kadar tekrarlayın (geçerli).

Bir satırda 4 kod en kabarık kısmıdır. Matris için tüm çapraz dizeler bşu şekilde üretilir:

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

İlk önce 'aşağı eğimli' köşegenleri ve sonra 'yukarı eğimli' olanları listeler.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.