Bu hücreleri gruplayın!


12

Bu meydan okuma Layerz oyununa dayanmaktadır.

Stdin'de veya işlev bağımsız değişkeni olarak, her hücrenin boşluk içerdiği 2B dikdörtgen hücre dizisi verildiğinde (penaltı olmadan boşluklar yerine 0'lar kullanmayı seçebilirsiniz), 1, a 2, 3 veya 4 ; boş olmayan her hücre tam olarak bir bölge içerecek şekilde geçerli bölgelere (aşağıda tanımlandığı gibi) bölmenin bir yolunu bulun. Sonra, makul bir biçimde bulunan çözümü çıktı. Çözüm yoksa, çıktı üretmeden durdurun veya tek bir falsey değeri verin ve ardından durdurun.

Aşağıdakilerden herhangi biri geçerli bir bölge oluşturur:

  • 1 içeren tek bir hücre
  • 2 ve tam olarak boş olmayan dikey komşularından birini içeren bir hücre
  • Boş olmayan ortogonal komşularının 3 ve tam ikisini içeren bir hücre
  • Boş olmayan ortogonal komşularının 4 ve tam olarak üçünü içeren bir hücre

Bu , bu yüzden bayt cinsinden en kısa geçerli cevap kazanır.

Bazı test örnekleri:

1. Oldukça önemsiz olan:

resim açıklamasını buraya girin

Ve çözüm, her bölge farklı bir renkte:

resim açıklamasını buraya girin

2. Daha ilginç bir tane

resim açıklamasını buraya girin

Bunun birden fazla çözümü var, ama işte bunlardan biri:

resim açıklamasını buraya girin

3. Herhangi bir çözümü olmayan boşluklar içeren daha küçük bir çözüm (ikisini "yakalamak için" ikisinden birini veya ikiden ikisini almak için üçünü kullanmanıza bağlı olarak, bitişik olmayan [ve dolayısıyla gruplandırılamayan] ikişer ikişer tek başına ikişer tane):

resim açıklamasını buraya girin

Bu ızgarada çözüm bulunmadığından, bu ızgara verildiğinde programınız çıktı üretmeden durmalıdır.

4. Bu (ilk 2 bir hücre sola kaydırılmış) bir çözüm var:

resim açıklamasını buraya girin

Çözüm:

resim açıklamasını buraya girin

(Sağ alt 2, 3'ü "yakalamak" için kullanılır)

5. Çünkü biz dört ayak ile bir test durumda gerekli:

Bir çözüm:


2
Test vakalarının ASCII sürümleri varsa yararlı olacaktır, bu yüzden insanların hepsini yazmak zorunda kalmamaları gerekir ve test vakaları 4geçerli girdi ise s'yi de kapsamalıdır .
Martin Ender

1
Ortogonal komşular sadece sağ aşağı yukarı sola mı yoksa köşegenlere mi karşılık gelir? eğer sadece sağ yukarı aşağı bırakılırsa, 3 nasıl diğer iki 3 ile aynı bölgede olur? onlardan biri dik bir komşu değil.
Eyal Lev

@EyalLev Yalnızca sol-sağ-yukarı-aşağı. Sağ üst 3 ve 2 komşusu bölgeyi oluşturmaktadır.
SuperJedi224

@ SuperJedi224 sağ üst 3 ve iki komşusu geçerli bir bölge oluşturuyor, evet, ama bu komşular oluşturmuyor. bir bölge "kapalı küme" olmak zorunda değil mi? yani bölgedeki her üye o bölgenin geçerli bir üyesi olmalıdır?
Eyal Lev

Yanıtlar:


3

Bu zorluğun bir yıldan daha eski olduğunu biliyorum, ama bunu "cevapsız" olarak buldum ve benim için oldukça ilginç görünüyordu.

"Kök" hücrenin sayısının her bölgedeki tek anlamlı sayı olduğunu varsayarsak (örneklerden çıkarılabilir), işte benim geri izleme çözümüm:

Piton 3 , 355 351 349 bayt

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)

Çevrimiçi deneyin!

Girdi biçimi, tamsayıların 2B, sıfır olarak boşlukların listesidir ve çıktı biçimi, sayı başına bir bölgeyi temsil eden tamsayıların 2B listesidir. Bölge numarası bir ile başlar; sıfır boş hücreler için ayrılmıştır (girişte olduğu gibi). Verilen giriş çözülemezse, işlev tek sıfır (falsy değeri) döndürür.

Örneğin, test durumu 5 aşağıdaki gibi girilir:

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

ve çıktı

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

Ungolfed, yorumlarla:

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)
 

Çevrimiçi deneyin!

Not: Bu, NP-tam olduğu bilinen iyi bir Set Paketleme özelliğidir. Bu özel sorun sınırlı set boyutuna (maks. 4) sahiptir ve polinom zamanında "iyi" set ambalajı bulmak için yaklaşık algoritmalar vardır, ancak mümkün olan maksimum set ambalajını garanti etmezler (bu problemde kesinlikle gereklidir).

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.