Imploser la boîte

17

Les boîtes ASCII ressemblent à ceci:

++    +---+    +------+    +---+    +---+
++    |   |    |      |    |   |    |   |
      |   |    |      |    |   |    |   |
+-+   |   |    |      |    |   |    |   |
+-+   |   |    |      |    |   |    +---+
      +---+    |      |    |   |
+--+           |      |    |   |    ++
|  |           |      |    |   |    ||
|  |           +------+    |   |    ||
+--+                       |   |    ||
                           +---+    ||
                                    ||
                  +-----+           ||
+------------+    |     |           ++
|            |    |     |
|            |    |     |
+------------+    +-----+

Voici quelques exemples des mêmes boîtes ASCII implosées:

++    +- -+    +-    -+    +- -+    +- -+
++    | - |    | -  - |    | - |    | - |
       | |      | -- |      | |      | |
+-+    | |       |  |        "      | - |
+-+   | - |       ||        | |     +- -+
      +- -+      |  |      |   |
+--+            | -- |      | |     ++
|  |           | -  - |      "      ||
|  |           +-    -+     | |     ||
+--+                       | - |   |  |
                           +- -+   |  |
      --                            ||
     -  -         +-   -+           ||
+-  -    -  -+    | - - |           ++
| --      -- |     | = |
| --      -- |    | - - |
+-  -    -  -+    +-   -+
     -  -
      --

Voici un lien vers toutes ces boîtes de cas de test dans un format plus facile à copier. L'ordre est toutes les entrées suivies de toutes les sorties dans le même ordre.

Votre objectif est de prendre une boîte ASCII en entrée et de renvoyer la boîte implosée. Les règles d'implosion sont:

  1. "+" ne change jamais; ni "-" ni "|" directement à côté de "+"
  2. En partant des coins, les "-" et "|" déplacer vers l'intérieur d'un espace de plus que le même personnage plus près du coin. Si un "-" et un "|" se déplacerait jamais au même endroit, ni l'un ni l'autre ne bouge.
  3. Si un "-" et un "-" se déplacent au même endroit, mettez un "=" à cet endroit. Si un "|" et "|" déplacer au même endroit, mettre un "à cet endroit. Ceux-ci comptent comme deux de leurs personnages respectifs au même endroit se déplaçant dans des directions opposées.
  4. Deux "-" ou deux "|" peuvent se dépasser, comme le montre l'exemple en bas à gauche.
  5. Si la boîte est suffisamment maigre, elle commencera à s'étendre vers l'extérieur de la même manière, en s'éloignant toujours du côté où elle a commencé.
  6. Le résultat doit être symétrique à travers la ligne médiane dans les directions x et y (en ignorant les nouvelles lignes); cela inclut des espaces, il peut donc être nécessaire de compléter le résultat avec des espaces pour satisfaire cela.

Détails de la règle:

  1. Il s'agit de code-golf, donc le programme le plus court en octets gagne.
  2. Des échappatoires standard s'appliquent.
  3. Vous pouvez supposer que chaque ligne se termine par un caractère de nouvelle ligne.
  4. Les seuls caractères de la chaîne d'entrée seront "+", "-", "|", "" et "\ n" (nouvelle ligne), et votre chaîne de sortie devrait suivre les mêmes règles, avec l'ajout de "=" et "comme caractères possibles.
  5. Vous pouvez éventuellement avoir une seule nouvelle ligne à la fin de la dernière ligne.
  6. La plus petite boîte ASCII que vous devez gérer est l'exemple en haut à gauche. Chaque boîte ASCII aura exactement 4 "+", exactement à ses coins.
  7. Vous devrez gérer des boîtes de taille m x npour tous les entiers m,ntels que 2<=m,n<256(la plus grande taille de chaîne possible 255*(255+1))
  8. Vous pouvez supposer que vous obtiendrez toujours une seule boîte ASCII valide en entrée.
Melon fricatif
la source
Je pense que vous avez oublié d'ajouter "comme caractère possible dans la sortie sur le chiffre 4 des détails de la règle. Edit: Pouvons-nous supposer que l'entrée n'a pas de lignes vides?
Theraot
Cet exemple 1x6 est génial, pourquoi implose-t-il vers l'extérieur? Je pense que l'un de ceux ||de cet exemple doit être un "ou quelque chose comme ça
Magic Octopus Urn
@carusocomputing identique à l'exemple en bas à gauche, les murs se déplacent les uns les autres (donc le volume de la boîte est négatif) - règles 4 et 5.
Lyth
@Lyth ne devrait-il pas encore exister "? Je suppose que le "seul apparaît sur 3 de large ou plus?
Magic Octopus Urn
@carusocomputing Considérez ceci: Où iriez- "vous? À gauche ou à droite? Ça ne peut pas être les deux, mais ça ne peut pas non plus parce que le résultat est symétrique.
HyperNeutrino

