Etichetta vicoli ciechi


16

Dato un input di una "strada" di arte ASCII, l'output della strada con tutti i vicoli ciechi etichettati.

Questa è una strada:

########.....######..#..###
#......#######....#..#..#.#
#.##......#...#####..#..###
#..#####..#....#..#######.#
#......#...#####.....##...#
#..###.#...#...###...#..###
##########.#..#..##..#.##.#
..#......#.######.#..#.#.#.
..#......#.#..#.#.#..#.#.#.
..######.###..##..#########

Questa è la strada con vicoli ciechi etichettati con la lettera X:

########.....######..X..###
#......#######....#..X..#.#
#.XX......X...X####..X..###
#..XXXXX..X....#..#######.#
#......X...#####.....##...#
#..###.X...#...###...#..###
##########.#..X..##..#.##.X
..X......#.#XXXXX.#..#.#.X.
..X......#.#..X.X.#..#.#.X.
..XXXXXX.###..XX..######XXX

Un vicolo cieco è definito come qualsiasi tessera stradale che confina con n altre tessere stradali, almeno n-1 sono considerate vicoli ciechi già da questa regola. "Bordatura" è nelle quattro direzioni cardinali, quindi le tessere che bordano in diagonale non contano.

Questa regola viene applicata ripetutamente, poiché i vicoli ciechi di nuova creazione possono, essi stessi, creare più vicoli ciechi . Si noti inoltre che ogni tessera stradale che delimita solo un'altra tessera stradale viene considerata un vicolo cieco la prima volta che viene applicata la regola.

