İkili Bulmaca Çözücü


10

Giriş

Bulmacanın kuralları:

İkili ( Takuzu veya Subiku olarak da bilinir) bulmacasını anlamak çok basittir ve sadece birkaç kuralı vardır:
Oyunun adı ikili olduğu için oldukça açıktır, ancak yalnızca sıfırları ve olanları doldurabilirsiniz.

  1. Aynı basamaktan ikiden fazlası dikey veya yatay olarak birbirine bitişik olamaz
  2. Her satır ve her sütun eşit miktarda sıfır ve bir sütun içermelidir (bu, her ikili oyunun her zaman eşit boyutlara sahip olacağı anlamına gelir).
  3. Yinelenen satır ve yinelenen sütun olmayabilir (sıfır ve satırlarla aynı sırayla).

İsterseniz oyunu www.binarypuzzle.com adresinde oynayabilirsiniz .

taktikler:

Kural 1 nedeniyle, aşağıdaki durumlarda her zaman bir rakam doldurabiliriz:
- Aynı basamaktan dikey veya yatay olarak birbirine bitişik iki tane varsa , bu durumda her iki taraftaki karşı basamağı doldurabiliriz. Yani .11...0110...
- Aralarında yalnızca bir boşluk olacak şekilde aynı basamaktan dikey veya yatay olarak iki tane var. Yani .1.1...101..

Kural 1 nedeniyle, üç boşluk kaldığında ve aynı rakamın üç bitişikine sahip olamadığımızda, boşluklardan birini doldurabiliriz. Yani .0.1.010.1.0(Hala iki tane doldurmalıyız ve ortada üç bitişik olanımız olamaz, bu yüzden ilk boşluk bir olmalıdır 1.)

Kural 2 nedeniyle, yarıları zaten ters rakamla doldurulmuşsa, kalan satırları her zaman bir satır veya sütunda doldurabiliriz. Yani .1.011010011

Kural 3 nedeniyle, eşit sıralı bir satırda çözülecek sadece iki tane kalırsa, her zaman karşıt basamakları doldurabiliriz. Yani 101100 & 1..100101100 & 110100

Kural 3 nedeniyle, eşit olarak sıralanmış bir hatta üç boşluk kaldığında bazen bir boşluğu doldurabiliriz. Yani 010011 & .1.01.010011 & .1.010(Burada 1sonunda bir dolgu yapamayız , çünkü bu, diğer iki boşlukta sıfırları doldurmamız gerektiği anlamına gelir ve her iki satırı da sırayla eşitler.)

Misal:

Aşağıdaki 6x6 ızgarayla başlıyoruz ve bazılarını ve sıfırları doldurduk (ve noktalar henüz doldurmadığımız boşluklar):

.1....
.10.0.
1.11..
.1....
...1.0
......

Kural 1 ve 2 nedeniyle bu rakamları doldurabiliriz:

.1.01.
.1010.
101100
010011
.0.1.0
.010..

Kural 1 nedeniyle satır 5, sütun 1'de 1 girebiliriz:

.1.01.
.1010.
101100
010011
10.1.0
.010..

