Nonogram çizgi kaba kuvvet çözümü


25

Arka fon

Picross veya Griddlers olarak da bilinen Nonogram , amacın 2B ızgaradaki her bir hücrenin, her bir satırdaki ardışık renkli hücrelerin sayıları kullanılarak renklendirilmesi veya boş bırakılması gerekip gerekmediğini belirlemek olduğu bir bilmecedir.

Aşağıdaki çözüm ile örnek bir Nonogram bulmacası.

Sorun şu ki, bazı ticari Nonogram oyunlar / mobil uygulamalar elle çözülemeyen bulmacalara sahipler (örneğin, birden çok çözümü var veya derinlemesine izlemeyi gerektiren). Bununla birlikte, oyuncuya, doğru cevabı boş olan bir hücreyi renklendirmeye çalıştığınızda bir canın kaybolduğu bazı hayatlar da sunar . Öyleyse şimdi bu kötü "bulmacaları" zorla uygulama zamanı!

Görevi basitleştirmek için ipucuyla yalnızca bir satır hayal edin ve başka bir şey yapmayın:

3 7 | _ _ _ _ _  _ _ _ _ _  _ _ _ _ _

[3,7]İpuçları, ve hat uzunluğu 15 hücreleri. Birden fazla olası çözümü olduğundan, bu çizgiyi tamamen çözmek için bazı yaşamları riske atmamız gerekiyor (yani tüm renkli hücreleri belirlemek).

Meydan okuma

İpuçlarını içeren bir çizgi (pozitif tamsayıların bir listesi) ve çizgi uzunluğu göz önüne alındığında, çizgiyi en uygun strateji ile kaba bir şekilde zorladığınızı varsayarak kaybedeceğiniz maksimum yaşam sayısını bulun.

Renkli hücreleri her zaman tahmin edebileceğinizi unutmayın . Gerçek oyunlarda, boş hücreleri tahmin etmenin (doğru ya da yanlış) yaşamınız üzerinde bir etkisi yoktur, dolayısıyla bulmacayı bu şekilde “çözemezsiniz”.

Ayrıca, girişin her zaman geçerli bir Nonogram çizgisini temsil ettiğini varsayabilir, bu nedenle böyle bir konuda endişelenmenize gerek yoktur [6], 5.

açıklama

İlk önce daha basit örneklere bakalım.

[1,2], 5

Bu çizgi için tam olarak üç olasılık vardır ( Orenkli bir hücredir, .boş bir tanedir):

O . O O .
O . . O O
. O . O O

Hücre 0'ı (soldan 0 temelli dizin) renklendirmeyi denersek, aşağıdakilerden biri olur:

  • Hücre doğru renklendirilmiş. Şimdi iki ihtimalimiz var ve çizgiyi tam olarak çözmek için hücre 2 ile hücre 4 arasında seçim yapabiliriz. Her iki durumda da, en kötü durumda bir canını kaybedeceğiz.
  • Hücre boş ve bir canımızı kaybediyoruz. Bu durumda, bu çizginin benzersiz çözümünü zaten belirledik, bu yüzden 1 hayatımızı kaybettik.

Bu nedenle, cevap [1,2], 51'dir.

[5], 10

Ikili arama? Hayır!

En belirgin ilk seçenek 4 veya 5'tir; bu, boş olması durumunda (1 hayat pahasına) bir olasılığı ortaya çıkarır. Diyelim ki önce 4 tane seçtik. Hücre 4 gerçekten renkliyse, sola doğru uzatırız, yani bir hayat kaybolana kadar 3, 2, 1 ve 0'ı deneyin (ya da hücre 0 renkli olana kadar, o zaman hiç hayat geçirmeyiz). Ne zaman bir hayat kaybedilirse, çözümü benzersiz bir şekilde belirleyebiliriz, örneğin böyle bir şey görürsek:

_ _ X O O _ _ _ _ _

o zaman cevabın bu olduğunu zaten biliyoruz:

