จัดกลุ่มเซลล์เหล่านี้!


12

ความท้าทายนี้ขึ้นอยู่กับเกมLayerz

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

สิ่งต่อไปนี้ถือว่าเป็นภูมิภาคที่ถูกต้อง:

  • เซลล์เดียวที่มี 1
  • เซลล์ที่มี 2 และหนึ่งในเพื่อนบ้าน orthogonal ที่ไม่ว่างเปล่า
  • เซลล์ที่มี 3 และสองของเพื่อนบ้าน orthogonal ไม่ว่าง
  • เซลล์ที่มี 4 และสามของเพื่อนบ้าน orthogonal ไม่ว่าง

นี่คือดังนั้นคำตอบที่ถูกต้องสั้นที่สุดเป็นไบต์ชนะ

กรณีทดสอบบางส่วน:

1. คนที่ค่อนข้างเล็กน้อย:

ป้อนคำอธิบายรูปภาพที่นี่

และนี่คือวิธีแก้ปัญหาโดยแต่ละภูมิภาคมีสีแตกต่างกัน:

ป้อนคำอธิบายรูปภาพที่นี่

2. อันที่น่าสนใจมากกว่า

ป้อนคำอธิบายรูปภาพที่นี่

อันนี้มีทางออกมากกว่าหนึ่งอัน แต่นี่คือหนึ่งในนั้น:

ป้อนคำอธิบายรูปภาพที่นี่

3. ตัวที่เล็กกว่าที่มีช่องว่างซึ่งไม่มีวิธีแก้ปัญหาใด ๆ (ขึ้นอยู่กับว่าคุณใช้หนึ่งใน twos เพื่อ "จับ" สามหรือสามเพื่อใช้สอง twos คุณเหลือด้วย คู่ที่ไม่อยู่ติดกัน [และจึงไม่สามารถจัดกลุ่มได้] สองครั้งหรือสองตัวเดียว):

ป้อนคำอธิบายรูปภาพที่นี่

เนื่องจากกริดนี้ไม่มีวิธีแก้ปัญหาโปรแกรมของคุณควรหยุดทำงานโดยไม่สร้างเอาต์พุตใด ๆ เมื่อให้กริดนี้

4. อันนี้ (ด้วย 2 อันดับแรกที่เลื่อนไปหนึ่งเซลล์ทางซ้าย) จะมีวิธีแก้ไขดังนี้:

ป้อนคำอธิบายรูปภาพที่นี่

วิธีการแก้:

ป้อนคำอธิบายรูปภาพที่นี่

(ขวาล่าง 2 ใช้เพื่อ "จับ" 3)

5. เพราะเราต้องการกรณีทดสอบที่มีสี่:

ทางออกหนึ่ง:


2
มันจะมีประโยชน์ถ้ามีกรณีทดสอบ ASCII เวอร์ชันดังนั้นผู้ใช้ไม่จำเป็นต้องพิมพ์ทั้งหมดและกรณีทดสอบควรครอบคลุม4s หากไฟล์เหล่านั้นเป็นอินพุตที่ถูกต้อง
Martin Ender

1
เพื่อนบ้านแบบมุมฉากหมายถึงซ้ายขวาขึ้นหรือเป็นเส้นทแยงมุมเท่านั้น? ถ้าเหลือเพียงขวาลงมาทำไม 3 อยู่ในภูมิภาคเดียวกับอีกสอง 3? หนึ่งในนั้นไม่ได้เป็นเพื่อนบ้านมุมฉาก
Eyal Lev

@EyalLev เฉพาะจากซ้ายไปขวาขึ้นลง มุมบนขวา 3 และ 2 ประเทศเพื่อนบ้านเป็นภูมิภาค
SuperJedi224

@ SuperJedi224 ด้านบนขวา 3 และเป็นสองประเทศเพื่อนบ้านเป็นภูมิภาคที่ถูกต้องใช่ แต่เพื่อนบ้านเหล่านั้นไม่ได้ ภูมิภาคต้องไม่เป็น "ชุดปิด" หรือไม่ คือสมาชิกทุกคนในภูมิภาคต้องเป็นสมาชิกที่ถูกต้องของภูมิภาคนั้น ๆ
Eyal Lev

