Quanto lontano dall'esterno?


15

Prendi una regione 2D di spazio divisa in elementi quadrati di unità allineati ad asse con i loro centri allineati ad intervalli interi. Si dice che un bordo è interno se è condiviso da due elementi, altrimenti è un bordo esterno.

Il tuo obiettivo è trovare il numero minimo di elementi vicini che devono essere attraversati per raggiungere un bordo esterno a partire dal centro di ciascun elemento, noto come traversal distance, o distancein breve. Puoi attraversare solo un bordo (cioè nessun taglio dell'angolo / movimento diagonale). Si noti che gli "elementi esterni" (elementi che hanno almeno un bordo esterno) sono considerati necessari per attraversare gli 0elementi vicini per raggiungere un bordo esterno.

Ingresso

L'input è un elenco di coordinate di coppie intere non negative che indicano la (x, y) del centro di tutti gli elementi. Si presume che non vi siano elementi sovrapposti (ovvero una coppia x / y identifica in modo univoco un elemento). Si può non assumere nulla circa l'ordine di ingresso elemento.

Siete invitati a trasformare l'origine dell'input in qualsiasi posizione (ad esempio 0,0 o 1,1, ecc.).

Si può presumere che tutti gli elementi di input siano collegati o, in altre parole, è possibile viaggiare da un elemento qualsiasi a qualsiasi altro elemento utilizzando le regole sopra. Si noti che ciò non significa che la regione 2D sia semplicemente connessa; potrebbe avere dei buchi all'interno.

Esempio: quanto segue è un input non valido.

0,0
2,0

inserisci qui la descrizione dell'immagine

non è richiesto il controllo degli errori.

L'input può provenire da qualsiasi sorgente (file, stdio, parametro della funzione, ecc.)

Produzione

L'output dovrebbe essere un elenco di coordinate che identificano ciascun elemento e la distanza intera corrispondente percorsa per arrivare a un bordo. L'output può essere nell'ordine degli elementi desiderato (ad es. Non è necessario che gli output siano nello stesso ordine ricevuto come input).

L'output può essere su qualsiasi sorgente (file, stdio, valore di ritorno della funzione, ecc.)

Qualsiasi output che corrisponde alla coordinata dell'elemento con la sua distanza esterna va bene, ad es. Tutti questi vanno bene:

x,y: distance
...

[((x,y), distance), ...]

[(x,y,distance), ...]

Esempi

Gli input di esempio di testo sono nella forma x,y, con un elemento per riga; sei libero di ridisegnarlo in un comodo formato di input (vedi regole del formato di input).

Gli output di esempio di testo sono nel formato x,y: distance, con un elemento per riga; di nuovo, puoi rimodellarlo in un comodo formato di output (vedi regole del formato di output).

Le figure grafiche hanno il limite inferiore sinistro come (0,0) e i numeri all'interno rappresentano la distanza minima prevista percorsa per raggiungere un bordo esterno. Si noti che queste cifre sono puramente a scopo dimostrativo; il tuo programma non ha bisogno di emetterli.

Esempio 1

ingresso:

1,0
3,0
0,1
1,2
1,1
2,1
4,3
3,1
2,2
2,3
3,2
3,3

Produzione:

1,0: 0
3,0: 0
0,1: 0
1,2: 0
1,1: 1
2,1: 0
4,3: 0
3,1: 0
2,2: 1
2,3: 0
3,2: 0
3,3: 0

rappresentazione grafica:

inserisci qui la descrizione dell'immagine

Esempio 2

ingresso:

4,0
1,1
3,1
4,1
5,1
6,1
0,2
1,2
2,2
3,2
4,2
5,2
6,2
7,2
1,3
2,3
3,3
4,3
5,3
6,3
7,3
8,3
2,4
3,4
4,4
5,4
6,4
3,5
4,5
5,5

produzione:

4,0: 0
1,1: 0
3,1: 0
4,1: 1
5,1: 0
6,1: 0
0,2: 0
1,2: 1
2,2: 0
3,2: 1
4,2: 2
5,2: 1
6,2: 1
7,2: 0
1,3: 0
2,3: 1
3,3: 2
4,3: 2
5,3: 2
6,3: 1
7,3: 0
8,3: 0
2,4: 0
3,4: 1
4,4: 1
5,4: 1
6,4: 0
3,5: 0
4,5: 0
5,5: 0

rappresentazione grafica:

inserisci qui la descrizione dell'immagine

Esempio 3

ingresso:

4,0
4,1
1,2
3,2
4,2
5,2
6,2
8,2
0,3
1,3
2,3
3,3
4,3
5,3
6,3
7,3
8,3
9,3
1,4
2,4
3,4
4,4
5,4
6,4
7,4
8,4
9,4
2,5
3,5
4,5
5,5
6,5
9,5
10,5
11,5
3,6
4,6
5,6
9,6
10,6
11,6
6,7
7,7
8,7
9,7
10,7
11,7

produzione:

4,0: 0
4,1: 0
1,2: 0
3,2: 0
4,2: 1
5,2: 0
6,2: 0
8,2: 0
0,3: 0
1,3: 1
2,3: 0
3,3: 1
4,3: 2
5,3: 1
6,3: 1
7,3: 0
8,3: 1
9,3: 0
1,4: 0
2,4: 1
3,4: 2
4,4: 2
5,4: 2
6,4: 1
7,4: 0
8,4: 0
9,4: 0
2,5: 0
3,5: 1
4,5: 1
5,5: 1
6,5: 0
9,5: 0
10,5: 0
11,5: 0
3,6: 0
4,6: 0
5,6: 0
9,6: 0
10,6: 1
11,6: 0
6,7: 0
7,7: 0
8,7: 0
9,7: 0
10,7: 0
11,7: 0

rappresentazione grafica:

inserisci qui la descrizione dell'immagine

punteggio

Questo è il codice golf. Vince il codice più breve in byte. Si applicano scappatoie standard. Sono consentiti qualsiasi componente aggiuntivo diverso da quelli specificamente progettati per risolvere questo problema.


Possiamo produrre come [((1,0), 0), ...]?
Lirtosiast

@lirtosiast yes
helloworld922

1
Nei tuoi esempi, non dichiari esplicitamente gli input.
Dale Johnson,

@DaleJohnson prende solo le prime due colonne di ciascun input di testo per le coppie x, y. Non ho aggiunto una casella di citazione separata solo per gli input poiché sembrava essere un po 'lungo. C'è un modo per aggiungere una casella di preventivo e limitarne manualmente l'altezza verticale?
helloworld922,

trovare il numero minimo di elementi vicini che devono essere attraversati per raggiungere un bordo esterno Partendo da dove? E puoi aggiungere l'output nei test ces?
Luis Mendo,

Risposte:


2

MATLAB / Octave, 143 byte

function [v,x,y]=d(x,y)R=S=zeros(max(y+3),max(x+3));i=sub2ind(size(S),y+2,x+2);S(i)=1;while nnz(S=imerode(S,strel('disk',1,0)))R+=S;end;v=R(i);

Ungolfed

function [v,x,y]=d(x,y)
  R=S=zeros(max(y+3),max(x+3));
  i=sub2ind(size(S),y+2,x+2);
  S(i)=1;
  while nnz(S=imerode(S,strel('disk',1,0)))
    R+=S;
  end;
  v=R(i);

Spiegazione

Crea matrici S ource e R esult delle dimensioni appropriate, piene di zeri.

R=S=zeros(max(y+3),max(x+3));

Calcola gli indici lineari che corrispondono alle xycoppie, con un elemento di riempimento ai bordi.

i=sub2ind(size(S),y+2,x+2);

Disegna la struttura.

S(i)=1;

Sè mostrato qui per l' esempio 2 :

0   0   0   0   0   0   0   0   0   0   0
0   0   0   0   0   1   0   0   0   0   0
0   0   1   0   1   1   1   1   0   0   0
0   1   1   1   1   1   1   1   1   0   0
0   0   1   1   1   1   1   1   1   1   0
0   0   0   1   1   1   1   1   0   0   0
0   0   0   0   1   1   1   0   0   0   0
0   0   0   0   0   0   0   0   0   0   0

Rimuovere tutti gli elementi del bordo per erosione dell'immagine

S=imerode(S,strel('disk',1,0))

usando il disco dell'elemento strutturante con raggio 1 :

0   1   0
1   1   1
0   1   0

Se fosse consentito il movimento diagonale, utilizzeremmo invece il rettangolo:

1   1   1
1   1   1
1   1   1

Quindi, incrementare il risultato per tutti gli elementi non di confine

R+=S;

e ciclo fino a quando l'immagine è completamente erosa.

while nnz(S)

Restituisce il risultato per ogni xycoppia.

v=R(i);

2

Pyth, 26 byte

V]MQNf>*4Nl=Nsmfq1.a,dYQN0