. . . O O O O O . .

Bu nedenle, cevabı [5], 10da 1'dir.

[3,7], 15

Boşsa, hemen aşağıdaki çözümü ortaya çıkaracak olan hücre 11 ile başlayın.

O O O . O O O O O O O X . . .

Sonra 12'yi deneyin; eğer boşsa, 1 ekstra ömür pahasına çözülebilecek iki olasılık sunar.

O O O . . O O O O O O O X . .
. O O O . O O O O O O O X . .

Şimdi 2 deneyin. Boşsa, [1,2], 5örneğe benzer şekilde çözülebilecek üç olasılık ortaya çıkar .

. . X O O O . O O O O O O O .
. . X O O O . . O O O O O O O
. . X . O O O . O O O O O O O

Bu şekilde riski en aza indirmeye devam ederseniz, max ile herhangi bir çözüme ulaşabilirsiniz. 2 hayat geçirdi.

Test Kılıfları

[1,2] 5 => 1
[2] 5 => 2
[1] 5 => 4
[] 5 => 0
[5] 10 => 1
[2,1,5] 10 => 0
[2,4] 10 => 2
[6] 15 => 2
[5] 15 => 2
[4] 15 => 3
[3,7] 15 => 2
[3,4] 15 => 3
[2,2,4] 15 => 4
[1,1,1,1,1,1,1] 15 => 2

[2,1,1,3,1] 15 => 3
[1,1,1,2,1] 15 => 5

Son iki durumda, en uygun strateji minimum boşluklardan geçmek değil , sadece soldan sağa (veya sağdan sola) geçmek. Onu işaret ettiği için @crashoz teşekkürler.

kurallar

Standart kuralları geçerlidir. Bayt cinsinden en kısa geçerli gönderim kazanır.

cömertlik

Biri polinom-zaman algoritmasıyla (doğruluk ispatıyla) gelirse, böyle bir çözüme +100 ödül vereceğim.


Amaçlanan çıktı nedir [6], 5?
Sızdıran Rahibe

Bir tahminde bulunduğunuzda, hücrenin siyah olduğunu tahmin etmek zorunda mısınız yoksa siyah mı yoksa beyaz mı olduğunu tahmin edebiliyor musunuz?
feersum

@ LeakyNun Geçersiz bir satır. Girişin her zaman geçerli bir Nonogram satırı olduğunu varsayabilirsiniz.
Bubbler

@feersum Her zaman renkli hücreleri tahmin edersiniz. Gerçek oyunlarda, boş bir hücreyi (doğru ya da yanlış) tahmin etmek hayatınızı etkilemez, bu nedenle onunla herhangi bir geri bildirim alamazsınız.
Bubbler

Harika bir meydan okuma
Enrico Borba

Yanıtlar:


19

Ruby , 85 bayt

f=->l,n,s=n-l.sum-l.size+1{*a,b=l;b&&s>0?(a[0]?1+f[a,n-b-2,s-1]:(n.to_f/b).ceil-1):0}

Çevrimiçi deneyin!

açıklama

l=[l1,l2,...,lx]xn

lx
nlx
nlx1+f(l,nlx)
1+f(l~,nlx2)l~l

Böylece ise bu fonksiyon ile yaşam sayısını alabiliriz.