Kural 3 nedeniyle, satır 1, sütun 6'da 0'ı doldurabiliriz (satır 4'e bakarken):

.1.010
.1010.
101100
010011
10.1.0
.010..

Artık kural 1 ve 2 nedeniyle boşlukları rakamlarla doldurmaya devam edebiliriz:

.1.010
010101
101100
010011
10.1.0
.010.1

Şimdi kural 3 nedeniyle 5. satırı bitirebiliriz (3. satıra bakarken):

.1.010
010101
101100
010011
100110
.010.1

Ve sonra kural 1 ve 2 nedeniyle bulmacayı bitirebiliriz:

011010
010101
101100
010011
100110
101001

Meydan okuma:

Sorun basittir: başlangıç ​​ızgarası göz önüne alındığında, çözülen bulmacanın çıktısını alın.

NOT: Yukarıdaki kuralları uygulamanız gerekmez. Tabii ki yapabilirsiniz ve bu zorluğun nasıl uygulanacağı konusunda ipuçları vermelidir, ancak çözümü akılda tutarak kurallarla kaba kuvvetlendirmek tamamen iyidir.
Bunu nasıl çözeceğiniz size kalmış, ama zorluk çözülmüş bulmacanın çıktısını almak.

Zorluk kuralları:

  • Izgara için giriş ve çıkış formatı esnektir, ancak lütfen ne kullandığınızı belirtin. (Yani 2D bayt dizisi; Yeni satırlı dize; vb.)
  • Bu, yukarıdaki karakterler için de geçerlidir. Kullandığım örnekte 01., ancak isterseniz ABxbunun yerine kullanabilirsiniz . Lütfen hangi giriş / çıkış biçimini ve karakterleri kullandığınızı belirtin.
  • Yalnızca aşağıdaki ızgara boyutlarının kullanılacağını varsayabilirsiniz 6x6:; 8x8; 10x10; 12x12; 14x14; 16x16.

Genel kurallar:

  • Bu , bayt en kısa cevap kazanır.
    Kod golf dillerinin, kod yazmayan dillerle yanıt göndermenizi engellemesine izin vermeyin. 'Herhangi bir' programlama dili için olabildiğince kısa bir cevap bulmaya çalışın.
  • Cevabınız için standart kurallar geçerlidir , bu nedenle STDIN / STDOUT, fonksiyon / yöntemi uygun parametrelerle, tam programları kullanmanıza izin verilir. Çağrınız.
  • Standart Boşluk Doldurma yasaktır.
  • Mümkünse, lütfen kodunuz için test içeren bir bağlantı ekleyin.
  • Ayrıca, gerekirse bir açıklama ekleyin.

Test senaryoları:

Noktalar yalnızca okunabilirlik için eklenir, boşluk kullanmaktan veya boşluklar için tercih ettiğiniz başka bir şeyden çekinmeyin. Hem giriş hem de çıkış formatı esnektir.

Input:
1..0..
..00.1
.00..1
......
00.1..
.1..00

Output:
101010
010011
100101
011010
001101
110100

Input:
.1....
.10.0.
1.11..
.1....
...1.0
......

Output:
011010
010101
101100
010011
100110
101001

Input:
.......1..
.00..0..1.
.0..1..0.0
..1...1...
1.1......1
.......1..
.0..1...0.
....11...0
.0.0..1..0
0...0...1.

Output:
0110010101
1001100110
1001101010
0110011001
1010100101
0101010110
1001101001
0110110100
1010011010
0101001011


Yanıtlar:


4

Brachylog , 34 bayt

{ℕ<2}ᵐ²&≜{d?ọᵐctᵐ=&{ḅlᵐ⌉<3}ᵐ}&\↰₂&

Çevrimiçi deneyin!

Bu oldukça yavaş, bu yüzden TIO'daki test durumu 4x4. Şu anda ne kadar zaman aldığını görmek için bilgisayarımda 6x6 test durumunu çalıştırıyorum.

Bu listelerin bir listesini girdi olarak alır. Bilinmeyen değerler değişkenlerle, yani büyük harfli dizelerle belirtilmelidir (ve hepsi farklı olmalıdır, aksi takdirde bazı hücrelerin aynı değere sahip olması gerektiğini belirtmelisiniz)

açıklama

İçerideki değerleri kısıtlarız {0,1}, sonra 3 kurala da uyuncaya kadar değişkenlerin örneklemelerini deneriz. Bu yüzden bu kadar yavaştır (çünkü birini bulana kadar hepsini deneyecek ve bu durumda Brachylog yeterince iyi uygulanmadığından, olası bir matrisi denemeden önce kısıtlamalar uygulanabilecektir).

                                 &  Output = Input
{   }ᵐ²                             Map two levels on the Input (i.e. each cell):
 ℕ<2                                  The cell is either 0 or 1
       &≜                           Assign values to all cells
         {                  }       Define predicate 2:
          d?                          The Input with no duplicates is still the Input
                                        (i.e. all rows are different)
           ?ọᵐctᵐ=                    All occurences of 1s and 0s for each rows are equal
                  &{      }ᵐ          Map on rows:
                    ḅlᵐ                 Get the lengths of runs of equal values
                       ⌉<3              The largest one is strictly less than 3
                             &\↰₂   Apply predicate 2 on the transpose of the Input
                                      (i.e. do the same checks but on columns)

Meraktan, Brachylog sermaye alfabesinin ötesindeki değişkenleri nasıl gösterir? Diyelim ki çözümünüz daha hızlı çalışacak, 14x14 ızgaradaki tüm boş alanları Aiçinden Y( Zoutput parametresi ile) dolduramayacak . O devam mı AA, ABvs?
Kevin Cruijssen

2
@KevinCruijssen Her büyük harfli tanımlayıcı bir değişkendir, bu nedenle evet AAbir değişkendir ve KEVINCRUIJSSENaynı zamanda bir değişkendir.
17'de

3
Şüphelendiğim gibi, Brachylog için bir meydan okuma: D
Jonathan Allan

3

JavaScript (ES6), 274 270 bayt

Boş hücrelerin işaretlendiği 2D dizisi olarak girdi alır 2. Konsola olası tüm çözümleri yazdırır.

f=(a,x=0,y=0,w=a.length,p,R=a[y])=>(M=z=>!a.some((r,y)=>/(0|1),\1,\1/.exec(s=r.map((v,x)=>(v=z?v:a[x][y],b-=v&1,c-=!v,m|=v&2,v),b=c=w/2))||b*c<0|o[b*c||s]&(o[s]=1),o={}))(m=0)&M(1)&&(m?R&&[0,1].map(n=>(p=R[x])==n|p>1&&(R[x]=n,f(a,z=(x+1)%w,y+!z),R[x]=p)):console.log(a))

Nasıl çalışır

Kodun ilk kısmı M(), geçerli kartın geçerliliğini hem yatay hem de dikey olarak kontrol etmek için bu işlevi kullanır .

M = z =>
  !a.some((r, y) =>
    /(0|1),\1,\1/.exec(
      s = r.map((v, x) =>
        (
          v = z ? v : a[x][y],
          b -= v & 1,
          c -= !v,
          m |= v & 2,
          v
        ),
        b = c = w / 2
      )
    ) ||
    b * c < 0 |
    o[b * c || s] &
    (o[s] = 1),
    o = {}
  )

Tam bir satırı veya sütunu s dizesiyle eşler . Bu aslında bir dizeye zorlanan bir dizidir, bu yüzden öyle görünüyor "1,2,2,0,2,2".

Kullanır:

  • /(0|1),\1,\1/3 veya daha fazla ardışık özdeş basamağı algılamak için normal ifade .
  • Sayaçlar b ve c sayısının izlemek için olanlar ve sıfır . Her iki sayaç da w / 2 olarak başlatılır ve bir veya sıfırla (sırasıyla) her karşılaşıldığında azaltılır . Bu şunlardan birine yol açar:
    • B = C = 0 b * C = 0 → hattı (birçok şekilde tam ve doğru sıfır olarak olanlar )
    • b> 0 VE c> 0 b * c> 0 → hat tamamlandı ancak şu ana kadar doğru değil (biz yok fazla / 2 w sıfır veya birden / 2 w olanlar )
    • b <0 VEYA c <0 b * c <0 → çizgi geçersiz
  • Tahtada kalan en az iki tane varsa sıfır olmayan m bayrağı ('eksik' için) .
  • Nesne o ana kadar karşılaşılan tüm satır desenleri takip etmek.

Kart geçersizse hemen dururuz. Kart geçerli ve eksiksizse, konsola yazdırırız. Aksi takdirde, kodun ikinci kısmı her 2'yi bir sıfır veya yinelemeli çağrılarla bir tane ile değiştirmeye çalışır :

[0, 1].map(n =>
  (p = a[y][x]) == n |
  p > 1 && (
    a[y][x] = n,
    f(a, z = (x + 1) % w, y + !z),
    a[y][x] = p
  )
)

gösteri


Açıklamayı eklediğiniz için teşekkür ederiz. Ve tek bir çıktı yerine tüm olası çıktıları nasıl bastığınızı seviyorum!
Kevin Cruijssen

1
@KevinCruijssen Bu muhtemelen optimal olmaktan uzak ama yazmak eğlenceliydi. Güzel meydan okuma!
Arnauld

1

Jöle , 53 51 bayt

ṡ€3ḄFf0,7L
SḤnLṀȯÇ
⁻QȯÇ
Fṣ©2L’0,1ṗż@€®F€s€LÇÐḟZÇ$Ðḟ

İhtiva eden ızgara temsil listeleri, bir listesini alır 0, 1ve 2(boşluk). Liste listelerinin bir listesini döndürür, her liste listesi aynı formattadır ( 2s olmadan da ) ve giriş için olası bir çözümü temsil eder.

Çevrimiçi deneyin! (Bu, bellek sınırlamaları nedeniyle sorunun test durumlarından herhangi birini çalıştırmaz - tüm 2 nSpaces ızgarası tamsayı listelerinin bir listesi olarak oluşturulur - ancak orada tek bir çözümle nispeten ağır bir durum koydum). Altbilgi, ızgaraları ayırır ve biçimlendirir.

Saf kaba kuvvet yöntemi - kuralları uygular ve bunları s veya s 2ile değiştirerek oluşabilecek her ızgara için kontrol eder .10

ṡ€3ḄFf0,7L - Link 1, # of runs of 3 1s or 3 0s by row: list of lists
ṡ€3        - all contiguous slices of length 3 for €ach list
   Ḅ       - convert all results from binary
    F      - flatten into one list
     f     - filter keep values in:
      0,7  -   0 paired with 7: [0,7]
         L - length

SḤnLṀȯÇ - Link 2, unequal counts of 1s and 0s by column ...or link 1: list of lists
S       - sum (vectorises, hence "by column", counts 1s since only 1s or 0s appear)
 Ḥ      - double
   L    - length (number of rows - OK since square)
  n     - not equal? (vectorises)
    Ṁ   - maximum (1 if any not equal)
     ȯÇ - ... or last link (1) as a monad

⁻QȯÇ - Link 3, rows are unique ...or link 2: list of lists
 Q   - unique
⁻    - not equal?
  ȯÇ - ... or last link (2) as a monad

Fṣ©2L’0,1ṗż@€®F€s€LÇÐḟZÇ$Ðḟ - Main link: list of lists
F                           - flatten
 ṣ©2                        - split at 2s and copy the result to the register
    L                       - length (# of such slices)
     ’                      - decrement (# of 2s)
      0,1                   - 0 paired with 1
         ṗ                  - Cartesian power (all binary lists of length # of 2s)
             ®              - recall value from register (the flat version split at 2s)
          ż@€               - zip (reversed @rguments) for €ach (1s & 0s where 2s were)
              F€            - flatten €ach
                s€L         - split €ach into chunks of length length(input) (into rows)
                    Ðḟ      - filter discard if:
                   Ç        -   call last link(3) as a monad
                         Ðḟ - filter discard if:
                        $   -   last two links as a monad:
                      Z     -     transpose
                       Ç    -     call last link(3) as a monad
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.