ASCII boxes look like this:
++ +---+ +------+ +---+ +---+
++ | | | | | | | |
| | | | | | | |
+-+ | | | | | | | |
+-+ | | | | | | +---+
+---+ | | | |
+--+ | | | | ++
| | | | | | ||
| | +------+ | | ||
+--+ | | ||
+---+ ||
||
+-----+ ||
+------------+ | | ++
| | | |
| | | |
+------------+ +-----+
Here are some examples of the same ASCII boxes, imploded:
++ +- -+ +- -+ +- -+ +- -+
++ | - | | - - | | - | | - |
| | | -- | | | | |
+-+ | | | | " | - |
+-+ | - | || | | +- -+
+- -+ | | | |
+--+ | -- | | | ++
| | | - - | " ||
| | +- -+ | | ||
+--+ | - | | |
+- -+ | |
-- ||
- - +- -+ ||
+- - - -+ | - - | ++
| -- -- | | = |
| -- -- | | - - |
+- - - -+ +- -+
- -
--
Here is a link to all of these test case boxes in an easier-to-copy format. The order is all inputs followed by all outputs in the same order.
Your goal is to take an ASCII box as input, and return the imploded box. The rules of implosion are:
- "+" never changes; neither do "-" or "|" directly adjacent to "+"
- Starting from the corners, the "-" and "|" move inward by one space more than the same character closer to the corner did. If a "-" and "|" would ever move to the same spot, neither moves.
- If a "-" and "-" move to the same spot, put a "=" in that spot. If a "|" and "|" move to the same spot, put a " in that spot. These count as two of their respective characters in the same spot moving in opposite directions.
- Two "-" or two "|" can move past each other, as seen in the bottom left example.
- If the box is skinny enough, it will start expanding outwards in the same way, always moving away from the side it started out part of.
- The result should be symmetric across the center line in both the x and y directions (ignoring newlines); this includes spaces, so the result may need to be padded with spaces to satisfy that.
Rule Details:
- This is code-golf, so shortest program in bytes wins.
- Standard loopholes apply.
- You can assume each line ends in a newline character.
- The only characters in the input string will be "+", "-", "|", " ", and "\n" (newline), and your output string should follow the same rules, with the addition of "=" and " as possible characters.
- You may optionally have a single trailing newline at the end of the last line.
- The smallest ASCII box you need to handle is the top-left example. Every ASCII box will have exactly 4 "+"s, exactly at its corners.
- You will need to handle boxes of size
m x n
for any integersm,n
such that2<=m,n<256
(largest possible string size of255*(255+1)
) - You can assume you will always get a single valid ASCII box as input.
2 Answers 2
Python 2, (削除) 591 (削除ここまで) (削除) 555 (削除ここまで) (削除) 545 (削除ここまで) (削除) 527 (削除ここまで) (削除) 525 (削除ここまで) (削除) 496 (削除ここまで) (削除) 436 (削除ここまで) (削除) 351 (削除ここまで) (削除) 334 (削除ここまで) (削除) 333 (削除ここまで) 303 bytes
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)
EDIT: My old method first imploded the top and bottom, and then the left and right. Instead, we can implode the top, rotate 90 degrees, and do that 4 times. Also, I was using the user-friendly code, this one requires input be in the form [['+', '-', '-', '-', '-', '-', '+'], ['|', ' ', ' ', ' ', ' ', ' ', '|'], ['|', ' ', ' ', ' ', ' ', ' ', '|'], ['|', ' ', ' ', ' ', ' ', ' ', '|'], ['+', '-', '-', '-', '-', '-', '+']]
which is ugly but shorter for the program :P (Thanks to Phoenix for catching that)
Credits to Leaky Nun for the header code in the TIO link used for converting human-readable input into computer-readable input.
-85 bytes thanks to Leaky Nun!
-17 bytes by switching from top-implosion to left-implosion which allows the entire row to be stored into a variable and modified. Thanks to Leaky Nun for the suggestion!
-1 byte by switching things around to remove a space.
-30 bytes thanks to Leaky Nun!
-
\$\begingroup\$ Assign
s[0]
andS[0]
to variables to save a few bytes \$\endgroup\$2017年05月27日 08:18:11 +00:00Commented May 27, 2017 at 8:18 -
\$\begingroup\$ @Ilikemydog Oh, right. Thanks! \$\endgroup\$2017年05月27日 15:19:49 +00:00Commented May 27, 2017 at 15:19
-
\$\begingroup\$ You can replace
p=s[0]
andP=S[0]
withp=z(s[0])
andP=z(S[0])
, respectively, and then replace all occurrences ofz(p)
withp
and allz(P)
withP
to save 18 bytes. \$\endgroup\$R. Kap– R. Kap2017年06月05日 02:25:38 +00:00Commented Jun 5, 2017 at 2:25 -
\$\begingroup\$ You can also replace
(z(s)-1)/2-p
withz(s)/2-.5-p
and(p-1)/2-z(s)
withp/2-.5-z(s)
to save 2 more bytes. \$\endgroup\$R. Kap– R. Kap2017年06月07日 02:55:01 +00:00Commented Jun 7, 2017 at 2:55 -
\$\begingroup\$ @R.Kap Oh okay. Thanks for both suggestions! \$\endgroup\$2017年06月07日 03:54:20 +00:00Commented Jun 7, 2017 at 3:54
C (clang), 693 bytes
New lines added for readability. The first two are required but the rest are not.
#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++);
}
Thanks for the great challenge! It was quite tricky but I still had a lot of fun.
This takes the input as command-line arguments and outputs to STDOUT a multi-line string of the imploded box. As always, golfing tips are very much appreciated.
-
\$\begingroup\$ 590 bytes \$\endgroup\$ceilingcat– ceilingcat2020年06月28日 06:03:39 +00:00Commented Jun 28, 2020 at 6:03
||
in that example need to be a"
or something... \$\endgroup\$"
though? I guess the"
only appears on 3-wide or greater? \$\endgroup\$"
go? On the left, or on the right side? It can't be both, but it can't be either because the result is symmetrical. \$\endgroup\$