Esempio 2

Il formato di output che ho usato è:

[[4, 3]]
2

Cioè, un elenco contenente il punto, seguito dalla distanza dall'esterno.

Il codice funziona utilizzando un set attualmente raggiunto, per ogni punto che filtra l'input per tutti i punti esattamente a 1 distanza da quel punto e controllando se il numero risultante di punti è 4 volte il numero iniziale e ripetendo fino a quando non lo è . Quando viene avviato in un determinato punto, ciò indica quanto è lontano quel punto dall'esterno.


2

MATL , 38 37 36 33 byte

1Z?t"tX@<~5Bt!Z~2X53$Y+4=+]3#fqhh

Questo utilizza la versione corrente (15.0.0) del linguaggio / compilatore.

Il formato di input è: un array con valori x e un array con valori y . Input e output sono basati su 1. Quindi i casi di test hanno i seguenti input:

[2 4 1 2 2 3 5 4 3 3 4 4]
[1 1 2 3 2 2 4 2 3 4 3 4]

[5 2 4 5 6 7 1 2 3 4 5 6 7 8 2 3 4 5 6 7 8 9 3 4 5 6 7 4 5 6]
[1 2 2 2 2 2 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 5 5 5 5 5 6 6 6]

[5 5 2 4 5 6 7 9 1 2 3 4 5 6 7 8 9 10 2 3 4 5 6 7 8 9 10 3 4 5 6 7 10 11 12 4 5 6 10 11 12 7 8 9 10 11 12]
[1 2 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8]

