การแก้แรงเดรัจฉานแบบ nonogram เส้น


25

พื้นหลัง

Nonogramหรือที่เรียกว่า Picross หรือ Griddlers เป็นปริศนาที่มีวัตถุประสงค์เพื่อตรวจสอบว่าแต่ละเซลล์ในตาราง 2D ควรมีสีหรือเว้นว่างไว้โดยใช้หมายเลขของเซลล์สีที่ต่อเนื่องกันในแต่ละบรรทัด

ต่อไปนี้เป็นตัวอย่างปริศนา Nonogram พร้อมโซลูชัน

ปัญหาคือเกม Nonogram เชิงพาณิชย์ / แอพมือถือบางส่วนมีปริศนาที่ไม่สามารถแก้ไขได้ด้วยมือ (เช่นมีวิธีแก้ปัญหาหลายอย่างหรือต้องใช้การย้อนรอยลึก) แต่พวกเขายังมีชีวิตบางอย่างที่จะเป็นผู้เล่นที่ชีวิตหนึ่งจะหายไปเมื่อคุณพยายามที่จะสีของเซลล์ที่มีคำตอบที่ถูกต้องคือว่างเปล่า ดังนั้นถึงเวลาที่จะบังคับให้ "ปริศนา" ที่น่ารังเกียจ!

เพื่อให้งานง่ายขึ้นลองจินตนาการถึงหนึ่งบรรทัดด้วยเงื่อนงำและไม่มีอะไรอื่น:

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

The [3,7]clues และความยาวบรรทัดคือ 15 เซลล์ เนื่องจากมันมีวิธีแก้ปัญหาที่เป็นไปได้หลายอย่างเราจึงต้องเสี่ยงชีวิตเพื่อที่จะแก้ปัญหานี้ได้อย่างเต็มที่ (เช่นกำหนดเซลล์สีทั้งหมด)

ท้าทาย

กำหนดบรรทัดคำใบ้ (รายการจำนวนเต็มบวก) และความยาวบรรทัดค้นหาจำนวนสูงสุดของชีวิตที่คุณจะสูญเสียโดยสมมติว่าคุณกำลังบังคับใช้กลยุทธ์ที่ดีที่สุด

โปรดทราบว่าคุณคาดเดาเซลล์ที่มีสีเสมอ ในเกมจริงการคาดเดาเซลล์ว่างเปล่า (ไม่ว่าจะถูกหรือผิด) ไม่มีผลต่อชีวิตของคุณดังนั้นคุณจึงไม่สามารถ "ไขปริศนา" ได้

นอกจากนี้คุณยังสามารถสันนิษฐานได้ว่าการป้อนข้อมูลที่ถูกต้องเสมอหมายถึงบรรทัด nonogram [6], 5ดังนั้นคุณจึงไม่จำเป็นต้องกังวลเกี่ยวกับสิ่งที่ชอบ

คำอธิบาย

ลองดูตัวอย่างที่ง่ายกว่าก่อน

[1,2], 5

มีความเป็นไปได้สามประการสำหรับบรรทัดนี้ ( Oเป็นเซลล์ที่มีสี.เป็นหนึ่งที่ว่างเปล่า):

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

หากเราลองระบายสีเซลล์ 0 (ดัชนี 0 จากซ้าย) จะเกิดสิ่งใดสิ่งหนึ่งต่อไปนี้:

  • เซลล์มีสีถูกต้อง ตอนนี้เรามีความเป็นไปได้สองอย่างและเราสามารถเลือกระหว่างเซลล์ 2 กับเซลล์ 4 เพื่อแก้ปัญหาได้อย่างเต็มที่ ทั้งสองกรณีเราจะสูญเสียหนึ่งชีวิตในกรณีที่เลวร้ายที่สุด
  • เซลล์ว่างเปล่าและเราสูญเสียชีวิต ในกรณีนี้เราได้ระบุวิธีการแก้ปัญหาที่ไม่ซ้ำกับสายนี้แล้วดังนั้นเราจึงทำไปด้วย 1 ชีวิตที่หายไป

ดังนั้นคำตอบ[1,2], 5คือ 1

[5], 10

ค้นหาไบนารี่? Nope

ตัวเลือกแรกที่ชัดเจนที่สุดคือ 4 หรือ 5 ซึ่งจะเปิดเผยความเป็นไปได้หนึ่งอย่างถ้าว่างเปล่า (มีค่าเท่ากับ 1 ชีวิต) สมมติว่าเราเลือก 4 ก่อน หากเซลล์ 4 มีสีจริงเราขยายไปทางซ้ายคือลอง 3, 2, 1 และ 0 จนกว่าชีวิตจะหายไป (หรือเซลล์ 0 เป็นสีแล้วเราจะไม่เสียชีวิตเลย) เมื่อใดก็ตามที่ชีวิตหายไปเราสามารถกำหนดวิธีการแก้ปัญหาที่ไม่ซ้ำกันเช่นถ้าเราเห็นสิ่งนี้:

_ _ X O O _ _ _ _ _

จากนั้นเราก็รู้แล้วว่าคำตอบคือ:

. . . O O O O O . .

ดังนั้นคำตอบ[5], 10ก็คือ 1

[3,7], 15

เริ่มต้นด้วยเซลล์ 11 ซึ่งหากว่างเปล่าจะเปิดเผยโซลูชันต่อไปนี้ทันที

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

