Python 2, 1033 1007 924 879 829 787 713 699 692 691 688 687 672 670 664 659 654 648 643 642 630 625 623 620 570 560 554 545 518 514 513 510 505 492 476 454 451 443 partes
6 octets économisés grâce à Riley
6 octets économisés grâce à Adnan
Depuis que cette question a plus d'un an et n'a toujours pas de réponse, je pensais essayer.
n,i,o,u="\nI _";R=lambda x:range(1,x-1)
b=open(i).read()
s=b.split(n)
z=max(map(len,s))+3
a=[list(i+x.ljust(z,i))for x in[i]+s+[i]]
for x in R(len(a))*len(b):
A=a[x];B=a[x+1];C=a[x-1]
for y in R(z):
D=A[y-1:y+2];k=B[y];j=A[y+1]
if(i in[C[y],k]+D+(k==u)*B[y-1:y+2]or"V"==j)&(A[y]==o):A[y]=i
if"|"==A[y]==C[y]:A[y]={i:"|",j:">",A[y-1]:"<"}[i]
if[u]*3==D:A[y],B[y]={i:u+k,C[y]:"^"+k,k:" V"}[i]
print n.join(`y`[2::5]for y in a).replace(i,o)
Essayez-le en ligne!
Le programme lit dans la table un fichier nommé I
et l’imprime avec ses chaises std::out
. Je n'étais pas sûr de la plupart des cas critiques, j'ai donc pris mon meilleur jugement (celui qui demandait le moins d'effort), mais il semble que tous les tests soient satisfaisants. Certaines des sorties ne correspondent pas exactement mais elles ont toutes le même nombre de chaises.
Explication
La première ligne définit assez simplement quelques définitions qui nous permettront d’économiser des octets à l’avenir:
(Je vais décompresser ces macros pour plus de lisibilité dans les lignes futures)
n,i,o="\nI ";R=lambda x:range(1,x-1)
Ensuite, nous allons ouvrir un fichier nommé I
parce que nous avons déjà une variable qui est courte pour cela, donc cela économise quelques octets.
b=open("I").read().split("\n")
Nous nous sommes séparés le long des nouvelles lignes pour créer une liste de chaînes (les lignes de l'image)
s=b.split(n)
Je trouve ensuite la longueur de la plus longue ligne afin de pouvoir remplir toutes les lignes avec cette longueur. (J'ajoute aussi 3 car nous avons besoin d'un peu de rembourrage supplémentaire)
z=max(map(len,s))+3
Ensuite, nous effectuons le remplissage réel et créons une bordure de I
caractères autour du bord. En effet, nous devrons faire la différence plus tard entre l'intérieur et l'extérieur de la forme. Nous allons également modifier le type de données d’une liste de chaînes en une liste de caractères (longueur de 1 chaîne).
a=[list("I"+x.ljust(z,"I"))for x in["I"]+s+["I"]]
La ligne suivante est juste une autre définition d’économie d’octets.
(Je vais aussi déballer celui-ci)
B=R(len(a))
Maintenant, nous voulons diffuser les I
caractères partout en dehors de la forme. Nous pouvons le faire avec un automate pseudo-cellulaire. Chacun I
se propagera à tous les
personnages adjacents . Nous pourrions faire une boucle jusqu'à ce que l'automate se stabilise, mais cela ne peut pas prendre plus d'itérations qu'il n'y a de caractères, donc nous passons en boucle à travers chaque caractère b
(l'entrée d'origine)
for _ in b:
Pour chaque itération, nous voulons passer par-dessus chaque caractère de la liste 2D (à l'exception du remplissage le plus à l'extérieur)
for x in range(1,len(a)-1):
A=a[x] #<--Another definition I will fill in for clarity
for y in range(1,z-1):
Pour chaque position, nous lançons le code suivant:
if("I" in[a[x+1][y],a[x-1][y]]+a[x][y-1:y+2])&(a[x][y]==" "):a[x][y]=" "
Permet de décomposer cela.
Nous avons un si avec deux conditions séparées par un &
(bit à bit and
)
Le premier vérifie simplement s'il y a une I
dans l'une des cellules adjacentes et le second vérifie simplement si la cellule en cours est a " "
. Si nous remplissons ces conditions, nous définissons la cellule actuelle comme un I
.
Maintenant que nous avons déterminé l'extérieur et l'intérieur de la forme, nous pouvons commencer à placer les chaises autour de la table.
Encore une fois, nous parcourons toutes les cellules (et définissons quelques raccourcis)
for x in range(1,len(a)-1):
A=a[x]
for y in range(1,z-1):
k=a[x+1][y]
Maintenant voici ma partie préférée. Si vous avez traversé mon golf ennuyeux, principalement basé sur la définition à ce jour, je vais vous récompenser avec une belle friandise de golf intelligent (si je le dis moi-même).
Un petit fond en python:
En Python, si vous essayez d’attribuer deux fois une clé de dictionnaire, elle l’indique. Par exemple
>>> {1:"a",1:"b"}[1]
'b'
Nous abuserons de cette propriété pour attribuer la cellule actuelle à un caractère particulier.
La première condition est
if["_"]*3==a[x][y-1:y+2]:a[x][y],a[x+1][y]={"I":"_"+a[x+1][y],a[x-1][y]:"^ ",a[x+1][y]:" V"}["I"]
Si la cellule est au milieu d'un bord de 3 _
caractères, nous réaffecterons la cellule actuelle et la cellule située en dessous. Nous l'attribuerons au résultat de l'indexation d'un dictionnaire surchargé par I
. Nous définissons d'abord notre valeur par défaut avec la paire, "I":"_"+a[x+1][y]
ce qui signifie que s'il n'y a pas de changement, nous attribuerons les deux cellules à leurs valeurs d'origine. Ensuite, nous ajoutons la paire a[x-1][y]:"^ "
. Cela ne fera rien (important) à moins que la cellule au-dessus de la cellule actuelle ( a[x-1][y]
) ne soit remplie par un I
. S'il y en a un I
, il remplacera la valeur par défaut en nous demandant de placer une chaise dans la cellule en cours. Ensuite, nous passons à la cellule située en dessous de la cellule actuelle si cette cellule est I
remplacée par une nouvelle position afin de placer un fauteuil orienté vers le haut sous le point actuel.
La condition suivante est un peu plus simple
if"|"==a[x][y]==a[x-1][y]:a[x][y]={"I":"|",A[y+1]:">",A[y-1]:"<"}["I"]
Nous vérifions si la cellule en cours et la cellule au-dessus sont les deux |
. Si c'est le cas, nous mettons en place un dictionnaire.
La première paire du dictionnaire "I":"|"
définit la valeur par défaut. Puisque nous allons accéder à la clé I
si elle I
n’est pas réaffectée, elle reviendra par défaut à |
(le personnage qu’elle est déjà) et ne fait rien.
Nous ajoutons les deux clés A[y+1]:">",A[y-1]:"<"
Si l'une ou l'autre des deux cellules situées à gauche et à droite le sont, I
la cellule actuelle sera réaffectée à une chaise pointant dans la direction de l'extérieur.
Il ne reste plus qu’à sortir. Cependant, nous ne pouvons pas simplement imprimer, nous devons commencer par quelques tâches d’entretien. Nous devons reconvertir en chaîne et supprimer tous les I
s que nous avons créés. Ceci est fait dans une ligne.
print "\n".join(`y`[2::5]for y in a).replace("I"," ")