Génération de labyrinthes d'images

20

Défi

Écrivez un programme / une fonction qui accepte une "image" et génère un labyrinthe d'images formé à partir de cette image.

Contribution

Votre programme doit accepter deux arguments:

  • Moi, l'image pour former le labyrinthe
  • S, un booléen précisant s'il faut afficher ou non la solution du labyrinthe

I est donné sous la forme suivante:

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

#sont les cellules à inclure dans le chemin de la solution et .les cellules à exclure. Vous pouvez échanger les .«, #» et les nouvelles lignes avec n'importe quel caractère de votre choix tant qu'ils diffèrent les uns des autres. Alternativement, vous pouvez accepter un bitmap réel de l'image d'entrée.

Production

Votre labyrinthe résultant devrait être sous la forme suivante:

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

#représente les murs, .désigne les portions du chemin faisant partie de la solution et les espaces sont des chemins exclus de la solution. Les .'peuvent être remplacés par des espaces si S est faux. Encore une fois, les caractères peuvent être échangés avec d'autres caractères de votre choix ou vous pouvez générer une image bitmap réelle du labyrinthe avec la solution mise en évidence.

Détails supplémentaires

  • Les chemins doivent être d'une seule cellule (ne peut pas avoir un pool géant d'espace vide comme chemin)
  • Le labyrinthe ne doit contenir aucune boucle
  • Le labyrinthe doit être entièrement connecté (toutes les cellules doivent être accessibles depuis l'entrée / la sortie)
  • Le labyrinthe doit être entouré de murs (sauf s'il s'agit d'une entrée / sortie)
  • Le chemin de la solution ne doit pas inclure d'impasses
  • Il doit y avoir exactement 1 entrée et 1 sortie pour le labyrinthe
  • L'entrée et la sortie doivent être alignées sur le bord de la grille et adjacentes à une cellule incluse dans le chemin de la solution
  • Vous pouvez choisir l'emplacement de l'entrée et de la sortie
  • Vous pouvez supposer qu'un chemin valide peut être formé à partir de l'image d'entrée donnée

(Ajouté pour clarification) Le diagramme ci-dessous montre comment le chemin de la solution est corrélé à l'image d'entrée:

Input (I): |    Output:            |    Corresponding Cells: 
           |                       |    (@'s denote #'s from I)
           |                       |
.......    |    ###############    |    ###############
.#####.    |    #             #    |    #             #
.#####.    |    # ### ####### #    |    # ### ####### #
#######    |    # #.........# #    |    # #@.@.@.@.@# #
.#####.    |    # #.#######.# #    |    # #.#######.# #
.#####.    |    # #.#.......# #    |    # #@#@.@.@.@# #
.......    |    ###.#.#########    |    ###.#.#########
           |    ....#.#........    |    .@.@#@#@.@.@.@.
           |    #####.#.#######    |    #####.#.#######
           |    #  ...#.....  #    |    #  @.@#@.@.@  #
           |    # #.#######.# #    |    # #.#######.# #
           |    # #.........# #    |    # #@.@.@.@.@# #
           |    # ####### ### #    |    # ####### ### #
           |    #   #       # #    |    #   #       # #
           |    ###############    |    ###############
           |                       |

Cas de test

L'arrosage peut par exemple de Wikipedia :

Contribution:

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

Sortie (S = faux):

#####################################
#   #     #   #   #     #           #
# ### ### ### # # ##### ### ### ### #
#     # #   # # #         # #   # # #
# ### # ##### # ########### # ### # #
# # #         #           # # #   # #
# # # ### ##### # ### ### # ### ### #
#   # # #   #   # # #   # #   # #   #
# ### # ##### ##### ### ##### # # ###
# #   #       #   #   #       # # #  
### ####### ### ### # ### ##### ### #
#   #     # #   #   #   # #   # #   #
# ### ##### # ### ####### # # # # # #
# #       #             #   # #   # #
# # ##### ############# ### ### ### #
#   #   #       #     #   # #   # # #
# ### # ####### # ### ### # # ### # #
# # # #         #   # #   #   #     #
# # # ### ######### # # ##### # #####
# #   # # #       # #   #   # # #   #
# ##### # # ##### # ##### # # ### # #
#       # #   #   # #     # #   # # #
# ### ### ### # ### # ##### ####### #
#   # # #     # #   # #       #     #
# # # # ####### # ### # ##### # ### #
  # # # #   #   #     #     # #   # #
### # # # # # ############# # ### # #
#   # # # #   #         #   # #   # #
##### # # ##### ####### # ### ##### #
#     # # #   #       # #   #       #
##### # # # # ####### # ### #########
#     #     #         #       #     #
# ### ######### ############# # #####
# # #   #     # #       #     #     #
# # ######### # ####### ####### ### #
#             #                 #   #
#####################################

Sortie (S = vrai):

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

Exemple de bitmap (même labyrinthe que ci-dessus):

Entrée: Bitmap d'entréeSortie (S = faux): Solution bitmap de sortie non mise en évidenceSortie (S = vrai):Solution de bitmap de sortie mise en évidence

Dendrobium
la source
4
C'est peut-être juste moi, mais je ne vois pas l'image d'entrée dans le labyrinthe de sortie.
Mike Bufardeci
@ mike-bufardeci Ajout d'un diagramme montrant l'image d'entrée dans le labyrinthe de sortie. J'espère que cela pourra aider!
Dendrobium
2
Il ne semble pas y avoir de règle exigeant que le labyrinthe soit connecté. Serait-ce une solution valable? Il ne semble pas non plus y avoir de règle selon laquelle la grille doit être entourée de murs (à moins que chaque non-mur soit considéré comme une entrée ou une sortie). Serait-ce une solution valable?
Martin Ender
1
Veuillez également ajouter quelques cas de test supplémentaires.
flawr
@ MartinBüttner Le labyrinthe doit être entièrement connecté et entouré de murs, a édité la question en clarifiant ces points.
Dendrobium

Réponses:

10

Python 3, 1599 octets

J'ai trouvé que c'était un projet amusant et très intéressant (et quelque peu long). Quand j'ai vu cela, je me suis souvenu de l'été que j'ai passé exclusivement à écrire et à améliorer un algorithme de génération de labyrinthe et à me mettre immédiatement au travail.

Après un certain temps, j'ai eu un brouillon initial d'environ 6000 octets et j'ai passé les deux heures suivantes à le condenser dans le programme suivant:

import math,random;R=range;L=len;T=sorted;P=print;N=random.randint
def M(I,S):
 I=I.rsplit('\n');s=[0]*(1+L(I[0])*2);G=[s]
 for i in R(L(I)):
  r=[0]
  for x in I[i]:r+=x,0
  G+=[r];s=[0]*(1+L(I[0])*2);G+=[s]
 c=E(G,L(G[0])-2,-2);G[c][L(G[0])-1]=1;e=[c,L(G[0])-2];c=E(G,1,2);G[c][0]=1;G[c][1]=1;s=[c,1]
 while s!=e:
  o=[];Q(G,s,e,-2,0,o,0);Q(G,s,e,0,2,o,1);Q(G,s,e,2,0,o,2);Q(G,s,e,0,-2,o,3);o=T(o,key=lambda x:(x[2],-x[1]))[0][0]
  if o==0:G[s[0]-1][s[1]]=1;s[0]-=2
  elif o==1:G[s[0]][s[1]+1]=1;s[1]+=2
  elif o==2:G[s[0]+1][s[1]]=1;s[0]+=2
  else:G[s[0]][s[1]-1]=1;s[1]-=2
  G[s[0]][s[1]]=1
 s=0
 while not s:
  r=N(1,(L(G)-1)/2)*2-1;c=N(1,(L(G[0])-1)/2)*2-1
  if G[r][c]in[1,2]:
   o=[];F(G,r-2,c,o,0);F(G,r,c+2,o,1);F(G,r+2,c,o,2);F(G,r,c-2,o,3)
   try:
    if o[0]==0:G[r-1][c]=2;G[r-2][c]=2
    elif o[0]==1:G[r][c+1]=2;G[r][c+2]=2
    elif o[0]==2:G[r+1][c]=2;G[r+2][c]=2
    else:G[r][c-1]=2;G[r][c-2]=2
   except:0
  s=1
  for x in G:
   if'.'in x:s=0;break
 *s,='#  '
 if S:s[1]='.'
 for x in G:
  for y in x:P(s[y],end='')
  P()
def Q(G,s,e,x,y,o,a,n=0):
 c=lambda x,y:G[s[0]+x][s[1]+y]is'#'
 try:
  if c(x,y):
   try:n+=c(2*x,2*y)
   except:0
   try:n+=c(x+abs(x)-2,y+abs(y)-2)
   except:0
   try:n+=c(x-abs(x)+2,y-abs(y)+2)
   except:0
   o+=[[a,math.sqrt((s[0]+x-e[0])**2+(s[1]+y-e[1])**2),n]]
 except:0
def F(G,r,c,o,a):
 try:
  if G[r][c] is'.':o+=[a]
 except:0
def E(G,y,z,d='#'):
 c=[]
 for x in R(1,L(G)-1,2):
  n=0
  try:n+=G[x-2][y]==d
  except:0
  try:n+=G[x+2][y]==d
  except:0
  n+=G[x][y+z]==d
  if G[x][y]==d:c+=[[x,n]]
 if L(c)>1:c=T(c,key=lambda x:x[1])
 return c[0][0]

Ce qui est à peu près aussi insensé à regarder qu'un labyrinthe d'art ascii est ...

Il convient de noter que, puisque la fonction aléatoire n'est utilisée qu'après avoir trouvé le chemin correct, quel que soit le nombre de fois où la même entrée est donnée, l'itinéraire du début à la fin sera le même et, bien que ce programme le fasse travailler pour les exemples ci-dessus, parfois il ne sera pas en mesure de trouver une solution s'il "se conduit dans un mur" pour ainsi dire.

Lors de l'exécution des exemples ci-dessus, cela donne ceci:

>>> M('''.......
.#####.
.#####.
#######
.#####.
.#####.
.......''',True)
###############
# # #   # #   #
# # # ### # # #
# #...#.....# #
# #.#.#.###.###
#  .#.#.#...# #
###.#.#.#.### #
....#.#.#.#....
# ###.#.#.#.###
# #...#.#.#.  #
# #.###.#.#.# #
# #.....#...# #
### ####### # #
#         # # #
###############
>>> 

cette:

>>> M('''..................
..................
.......####.......
......##..##......
.....##....##....#
.....#......#...##
.#############.##.
##..############..
#...###########...
#...##########....
#...##########....
#...##########....
#...##########....
....##########....
....##########....
....##########....
..................
..................''',False)
#####################################
# #     #   # # #   # #   # # # # # #
# ### ##### # # # ### # ### # # # # #
#   # # #   #   # # # #   # # #   # #
### # # ### # ### # # # ### # ### # #
# #     #   # #         # # # # # # #
# ### ##### # # ##### ### # # # # # #
# # #   #   #     # #   # # # # # # #
# # # ##### # ##### ### # # # # # # #
# # # #         # # #         #      
# # # # # # ##### # ### # ######### #
# #   # # # #   # # # # # # # # #   #
# # ####### # ### # # ### # # # # # #
#         # #           #   #     # #
### ##### # # ######### ### ### ### #
#     #   # # #   #   #     #   # # #
# ### ### # # # # # # ####### ### # #
#   # #   # # # # # # #   #       # #
# ##### # # # # # # # # # # # ##### #
#   #   # # # # # # # # #   #     # #
# ####### # # # # # # # #############
#   #     # # # # # # #         #   #
# ####### # # # # # # ##### ##### # #
#   #     # # # # # #           # # #
# ### ### # # # # # ######### ### ###
    # #   # # # # #         #   #   #
# ### # # # # # # ######### ##### ###
#   # # # # # # #                 # #
# # # ### # # # ################### #
# # # # # # # #               #     #
# ### # # # # ############# ### ### #
# # # #     #                     # #
# # ##### # # # ##### # # ##### ### #
# # #     # # #     # # #     #   # #
### ##### # ### # # # ##### # ### # #
#         #   # # # #     # #   # # #
#####################################
>>> 

et ça:

>>> M('''..................
..................
.......####.......
......##..##......
.....##....##....#
.....#......#...##
.#############.##.
##..############..
#...###########...
#...##########....
#...##########....
#...##########....
#...##########....
....##########....
....##########....
....##########....
..................
..................''',True)
#####################################
#     #     # #   # # # # # # #     #
##### # # ### ### # # # # # # ### # #
# # # # # # # #     # # # # # # # # #
# # # ### # # ##### # # # # # # # ###
#   # #   # # #.......# #     #   # #
### # ### # # #.#####.# # ####### # #
#   # #   # #...#   #...#   # #   # #
### # ### # #.# # ### #.# ### ### # #
# # # # # #...# #   # #...  # #   #..
# # # # # #.# ### #######.### ### #.#
# #     #  .# #   # # #  .    # #...#
# # #######.##### # # ###.##### #.# #
#  .......#.#...........#...# #...# #
###.# ###.#.#.#########.###.# #.### #
#...# #  .#.#.#...#...#.....#...  # #
#.#######.#.#.#.#.#.#.#######.#######
#.    #  .#.#.#.#.#.#.#...#...#     #
#.#######.#.#.#.#.#.#.#.#.#.### #####
#.    #  .#.#.#.#.#.#.#.#...        #
#.#######.#.#.#.#.#.#.#.#############
#.    # #.#.#.#.#.#.#.#.....        #
#.##### #.#.#.#.#.#.#.#####.#########
#.  #    .#.#.#.#.#.#.......  # #   #
#.# # ###.#.#.#.#.#.########### # ###
..# # #  .#.#.#.#.#.........#   # # #
# # #####.#.#.#.#.#########.# ### # #
# # #    .#.#.#.#...........        #
#########.#.#.#.############### #####
#   #    .#.#.#.............# #     #
### # ###.#.#.#############.# ##### #
#     #  ...#...............      # #
##### # # ### # # # # ### # # ##### #
#     # #   # # # # #   # # #   #   #
####### # ### # # # ##### # ####### #
#       # #   # # #     # #       # #
#####################################
>>> 

Si vous souhaitez essayer d'exécuter ce programme vous-même, utilisez la commande M(Image, Show solution). Je recommanderais d'utiliser les guillemets triples pour saisir l'image car sinon, il y aura beaucoup de barres obliques inversées ou de caractères de nouvelle ligne impliqués.

Anonyme No Lifer
la source
1
Surnom
1
Bon travail! Quelques conseils: utilisez à la 0place de pass, l.append(a);l.append(b)-> l+=a,b, l.append(a)-> l+=[a], cela peut valoir la peine d'être attribué '#'à une variable, et def E(G,y,z):\n c=[]->def E(G,y,z,c=[]):
Loovjo
1
De plus, if G[r][c]==1 or G[r][c]==2:-> if 0<G[r][c]<3:, s=[0]\n for x in R(L(I[0])*2):s+=[0]-> s=[0]*(1+L(I[0])*2)et (je pense que je ne l'ai pas testé) G=[s]-> *G=s.
Loovjo
@Loovjo Merci pour les conseils except:0, l+=a,bet s=[0]*(1+L(I[0])*2)vraiment aidé. Malheureusement, pour une raison quelconque, l'attribution de c dans l'appel de fonction ne le réinitialise pas sur plusieurs appels, ce qui signifie qu'il a cessé de fonctionner, G [r] [c] peut être une chaîne, donc je ne peux pas utiliser <ou> dessus et le * G = s m'a donné une erreur de syntaxe. Encore de bons conseils.
Anonyme No Lifer
1
@AnonymousNoLifer Aucun problème. De plus, si G[r][c]peut être une chaîne, cela G[r][c]in[1,2]devrait fonctionner.
Loovjo