L'input e l'output possono essere una singola stringa (con linee separate da qualsiasi carattere che non sia #o .) o un array / elenco / ecc. Se la tua lingua lo supporta, puoi anche prendere input con ogni riga come argomento di funzione.

Si può presumere quanto segue sull'input:

  • Ci sarà sempre almeno un "loop", ovvero un gruppo di #personaggi che possono essere seguiti all'infinito. (Altrimenti ogni singola tessera diventerebbe un vicolo cieco.)

  • Ciò implica che l'ingresso sarà sempre 2 × 2 o più grande, poiché il loop più piccolo è:

    ##
    ##
    

    (Che, per inciso, dovrebbe essere prodotto senza modifiche.)

  • Tutti i #personaggi saranno collegati. Cioè, se si eseguisse un riempimento di piena #, ne risentirebbero tutti.

Dato che si tratta di , vincerà il codice più breve in byte.

L'esempio sopra e la piccola griglia 2 × 2 possono essere usati come casi di test (non ci sono molti casi limite da affrontare in questa sfida).

Risposte:


8

CJam, 61 byte

q_N/{{0f+zW%}4*3ew:z3few::z{e__4=_@1>2%'#e=*"#"='X@?}f%}@,*N*

Provalo qui .

Spiegazione

Outline:

    q_N/               Read input lines
        {   }@,*       Perform some operation as many times as there are bytes
                N*     Join lines

Operation:

    {0f+zW%}4*         Box the maze with zeroes
    3ew:z3few::z       Mystical 4D array neighborhood magic.
                       (Think: a 2D array of little 3x3 neighborhood arrays.)

    {                        }f%    For each neighborhood, make a new char:
     e_                                 Flatten the neighborhood
       _4=_                             Get the center tile, C
           @1>2%                        Get the surrounding tiles
                '#e=                    Count surrounding roads, n
                    *                   Repeat char C n times
                     "#"=               Is it "#"? (i.e., C = '# and n = 1)
                         'X@?           Then this becomes an 'X, else keep C.

(Martin ha salvato due byte, grazie!)


Questa è una delle risposte di cjam più lunghe che abbia mai visto. =)
DJMcMayhem

2
@DJMcGoathem Ummm ...
Martin Ender,

Sono '#e "#"diversi in CJam?
ETHproductions

Sì, lo sono. "#"è uguale a ['#].
Lynn,

5

JavaScript (ES6), 110 109 byte

r=>[...r].map(_=>r=r.replace(g=/#/g,(_,i)=>(r[i+1]+r[i-1]+r[i+l]+r[i-l]).match(g)[1]||"X"),l=~r.search`
`)&&r

1 byte salvato grazie a @ edc65 !

Spiegazione

Approccio molto semplice al problema. Cerca ciascuno di essi #e, se ci sono meno di 2 #secondi, lo sostituisce con un X. Ripete questo processo più volte fino a quando non viene garantito che tutti i vicoli ciechi siano stati sostituiti con Xs.

var solution =

r=>
  [...r].map(_=>                    // repeat r.length times to guarantee completeness
    r=r.replace(g=/#/g,(_,i)=>      // search for each # at index i, update r once done
      (r[i+1]+r[i-1]+r[i+l]+r[i-l]) // create a string of each character adjacent to i
      .match(g)                     // get an array of all # matches in the string
        [1]                         // if element 1 is set, return # (the match is a #)
        ||"X"                       // else if element 1 is undefined, return X
    ),
    l=~r.search`
`                                   // l = line length
  )
  &&r                               // return the updated r
<textarea id="input" rows="10" cols="40">########.....######..#..###
#......#######....#..#..#.#
#.##......#...#####..#..###
#..#####..#....#..#######.#
#......#...#####.....##...#
#..###.#...#...###...#..###
##########.#..#..##..#.##.#
..#......#.######.#..#.#.#.
..#......#.#..#.#.#..#.#.#.
..######.###..##..#########</textarea><br>
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>


1
Trucco comune che uso sempre per questo tipo di attività. Mentre usi sia le che le allo stesso modo, puoi calcolare l=~r.searchinvece di l=1+r.search. (Solo 1 byte salvato)
edc65

@ edc65 Clever. Grazie!
user81655

0

Python (3.5) 362 331 329 314 byte

grazie a @Alissa. lei mi aiuta a vincere ~ 33 byte

d='.'
r=range
def f(s):
 t=[list(d+i+d)for i in s.split()]
 c=len(t[0])
 u=[[d]*c]
 t=u+t+u
 l=len(t)
 g=lambda h,x:t[h][x]=='#'
 for k in r(l*c):
  for h in r(1,l):
   for x in r(1,c):
    if g(h,x) and g(h+1,x)+g(h-1,x)+g(h,x+1)+g(h,x-1)<2:
     t[h][x]='X'
 print('\n'.join([''.join(i[1:-1])for i in t][1:-1]))

spiegazioni

d='.'
r=range

Definizione della funzione

def f(s):

Aggiungi un bordo di "." a destra e a sinistra del tabellone

 t=[list(d+i+d)for i in s.split()]
 c=len(t[0])
 u=[[d]*c]

Aggiungi un bordo di "." in alto e in basso

 t=u+t+u
 l=len(t)

Funzione lambda per testare '#'

 g=lambda h,x:t[h][x]=='#'

Eseguire il ciclo sulla lunghezza di input per essere sicuri di non dimenticare i vicoli ciechi

 for k in r(l*c):

Passa su colonne e linee

  for h in r(1,l):
   for x in r(1,c):

Verifica se abbiamo '#' intorno e sulla posizione

    if g(h,x) and g(h+1,x)+g(h-1,x)+g(h,x+1)+g(h,x-1)<2:

Sostituisci '#' con 'X'

     t[h][x]='X'

Ritaglia il bordo pieno di "." e unisciti in stringa

 print('\n'.join([''.join(i[1:-1])for i in t][1:-1]))

uso

f("########.....######..#..###\n#......#######....#..#..#.#\n#.##......#...#####..#..###\n#..#####..#....#..#######.#\n#......#...#####.....##...#\n#..###.#...#...###...#..###\n##########.#..#..##..#.##.#\n..#......#.######.#..#.#.#.\n..#......#.#..#.#.#..#.#.#.\n..######.###..##..#########")

########.....######..X..###
#......#######....#..X..#.#
#.XX......X...X####..X..###
#..XXXXX..X....#..#######.#
#......X...#####.....##...#
#..###.X...#...###...#..###
##########.#..X..##..#.##.X
..X......#.#XXXXX.#..#.#.X.
..X......#.#..X.X.#..#.#.X.
..XXXXXX.###..XX..######XXX

1) utilizzare split()invece di splitlines(). 2) t=['.'*(c+2)]+['.'+i+'.'for i in s]+['.'*(c+2)]è più corto. E può essere abbreviato ancora di più: d='.';t=[d*c]+t+[d*c];t=[d+i+d for i in t]3) non hai bisogno di tutto l'elenco (zip (....)) cosa, usaprint('\n'.join([''.join(i[1:-1])for i in t])
Alissa

@Alissa, grazie per il tuo aiuto, utilizzo i suggerimenti per i punti 1) e 3) ma per il 2) non riesco a rimuovere tutte le parentesi, abbiamo bisogno di un elenco di elenchi di caratteri e non di un elenco di stringhe perché 'str' object does not support item assignment. l'elenco dell'elenco mi consente di utilizzare t [h] [x] = 'X'
Erwan,

scusa, mi sono perso la cosa dell'immutabilità delle stringhe. È inoltre possibile spostare tutte le costanti ( r, ge d) dalla vostra funzione (consente di risparmiare un po 'di tabulazione). Forse alcuni giochi intorno a split () potrebbero aiutare:, t=[d+list(i)+d for i in s.split()]quindi calcolare le lunghezze, quindi aggiungere linee di punti alla fine e all'inizio, quindi modificare i cicli per lavorare con queste lunghezze estese. Non sono sicuro se accorcerà il codice, ma potrebbe
Alissa,

@Alissa non riesco a spostare g dalla funzione perché usa t testerò l'altro tuo commento
Erwan,
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.