Згрупуйте ці клітини!


12

Ця задача заснована на грі Layerz.

Враховуючи, на stdin або як аргумент функції, 2D прямокутний масив комірок, де кожна комірка містить чи порожню (ви можете використовувати 0s замість пробілів без штрафних санкцій), 1, 2, 3 або 4 ; знайти спосіб поділити його на допустимі регіони (як визначено нижче) таким чином, щоб кожна непуста клітинка містила точно одну область. Потім виведіть знайдене рішення у будь-якому розумному форматі. Якщо рішення немає, або зупиніть, не виробляючи вихід, або виведіть єдине значення фальси, тоді зупиніть.

Будь-який із наведених нижче дійсних регіонів:

  • Єдина клітина, що містить 1
  • Клітина, що містить 2 та точно один із своїх непорожніх ортогональних сусідів
  • Клітина, що містить 3 та рівно два її непорожніх ортогональних сусіда
  • Клітина, що містить 4 та рівно три її непорожніх ортогональних сусіда

Це , тому найкоротша відповідна відповідь у байтах виграє.

Деякі тестові випадки:

1. Досить тривіальний:

введіть тут опис зображення

І це рішення, кожен регіон має інший колір:

введіть тут опис зображення

2. Більш цікавий

введіть тут опис зображення

У цьому є кілька рішень, але ось одне з них:

введіть тут опис зображення

3. Менший, який містить пробіли, не має жодних рішень (залежно від того, чи використовуєте ви одне з двох для "захоплення" трьох, або три, щоб взяти два з двох, вам або залишилося пара несумісних [і, отже, нерозбірливих] двох або одиничних двох самостійно):

введіть тут опис зображення

Оскільки в цій сітці немає рішень, ваша програма повинна зупинятися, не даючи жодного результату при даній сітці.

4. Цей (у верхній частині 2 змістив одну клітинку вліво) має рішення, хоча:

введіть тут опис зображення

Рішення:

введіть тут опис зображення

(Правий нижній 2 використовується для "захоплення" 3)

5. Тому що нам знадобився тестовий випадок з кількома четвереньками:

Одне рішення:


2
Було б корисно, якби існували версії ASCII тестових випадків, тому людям не потрібно вводити їх усі, а тестові випадки також повинні охоплювати 4s, якщо вони є дійсними вхідними даними.
Мартін Ендер

1
чи знаходяться ортогональні сусіди лише зліва направо вгору, або також діагоналі? якщо тільки ліворуч праворуч вниз, то як же 3 знаходиться в тому ж регіоні, що й два інших 3? один з них не є ортогональним сусідом.
Eyal Lev

@EyalLev Лише ліво-право-вгору-вниз. Правий верхній край 3 та його 2 сусіди складають регіон.
SuperJedi224

@ SuperJedi224 праворуч вгорі 3, і це два сусіди є дійсним регіоном, так, але ці сусіди цього не роблять. чи не повинен регіон бути "закритим набором"? тобто кожен член регіону повинен бути дійсним членом цього регіону?
Eyal Lev

Відповіді:


3

Я знаю, що цьому виклику більше року, але я просто знайшов це "без відповіді" і виглядав мені досить цікаво.

Якщо припустити, що номер "кореневої" комірки є єдиним значущим у кожному регіоні (виводиться з прикладів), ось моє зворотне рішення:

Пітон 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)

Спробуйте в Інтернеті!

Формат введення - це двовимірний список цілих чисел, пробіли як нуль, а вихідний формат також є двовимірним списком цілих чисел, що представляють одну область на число. Номер регіону починається з одиниці; нуль зарезервовано для порожніх комірок (як у вхідних даних). Якщо даний вхід є нерозв’язним, функція повертає один нуль (фальшиве значення).

Наприклад, тестовий випадок 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]]

Безголовка, з коментарями:

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)
 

Спробуйте в Інтернеті!

Примітка. Це особливий випадок комплектування упаковки, який, як відомо, є комплектним для NP. Ця конкретна проблема має обмежений розмір набору (макс. 4), і існують алгоритми наближення, щоб знайти "хороший" набір упаковки в поліноміальний час, але вони не гарантують максимально можливий набір упаковки (що в цій проблемі строго потрібно).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.