Étiqueter les impasses

16

Étant donné l'entrée d'une "route" de l'art ASCII, sortez la route avec toutes les impasses étiquetées.

Ceci est une route:

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

Voici la route avec des impasses marquées de la lettre X:

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

Une impasse est définie comme toute tuile de route qui borde n autres tuiles de route, dont au moins n-1 sont déjà considérées comme des impasses par cette règle. "Border" est dans les quatre directions cardinales, donc les tuiles bordant en diagonale ne comptent pas.

Cette règle est appliquée à plusieurs reprises, car les impasses nouvellement créées peuvent, elles-mêmes, créer plus d' impasses . Notez également que toute tuile de route qui borde une seule autre tuile de route est considérée comme une impasse la première fois que la règle est appliquée.

L'entrée et la sortie peuvent être soit une chaîne unique (avec des lignes séparées par un caractère différent de #ou .), soit un tableau / liste / etc. Si votre langue le prend en charge, vous pouvez également prendre des entrées, chaque ligne étant un argument de fonction.

Vous pouvez supposer ce qui suit à propos de l'entrée:

  • Il y aura toujours au moins une "boucle", c'est-à-dire un groupe de #caractères pouvant être suivis à l'infini. (Sinon, chaque tuile deviendrait une impasse.)

  • Cela implique que l'entrée sera toujours 2 × 2 ou plus, car la plus petite boucle est:

    ##
    ##
    

    (Qui, soit dit en passant, devrait être sorti sans changement.)

  • Tous les #personnages seront connectés. Autrement dit, si vous effectuiez un remplissage d'inondation sur l'un #d'entre eux, tous seraient affectés.

Puisqu'il s'agit de , le code le plus court en octets gagnera.

L'exemple ci-dessus et la minuscule grille 2 × 2 peuvent être utilisés comme cas de test (il n'y a pas beaucoup de cas de bord à couvrir dans ce défi).

Poignée de porte
la source

Réponses:

8

CJam, 61 octets

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

Essayez-le ici .

Explication

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 a économisé deux octets, merci!)

Lynn
la source
C'est l'une des réponses cjam les plus longues que j'aie jamais vues. =)
DJMcMayhem
2
@DJMcGoathem Ummm ...
Martin Ender
Sont '#et "#"différents dans CJam?
ETHproductions
Oui, ils le sont. "#"est égal à ['#].
Lynn
5

JavaScript (ES6), 110 109 octets

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 octet enregistré grâce à @ edc65 !

Explication

Approche très simple du problème. Recherche chacun #, et s'il y a moins de 2 #s autour, le remplace par un X. Répète ce processus plusieurs fois jusqu'à ce qu'il soit garanti que toutes les impasses ont été remplacées par l' Xart.

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>

user81655
la source
1
Astuce courante que j'utilise toujours pour ce type de tâche. Comme vous utilisez à la fois l et -l de la même manière, vous pouvez calculer à la l=~r.searchplace de l=1+r.search. (1 octet seulement enregistré)
edc65
@ edc65 Clever. Merci!
user81655
0

Python (3.5) 362 331 329 314 octets

merci à @Alissa. elle m'aide à gagner ~ 33 octets

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]))

Explications

d='.'
r=range

Définition de fonction

def f(s):

Ajoutez une bordure de '.' à droite et à gauche du plateau

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

Ajoutez une bordure de '.' en haut et en bas

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

Fonction lambda pour tester '#'

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

Boucle sur la longueur d'entrée pour être sûr de ne pas oublier les impasses

 for k in r(l*c):

Boucle sur colonnes et lignes

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

Testez si nous avons «#» autour et sur la position

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

Remplacez «#» par «X»

     t[h][x]='X'

Recadrez la bordure remplie de '.' et se joindre à la chaîne

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

Usage

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
Erwan
la source
1) utilisez split()au lieu de splitlines(). 2) t=['.'*(c+2)]+['.'+i+'.'for i in s]+['.'*(c+2)]est plus court. Et cela peut être raccourci encore plus: d='.';t=[d*c]+t+[d*c];t=[d+i+d for i in t]3) vous n'avez pas besoin de toute la liste (zip (....)), utilisezprint('\n'.join([''.join(i[1:-1])for i in t])
Alissa
@Alissa merci pour votre aide j'utilise vos conseils pour les points 1) et 3) mais pour le 2) je ne peux pas supprimer tous les crochets, nous avons besoin d'une liste de liste de char et non d'une liste de chaîne car 'str' object does not support item assignment. la liste de liste me permet d'utiliser t [h] [x] = 'X'
Erwan
désolé, j'ai raté le problème de l'immuabilité des cordes. Vous pouvez également déplacer toutes les constantes ( r, get d) hors de votre fonction (vous évite une tabulation). Peut-être que jouer avec split () pourrait aider:, t=[d+list(i)+d for i in s.split()]puis calculer les longueurs, puis ajouter des lignes de points à la fin et au début, puis modifier vos cycles pour travailler avec ces longueurs étendues. Je ne sais pas si cela raccourcira le code, mais cela pourrait
Alissa
@Alissa je ne peux pas déplacer le g hors de la fonction car il utilise t je vais tester votre autre commentaire
Erwan