Réponses:

15

Python 2 , 591 555 545 527 525 496 436 351 334 333 303 octets

s=input()
w=len(s[0])
h=len(s)
V=max(0,w/2-h)
H=max(0,h/2-w)
p=[[' ']*w]*V
q=[' ']*H
s=[q+k+q for k in p+s+p]
d,c=' -=',' |"'
exec"c,d,V,H,w,h=d,c,H,V,h,w;s=map(list,zip(*s))[::-1]\nfor j in range(h-4):q=s[V+j+2];q[H]=c[q[H]==c[2]];r=H+min(j+1,h-4-j);q[r]=c[1+(q[r]>' ')]\n"*4
for x in s:print''.join(x)

Essayez-le en ligne!

EDIT : Mon ancienne méthode a d'abord implosé le haut et le bas, puis la gauche et la droite. Au lieu de cela, nous pouvons imploser le haut, pivoter de 90 degrés et le faire 4 fois. De plus, j'utilisais le code convivial, celui-ci nécessite une entrée sous la forme [['+', '-', '-', '-', '-', '-', '+'], ['|', ' ', ' ', ' ', ' ', ' ', '|'], ['|', ' ', ' ', ' ', ' ', ' ', '|'], ['|', ' ', ' ', ' ', ' ', ' ', '|'], ['+', '-', '-', '-', '-', '-', '+']]qui est laide mais plus courte pour le programme: P (Merci à Phoenix d'avoir attrapé ça)

Crédits à Leaky Nun pour le code d'en-tête dans le lien TIO utilisé pour convertir les entrées lisibles par l'homme en entrées lisibles par ordinateur.

-85 octets grâce à Leaky Nun!
-17 octets en passant de l'implosion supérieure à l'implosion gauche qui permet à la ligne entière d'être stockée dans une variable et modifiée. Merci à Leaky Nun pour la suggestion!
-1 octet en inversant les choses pour supprimer un espace.
-30 octets grâce à Leaky Nun!

HyperNeutrino
la source
Affectez s[0]et S[0]à des variables pour économiser quelques octets
caird coinheringaahing
@Ilikemydog Oh, c'est vrai. Merci!
HyperNeutrino
Vous pouvez remplacer p=s[0]et P=S[0]avec p=z(s[0])et P=z(S[0]), respectivement, puis remplacer toutes les occurrences de z(p)avec pet tous z(P)avec Ppour économiser 18 octets.
R. Kap
Vous pouvez également remplacer (z(s)-1)/2-ppar z(s)/2-.5-pet (p-1)/2-z(s)par p/2-.5-z(s)pour économiser 2 octets supplémentaires.
R. Kap
@ R.Kap Oh d'accord. Merci pour les deux suggestions!
HyperNeutrino
1

C (clang) , 693 octets

Nouvelles lignes ajoutées pour plus de lisibilité. Les deux premiers sont requis mais les autres ne le sont pas.

#define P B[i][l]
#define m malloc(8)
I(B,h,V,S,J,Z,i,j,l,n,H,W,c,C,a,z,_,L,G,u,N,M)char**B,**Z;char*L,*G,*u;{
V=strlen(B[0]);
S=J=0;
Z=m;
for(i=0,j=h-1;i<h/2+h%2;i++,j--){
for(l=0,n=V-1;l<V/2+V%2;l++,n--){
if(P!=43&&((B[i][l-1]!=43&&i<1)||(B[i-1][l]!=43&&l<1))){
H=P==45;
W=P=='|';
P=B[j][l]=B[i][n]=B[j][n]=32;
if(H){
c=(N=i+l-1)==(M=j-l+1)?61:45;
if(M<0)L=m,sprintf(L,"%*s",V,""),L[l]=L[n]=c,Z[J]=L,J++;
else B[N][l]=B[N][n]=B[M][l]=B[M][n]=c;
}
if(W){
c=(N=l+i-1)==(M=n-i+1)?34:'|';
if(M<0)G=m,sprintf(G,"|%*s%s%*s|",i-n-2,"",B[i],i-n-2,""),B[i]=B[j]=G,S++;
else B[i][N]=B[j][N]=B[i][M]=B[j][M]=c;
}
}
}
}
for(a=-J+1;a<=h+J;u=a<1?Z[-a]:a<=h?B[a-1]:Z[a-h-1],C=S+1-strlen(u)/2,printf("%*s%s\n",C>0?C:0,"",u),a++);
}

Merci pour le grand défi! C'était assez compliqué mais je m'amusais toujours beaucoup.

Cela prend l'entrée comme arguments de ligne de commande et renvoie à STDOUT une chaîne de plusieurs lignes de la boîte implosée. Comme toujours, les conseils de golf sont très appréciés.

Essayez-le en ligne!

R. Kap
la source