f(l,n)={0,if 1xli+x1nnlx1if x=11+max{f(l,nlx)f(l~,nlx2),otherwise

İşte bir örnek _bilinmemektedir, Xbilinen bir alandır, Obilinen bir renkli hücredir ve Lhayat kaybedilir

[2,2,4] 15                  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
(1) -> [2,2,4] 11           _ _ _ _ _ _ _ _ _ _ _ L X X X
    (1) -> [2,2,4] 7        _ _ _ _ _ _ _ L X X X L X X X
        0                   X X X L X X X L X X X L X X X
    (2) -> [2,2] 5          _ _ _ _ _ X O O O O L L X X X
        0                   O O X O O X O O O O L L X X X 
(2) -> [2,2] 9              _ _ _ _ _ _ _ _ _ X O O O O L
    (1) -> [2,2] 7          _ _ _ _ _ _ _ L X X O O O O L
        (1) -> [2,2] 5      _ _ _ _ _ L X L X X O O O O L
            0               O O X O O L X L X X O O O O L
        (2) -> [2] 3        _ _ _ X O O L L X X O O O O L
            1               O O L X O O L L X X O O O O L               
    (2) -> [2] 5            _ _ _ _ _ X O O L X O O O O L
        2                   O O L L X X O O L X O O O O L

O(2n)

h

h(l,n)=n1xlix+1

h

h

h(l,nlx)=nlx1xlix+1=(n1xlix+1)lx=h(l,n)lx

h(l~,nlx2)=nlx21x1li(x1)+1=(n1xlix+1)1=h(l,n)1

h(l,n)={0,if 1xli+x1nnlx,if x=1max{h(l,nlx)+lxh(l~,nlx2)+1,otherwise

h

[h(l,nlx)+lx][h(l~,nlx2)+1]=nlxn1xlix+1+lx[nlx21x1li(x1)+1+1]=2

[h(l,nlx)+lx][h(l~,nlx2)+1]=2[h(l,nlx)+lx][h(l~,nlx2)+1]<0[h(l,nlx)+lx]<[h(l~,nlx2)+1]

h(l,n)={0,if 1xli+x1nnlx,if x=1h(l~,nlx2)+1otherwise

hfh

f(l,n)={0,if 1xli+x1nnlx1if x=11+f(l~,nlx2),otherwise

nO(n)


2
PPCG'ye hoş geldiniz, inanılmaz ilk mesaj!
Cole

1
@cole İlk gönderileri değil, ama kesinlikle inanılmaz! Çok akıllıca bir yaklaşım +1
Bay Xcoder

1
Mükemmel iş. O güne kadar kimse ciddi bir mantıksal kusur bulamazsa 2 gün sonra ödülünü vereceğim.
Bubbler

2

Python, 303 289 bayt

Uzun zamandır ilk golf oynamak, bu yüzden çok fazla aşırı yağ olabilir. ( 14 bayt değerinde bulduğun için teşekkürler Jo King .)

F işlevi mümkün olan tüm düzenlemeleri oluşturur (her zaman ilk karakter olarak boş bırakılmış olsa da, ancak aramadan önce uzunluğu 1 artırdıkça sorun olmaz). G işlevi, en az sayıda boşluk ve özdeyişle konumu seçer. H işlevi onları bir araya getirir.

f=lambda l,n:["."*i+"X"*l[0]+c for i in range(1,n-l[0]+1)for c in f(l[1:],n-i-l[0])]if l else["."*n]
def g(q,n):O,X=min([[[p[:i]+p[i+1:]for p in q if p[i]==u]for u in".X"]for i in range(n)],key=lambda x:len(x[0]));return(len(q)>1)*1and max(1+g(O,n-1),g(X,n-1))
h=lambda l,n:g(f(l,n+1),n+1)

Örneklerin hepsi iyi çalışıyor:

>>> h([3,7],15)
2
>>> h([3,4],15)
3
>>> h([1,1,1,2,1],15)
6


1
İade etmek izin var Falseiçin 0? Eğer öyleyse, değiştirebilir (len(q)>1)*1andiçin len(q)>1and. İade etmek izniniz yoksa Falseiçin 0o zaman bunu, ama değişim g(f(l,n+1),n+1)için 1*g(f(l,n+1),n+1)ve o-ecek hala bir byte tasarrufu
Zachary

1
Daha da iyisi: durumunda Falseizin verilmez 0yerine değişen, g(f(l,n+1),n+1)için 1*g(f(l,n+1),n+1)için değiştirmek,+g(f(l,n+1),n+1)
Zachary

2
Ayrıca, h=bayt sayınızı da saymanıza gerek yok
Zacharý

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.