Provalo online!

Spiegazione

Inizialmente viene creata una matrice con 1 nelle posizioni di input e 0 altrimenti. Quindi viene applicata una convoluzione con una maschera "Nord, Est, Sud, Ovest" ( [0 1 0; 1 0 1; 0 1 0]), e il risultato in ciascuna posizione viene confrontato con 4. Un risultato di 4 significa che quella posizione è circondata da altri punti, e quindi ha la distanza- all'esterno almeno 1. Il risultato (0 o 1 per ciascun punto) viene aggiunto alla matrice originale. Tali posizioni ora contengono 2 (al termine del processo la matrice verrà decrementata di 1).

Il processo di convoluzione è iterato. Per la successiva iterazione, l'input della convoluzione è la matrice accumulata con soglia 2; cioè, i valori inferiori a 2 sono impostati su 0. Il risultato della convoluzione indica quali punti hanno una distanza di almeno 2 (tutti i loro vicini hanno distanza 1).

Il numero di iterazioni viene scelto, per comodità, come numero di colonne della matrice di input. Questo è sufficiente (in effetti, il numero massimo richiesto di iterazioni è la metà della dimensione minima della matrice). Le ultime iterazioni possono essere inutili, ma non fanno male (aggiungono semplicemente 0 a tutti i punti).

Alla fine del processo, 1 viene sottratto dal risultato, poiché le posizioni con valore k hanno una distanza k -1 dall'esterno. Le coordinate e i valori di tutte le posizioni vengono estratti e visualizzati.

           % take x and y implicitly
1          % push 1
Z?         % build sparse matrix from that x, y indices with 1 as value
t          % duplicate
"          % for each column of that matrix
  t        %   duplicate
  X@       %   push iteration index
  <~       %   true for matrix entries that are >= iteration index
  5B       %   5 in binary: row vector [1 0 1]
  t!       %   duplicate and transpose into a column vector
  Z~       %   element-wise XOR with broadcast: gives desired mask,
           %   [0 1 0; 1 0 1; 0 1 0]
  2X53$Y+  %   2D convolution. Output has same size as input
  4=       %   compare with 4: are all neighbouring positions occupied?
  +        %   add to accumulated matrix from previous iteration
]          % end for each
3#f        % extract row index, column index and value for nonzero
           % entries. In this case all entries are nonzero
q          % subtract 1 to value to yield distance to exterior
hh         % concatenate vertically twice
           % display implicitly 

1

Python 3, 180 166 160 byte

def f(l,d=0):
 l=set(l);
 if l:i={(a,b)for a,b in l if all([x in l for x in[(a+1,b),(a-1,b),(a,b+1),(a,b-1)]])};return{(c,d)for c in l-i}|f(i,d+1)
 return set()

Sappiamo che se una coordinata ha meno di quattro vicini, deve trovarsi sull'esterno. Pertanto, possiamo più volte eliminare le celle esterne e assegnare loro una distanza uguale al numero di iterazioni / profondità di ricorsione in questo caso.

Sicuramente pensi che ci siano margini di miglioramento: qual è il modo migliore per controllare i vicini adiacenti?

modifica: dovrei essere autorizzato ad accettare un elenco di coppie come tuple.


0

PHP, 316 byte

<?preg_match_all("#^(\d+),(\d+)#m",$_GET[i],$t);foreach($t[1]as$k=>$v)$a[$v][$t[2][$k]]=0;function w($x,$y){global$a;return isset($a[$x][$y])?$a[$x][$y]:-1;};for(;$z++<max($t[2]);$o=$s,$s="")foreach($a as$x=>$b)foreach($b as$y=>$c)$s.="\n$x,$y: ".$a[$x][$y]=1+min(w($x+1,$y),w($x-1,$y),w($x,$y-1),w($x,$y+1));echo$o;

Versione online

Abbattersi

preg_match_all("#^(\d+),(\d+)#m",$_GET[i],$t); 
foreach($t[1]as$k=>$v) 
$a[$v][$t[2][$k]]=0;  # make a 2 D array
function w($x,$y){global$a;return isset($a[$x][$y])?$a[$x][$y]:-1;};# check the neighbours
for(;$z++<max($t[2]);$o=$s,$s="") # stored the last loop string first run make possible to 1 and so on
foreach($a as$x=>$b) # x values
foreach($b as$y=>$c) # y values
$s.="\n$x,$y: ".$a[$x][$y]=1+min(w($x+1,$y),w($x-1,$y),w($x,$y-1),w($x,$y+1)); # concanate array item x+y+value
echo$o; #Output

Visualizza come caratteri Ascii

ksort($a); 
foreach($a as$x=>$b){
for($y=0;$y<=max($t[2]);$y++)
echo isset($a[$x][$y])?$a[$x][$y]:" ";
#The better way would be make a SVG and use the text element and use a factor
#echo '<text x="'.($x*$factor).'" y="'.($y*$factor).'">'.$a[$x][$y].'</text>';
echo"\n";}
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.