Raggruppa queste celle!


12

Questa sfida si basa sul gioco Layerz.

Dato, su stdin o come argomento di funzione, una matrice rettangolare di celle 2D in cui ogni cella contiene uno spazio vuoto (puoi scegliere di usare 0s invece di spazi vuoti senza penalità), un 1, un 2, un 3 o un 4 ; trovare un modo per dividerlo in regioni valide (come definito di seguito) in modo tale che ogni cella non vuota sia contenuta esattamente da una regione. Quindi, genera la soluzione trovata in qualsiasi formato ragionevole. Se non esiste una soluzione, arrestare senza produrre output o emettere un singolo valore di falso, quindi arrestare.

Una delle seguenti costituisce una regione valida:

  • Una singola cella contenente un 1
  • Una cellula contenente un 2 ed esattamente uno dei suoi vicini ortogonali non vuoti
  • Una cellula contenente un 3 ed esattamente due dei suoi vicini ortogonali non vuoti
  • Una cellula contenente un 4 ed esattamente tre dei suoi vicini ortogonali non vuoti

Questo è , quindi vince la risposta valida più breve, in byte.

Alcuni casi di test:

1. Uno piuttosto banale:

inserisci qui la descrizione dell'immagine

E questa è la soluzione, con ogni regione di un colore diverso:

inserisci qui la descrizione dell'immagine

2. Uno più interessante

inserisci qui la descrizione dell'immagine

Questo ha più di una soluzione, ma eccone una:

inserisci qui la descrizione dell'immagine

3. Uno più piccolo, contenente spazi vuoti, che non ha alcuna soluzione (a seconda che tu usi uno dei due per "catturare" i tre, o i tre per prendere due dei due, o sei lasciato con un coppia di due non adiacenti [e quindi non raggruppabili] o uno solo due):

inserisci qui la descrizione dell'immagine

Poiché questa griglia non ha soluzioni, il programma dovrebbe arrestarsi senza produrre alcun output quando viene fornita questa griglia.

4. Questo (con i primi 2 spostati di una cella a sinistra) ha una soluzione però:

inserisci qui la descrizione dell'immagine

Soluzione:

inserisci qui la descrizione dell'immagine

(In basso a destra 2 viene utilizzato per "catturare" il 3)

5. Perché avevamo bisogno di un caso di test con alcuni fours:

Una soluzione:


2
Sarebbe utile se esistessero versioni ASCII dei casi di test in modo che le persone non debbano scriverli tutti insieme, e i casi di test dovrebbero anche coprire 4s se quelli sono input validi.
Martin Ender,

1
vicini ortogonali significa solo a sinistra in alto, o anche le diagonali? se lasciato solo verso il basso, come mai il 3 è nella stessa regione degli altri due 3? uno di loro non è un vicino ortogonale.
Eyal Lev,

@EyalLev Solo sinistra-destra-su-giù. In alto a destra 3 e i suoi 2 vicini costituiscono la regione.
SuperJedi224,

@ SuperJedi224 in alto a destra 3 ed i suoi due vicini costituiscono una regione valida, sì, ma quei vicini no. una regione non deve essere un "insieme chiuso"? cioè ogni membro della regione deve essere un membro valido di quella regione?
Eyal Lev,

Risposte:


3

So che questa sfida ha più di un anno, ma l'ho appena trovata in "senza risposta" e mi è sembrata abbastanza interessante.

Supponendo che il numero della cella "radice" sia l'unico significativo in ciascuna regione (deducibile dagli esempi), ecco la mia soluzione di backtracking:

Python 3 , 355 351 349 byte

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)

Provalo online!

Il formato di input è un elenco 2D di numeri interi, spazi vuoti come zero, e il formato di output è anche un elenco 2D di numeri interi che rappresentano una regione per numero. Il numero di regione inizia da uno; zero è riservato per celle vuote (come in input). Se l'ingresso specificato è irrisolvibile, la funzione restituisce zero singolo (valore errato).

Ad esempio, il caso di test 5 viene inserito come

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

e l'output è

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

Ungolfed, con commenti:

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)
 

Provalo online!

Nota: questo è un caso speciale di Set Packing che è noto per essere NP-completo. Questo problema specifico ha dimensioni del set limitate (max. 4) e esistono algoritmi di approssimazione per trovare un set di imballaggio "buono" in tempi polinomiali, ma non garantiscono il massimo set di pacchetti possibile (cosa strettamente richiesta in questo problema).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.