คำตอบ:


3

ฉันรู้ว่าความท้าทายนี้มีอายุเกินหนึ่งปี แต่ฉันเพิ่งพบสิ่งนี้ใน "คำตอบ" และดูน่าสนใจสำหรับฉัน

สมมติว่าหมายเลขของเซลล์ "root" เป็นสิ่งสำคัญเพียงหนึ่งเดียวในแต่ละภูมิภาค (สามารถอนุมานได้จากตัวอย่าง) นี่คือโซลูชันการย้อนรอยของฉัน:

Python 3 , 355 351 349 ไบต์

from itertools import*
def f(a):
 D=len(a[0])+1;S={D*r+c for r in range(len(a))for c in range(D-1)if a[r][c]};s=[{x,*t}for x in S for t in combinations({x-D,x-1,x+1,x+D}&S,a[x//D][x%D]-1)]
 def B(s,S,d=1):
  if{0}>S:return a
  if[]==s:return 0
  h,*t=s
  if h<=S:
   for x in h:a[x//D][x%D]=d
  return h<=S and B(t,S-h,d+1)or B(t,S,d)
 return B(s,S)

ลองออนไลน์!

รูปแบบการป้อนข้อมูลเป็นรายการ 2D ของจำนวนเต็มช่องว่างเป็นศูนย์และรูปแบบเอาต์พุตยังเป็นรายการจำนวนเต็ม 2D ที่แสดงถึงหนึ่งภูมิภาคต่อหมายเลข หมายเลขภูมิภาคเริ่มต้นที่หนึ่ง ศูนย์ถูกสงวนไว้สำหรับเซลล์ว่าง (เช่นในอินพุต) หากอินพุตที่ระบุไม่สามารถแก้ไขได้ฟังก์ชันจะส่งกลับค่าศูนย์เดียว (ค่าเท็จ)

ตัวอย่างเช่นกรณีทดสอบ 5 คืออินพุตเป็น

[[2,3,2],
 [3,4,3],
 [0,4,0],
 [3,3,3],
 [2,3,2],
 [0,3,0]]

และผลลัพธ์คือ

[[1,1,1],
 [2,2,2],
 [0,2,0],
 [3,4,5],
 [3,4,5],
 [0,4,0]]

Ungolfed พร้อมความคิดเห็น:

from itertools import*
def f(a):
 # Rows, cols, fake-cols to prevent neighbors wrap around
 R,C=len(a),len(a[0]);D=C+1
 # All valid cells represented as integers
 S={D*r+c for r in range(R) for c in range(C) if a[r][c]}
 # All valid regions rooted at each cell
 s=[{x,*t} for x in S for t in combinations({x-D,x-1,x+1,x+D}&S,a[x//D][x%D]-1)]
 # Start backtracking
 return backtrack(a,s,S,D)

# a: array to fill in the region numbers
# s: current candidates of regions
# S: current remaining cells to cover
# D: constant from f
# d: recursion depth == group number in the result
def backtrack(a,s,S,D,d=1):
 # Empty S: the board is correctly covered, return the result
 if not S:return a
 # Empty s: no more candidate regions to use, return false
 if not s:return 0
 h,*t=s
 # h is not a subset of S: h is not a valid cover, try with the rest using same depth
 if not h<=S:return backtrack(a,t,S,D,d)
 # h is a valid cover, write d to the cells in h
 for x in h:a[x//D][x%D]=d
 return backtrack(a,t,S-h,D,d+1)or backtrack(a,t,S,D,d)
 

ลองออนไลน์!

หมายเหตุ:นี่เป็นกรณีพิเศษของSet Packingซึ่งเป็นที่รู้จักกันดีในชื่อ NP-complete ปัญหาเฉพาะนี้มีขนาดชุดที่ จำกัด (สูงสุด 4) และมีอัลกอริทึมโดยประมาณเพื่อหาชุดการบรรจุที่ "ดี" ในเวลาพหุนาม แต่พวกเขาไม่รับประกันการบรรจุชุดที่เป็นไปได้สูงสุด (ซึ่งจำเป็นอย่างยิ่งในปัญหานี้)

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