จากนั้นลอง 12 ซึ่งถ้าว่างเปล่าให้สองความเป็นไปได้ซึ่งสามารถแก้ไขได้โดยเสียค่าใช้จ่าย 1 ชีวิตเพิ่มเติม

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

ตอนนี้ลอง 2 ถ้าว่างเปล่ามันจะนำไปสู่ความเป็นไปได้สามอย่างที่สามารถแก้ไขได้เช่นเดียวกับ[1,2], 5ตัวอย่าง

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

หากคุณลดความเสี่ยงให้น้อยที่สุดในลักษณะนี้คุณสามารถเข้าถึงโซลูชันได้สูงสุด 2 ชีวิตใช้เวลา

กรณีทดสอบ

[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

สำหรับสองกรณีสุดท้ายกลยุทธ์ที่ดีที่สุดจะไม่ผ่านช่องว่างขั้นต่ำ แต่เพียงจากซ้ายไปขวา (หรือจากขวาไปซ้าย) ขอบคุณ @crashoz ที่ชี้ให้เห็น

กฎระเบียบ

ใช้กฎมาตรฐานของการส่งที่ถูกต้องสั้นที่สุดในหน่วยไบต์ชนะ

เงินรางวัล

หากมีคนคิดอัลกอริธึมเวลาพหุนาม (พร้อมหลักฐานการพิสูจน์ความถูกต้อง) ฉันจะมอบรางวัลให้กับโซลูชั่นดังกล่าวจำนวน +100


ผลลัพธ์ที่ต้องการมีไว้ทำ[6], 5อะไร?
Leun Nun

เมื่อคุณคาดเดาคุณต้องเดาว่าเซลล์เป็นสีดำหรือคุณสามารถเดาได้ว่าเป็นสีดำหรือสีขาว
feersum

@LeakyNun มันเป็นบรรทัดที่ไม่ถูกต้อง คุณสามารถสมมติว่าการป้อนข้อมูลเป็นเส้น Nonogram ที่ถูกต้องเสมอ
Bubbler

@feersum คุณเดาเซลล์สีเสมอ ในเกมจริงการคาดเดาเซลล์ว่างเปล่า (ไม่ว่าจะถูกหรือผิด) ไม่มีผลต่อชีวิตของคุณดังนั้นคุณจึงไม่สามารถรับข้อเสนอแนะได้
Bubbler

ความท้าทายที่ยอดเยี่ยม
Enrico Borba

คำตอบ:


19

Ruby , 85 ไบต์

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}

ลองออนไลน์!

คำอธิบาย

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

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

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

นี่คือตัวอย่าง_ที่ไม่รู้จักXเป็นพื้นที่Oที่รู้จักเป็นเซลล์สีที่รู้จักและLสูญเสียชีวิต

[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 โพสต์แรกที่เหลือเชื่อ!
โคล

1
@ โคลมันไม่ใช่โพสต์แรกของพวกเขา แต่มันก็น่าทึ่งจริงๆ! วิธีการที่ฉลาดมาก +1
Mr. Xcoder

1
งานที่ยอดเยี่ยม ฉันจะให้รางวัลเงินรางวัล 2 วันต่อมาถ้าไม่มีใครพบข้อบกพร่องเชิงตรรกะที่ร้ายแรงใด ๆ จนกระทั่งถึงตอนนั้น
Bubbler

2

Python, 303 289 ไบต์

กอล์ฟเป็นครั้งแรกในระยะเวลานานดังนั้นอาจมีไขมันส่วนเกินจำนวนมาก (ขอบคุณJo Kingสำหรับการหาค่า 14 ไบต์)

ฟังก์ชั่น f สร้างการจัดเรียงที่เป็นไปได้ทั้งหมด (แม้ว่าจะมีช่องว่างเป็นอักขระตัวแรกเสมอ แต่ก็ดีตราบเท่าที่เราเพิ่มความยาว 1 ก่อนที่จะเรียกมัน) ฟังก์ชั่น g เลือกตำแหน่งที่มีจำนวนช่องว่างน้อยที่สุดและเกิดซ้ำ ฟังก์ชั่น h ทำให้พวกมันอยู่ด้วยกัน

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)

ตัวอย่างทั้งหมดทำงานได้ดี:

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


1
คุณได้รับอนุญาตให้กลับFalseสำหรับ0? ถ้าเป็นเช่นนั้นคุณสามารถเปลี่ยนไป(len(q)>1)*1and len(q)>1andถ้าคุณไม่ได้รับอนุญาตให้กลับFalseสำหรับ0แล้วทำอย่างนั้น แต่การเปลี่ยนแปลงg(f(l,n+1),n+1)ไป1*g(f(l,n+1),n+1)และมันจะยังคงบันทึกหนึ่งไบต์
Zachary

1
ได้ดียิ่งขึ้น: ในกรณีที่Falseไม่ได้รับอนุญาต0แทนการเปลี่ยนแปลงg(f(l,n+1),n+1)ที่จะ1*g(f(l,n+1),n+1)เปลี่ยนไป+g(f(l,n+1),n+1)
Zachary

2
นอกจากนี้คุณไม่จำเป็นต้องนับจำนวนh=ไบต์ของคุณ
Zacharý

1
288 ไบต์
Jonathan Frech
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.