Build ASCII Podiums

26

5

In sporting competitions, it often happens that winners are presented on podiums, with the first-place person on the highest in the middle, the second-place person on the middle height to the left, and the third-place person on the lowest and to the right. We're going to recreate that here with some special tweaks.

The podiums are presented below:

     @---@
     | @ |
@---@| | |
| @ || | |
| | || | |@---@
| | || | || @ |

This will form the basis for this challenge. The next step is to make the podiums wide enough to fit the people (printable ASCII strings) that are on them. However, we want to ensure aesthetic beauty (because this is a fantastic photo opportunity), so each podium needs to be the same width, and the width must be odd. Additionally, the people will (obviously) want to stand in the center of the podium, so the strings must be centered as best as possible. (You can align to either the left or the right, and it doesn't need to be consistent.) The above podiums are the minimum size, and are considered 3 wide.

For example, given the input ["Tom", "Ann", "Sue"] representing first-, second-, and third-place respectively, output the following podiums:

      Tom
     @---@
 Ann | @ |
@---@| | |
| @ || | | Sue
| | || | |@---@
| | || | || @ |

However, if we have Anne instead of Ann, we'll need to go up to the next size, 5, and center the strings as best as possible. Here, I'm aligning so the "extra" letter of Anne is to the left of center, but you can choose which side to align to.

         Tom
       @-----@
 Anne  |  @  |
@-----@|  |  |
|  @  ||  |  |  Sue
|  |  ||  |  |@-----@
|  |  ||  |  ||  @  |

Let's go for some longer names. How about ["William", "Brad", "Eugene"]:

          William
         @-------@
  Brad   |   @   |
@-------@|   |   |
|   @   ||   |   | Eugene
|   |   ||   |   |@-------@
|   |   ||   |   ||   @   |

Here we can see that Brad has a lot of whitespace, Eugene less so, and William fits just right.

For a longer test case, how about ["A", "BC", "DEFGHIJKLMNOPQRSTUVWXYZ"]:

                                     A
                         @-----------------------@
           BC            |           @           |
@-----------------------@|           |           |
|           @           ||           |           | DEFGHIJKLMNOPQRSTUVWXYZ
|           |           ||           |           |@-----------------------@
|           |           ||           |           ||           @           |

Finally, we have the smallest possible input, something like ["A", "B", "C"]:

       A
     @---@
  B  | @ |
@---@| | |
| @ || | |  C
| | || | |@---@
| | || | || @ |

  • Input and output can be given by any convenient method.
  • The input is guaranteed non-empty (i.e., you'll never receive "" as a name).
  • You can print it to STDOUT or return it as a function result.
  • Either a full program or a function are acceptable.
  • Any amount of extraneous whitespace is acceptable, so long as the characters line up appropriately.
  • Standard loopholes are forbidden.
  • This is so all usual golfing rules apply, and the shortest code (in bytes) wins.

AdmBorkBork

Posted 2019-02-20T17:20:11.813

Reputation: 41 581

Do all even-length names have to be aligned in the same direction? – Sparr – 2019-02-21T00:42:10.437

1Why do the podiums in the last example output have length 3 instead of length 1? – bruderjakob17 – 2019-02-21T13:33:45.547

3@bruderjakob he states at the beginning "the podiums above are the minimum size and are considered 3 wide" – rtpax – 2019-02-21T13:36:46.047

Answers

9

JavaScript (ES8), 196 bytes

a=>`141
101
521
031
236
330
332`.replace(/./g,n=>[...`@-@   |@||||`.substr(n*3,3)].join(' -'[+!+n].repeat(m/2))||a[n-=4].padStart(m+l[n]+3>>1).padEnd(m+3),m=Math.max(2,...l=a.map(s=>s.length))&~1)

Try it online!

Arnauld

Posted 2019-02-20T17:20:11.813

Reputation: 111 334

7

Groovy, 187, 176, 156, 150 bytes

f={n->m=n*.size().max()|1;h=' '*(m/2);'30734715746756276647665'*.toLong().sum{(n*.center(m+2)+[' '*(m+2),"@${'-'*m}@","|$h@$h|","|$h|$h|",'\n'])[it]}}

Try it online!

(note: the tio groovy interpreter could not handle indexing Lists using Long values even though groovy 2.5.6 can. Thus the tio answer is using *.toShort() instead of *.toLong() which adds a byte)

Defines a closure f which can be called via:

println(f(['tom','ann','sue']))

where f returns a string.

Explanation:

Unobfuscating the code, we have:

f={n->
  m=n*.size().max()|1
  h=' '*(m/2)
  a=n*.center(m+2)+[' '*(m+2),"@${'-'*m}@","|$h@$h|","|$h|$h|",'\n']
  '30734715746756276647665'*.toLong().sum{a[it]}
}
  • f={n-> - define closure f with one in-param n
  • m=n*.size().max()|1 - find max name len, binary-or to odd number
  • h=' '*(m/2) - h will contain floor(m/2) spaces, used later
  • a=...- creates an encoding list with elements:
    • indexes 0,1,2 - names, centered to max len
    • index 3 - m+2 spaces
    • index 4 - @---@ pattern, padded to len
    • index 5 - | @ | pattern, padded to len
    • index 6 - | | | pattern, padded to len
    • index 7 - newline
  • '307...'*.toLong().sum{a[it]}- use indicies into the encoding list to build the result. .sum uses the fact that string + string in groovy is valid.
  • note that the expression '3073...'*.toLong() uses the *. spread operator to call toLong() on each character, returning a list of numbers.
  • note in the answer the variable a has been inlined,nelines removed etc.

Matias Bjarland

Posted 2019-02-20T17:20:11.813

Reputation: 420

6

Canvas, 45 bytes

r351⁰{|*@;∔;J└l2M2%±├ ××l⇵╷-×└+-α∔k+│∔⇵;}┐++⇵

Try it here!

Explanation:

r    Center the input, preferring left. Converts to an ASCII-art object
     which pads everything with spaces. This is the bulk of the magic.

 251⁰{ .... }            for each number in [2, 5, 1]:
      |*                 repeat "|" vertically that many times
        @;∔              prepend an "@" - a vertical bar for later
           ;             swap top 2 stack items - put the centered art on top
            J            push the 1st line of it (removing it from the art)
             └           order the stack to [remaining, "@¶|¶|..", currentLine]
              l          get the length of the current line
               2M        max of that and 2
                 2%      that % 2
                   ±├    (-that) + 2
                      ×× prepend (-max(len,2)%2) + 2 spaces
l                 get the length of the new string
 ⇵╷               ceil(len / 2) -1
   -×             repeat "-" that many times - half of the podiums top
     └            order stack to [art, currLine, "@¶|¶|..", "----"]
      +           append the dashes to the vertical bar = "@-----¶|¶|.."
       -α∔        vertically add "-" and the original vertical bar - "-¶@¶|¶|.."
          k       remove the last line of that to make up for the middles shortness
           +      and append that horizontally - half of the podium without the name
            │     palindromize the podium
             ∔    and prepend the name
              ⇵   reverse vertically so the outputs could be aligned to the bottom
               ;  and get the rest of the centered input on top
Finally, 
┐     remove the useless now-empty input
 ++   join the 3 podium parts together
   ⇵  and undo the reversing

Abuses "and it doesn't need to be consistent", making it pretty unintelligible.

dzaima

Posted 2019-02-20T17:20:11.813

Reputation: 19 048

Umm...any chance of an explanation? – Matias Bjarland – 2019-02-20T22:43:17.203

1@MatiasBjarland though it's mostly stack manipulation and the rest i barely understand, there. – dzaima – 2019-02-20T23:05:46.007

4

Python 2, 197 190 bytes

n=input()
w=max([3]+map(len,n))
w+=~w%2;W=w+2
S=('{:^%d}'%w).format
x,y,s='@| '
a,b,c=map(S,n);A,B,C=x+'-'*w+x,y+S(x)+y,y+S(y)+y
for l in-~W*s+a,s*W+A,s+b+s+B,A+C,B+C+s+c,C+C+A,C+C+B:print l

Try it online!

-6 bytes, thanks to Andrew Dunai

TFeld

Posted 2019-02-20T17:20:11.813

Reputation: 19 246

You can save 6 bytes by replacing line 5 to x,y,p='@| ' and using p instead of ' ' – Andrew Dunai – 2019-02-21T19:01:20.607

1@andrewdunai thanks :) – TFeld – 2019-02-21T21:50:40.020

4

Python 2, 157 bytes

a=input()
i=7
while i:print''.join(([a[k/2]]+list('-@||||    '))[7-i-k].center(max(map(len,a))|1,'- '[i+k!=6]).join('@ |'[cmp(i+k,6)]*2)for k in(2,0,4));i-=1

Try it online!

Lynn

Posted 2019-02-20T17:20:11.813

Reputation: 55 648

3

Charcoal, 63 bytes

≔÷⌈EθLι²ηF³«J×ι⁺³⊗η⊗﹪⁻¹ι³⟦◧§θι⁺⊕η⊘⊕L§θι⟧≔⁻⁷ⅉιP↓ι@ηP↓ιP↓@@¹ηP↓ι@

Try it online! Link is to verbose version of code. Explanation:

≔÷⌈EθLι²η

Calculate the number of spaces in each half of a podium.

F³«

Loop over each place. Note that input is expected to be in the order 2nd, 1st, 3rd.

J×ι⁺³⊗η⊗﹪⁻¹ι³

Position to the start of the line that will have the text.

⟦◧§θι⁺⊕η⊘⊕L§θι⟧

Output the text with enough left padding to centre it.

≔⁻⁷ⅉι

Get the height of the podium.

P↓ι@ηP↓ιP↓@@¹ηP↓ι@

Draw the podium.

Alternative approach, also 63 bytes:

≔÷⌈EθLι²ηF³«J×ι⁺³⊗η⊗﹪⁻¹ι³⟦◧§θι⁺⊕η⊘⊕L§θι⪫@-@×-η⟧E⁻⁷ⅉ⪫⪫||§|@¬κ× η

Try it online! Link is to verbose version of code. Explanation:

≔÷⌈EθLι²η

Calculate the number of spaces in each half of a podium.

F³«

Loop over each place. Note that input is expected to be in the order 2nd, 1st, 3rd.

J×ι⁺³⊗η⊗﹪⁻¹ι³

Position to the start of the line that will have the text.

⟦◧§θι⁺⊕η⊘⊕L§θι

Output the text with enough left padding to centre it.

⪫@-@×-η⟧

Also output the top of the podium by inserting -s between the characters of the string @-@ to reach the correct width.

E⁻⁷ⅉ⪫⪫||§|@¬κ× η

Print the remainder of the podium by spacing the |s appropriately, except that the middle character is a @ on the first row.

Neil

Posted 2019-02-20T17:20:11.813

Reputation: 95 035

3

R 308 302 299

-6 bytes thanks to @JAD
-3 bytes thanks to @Guiseppe, now I'm under 300

function(a){i=max(1,nchar(a)%/%2)
e=2*i+1
`~`=rep
g=' '
s=g~e+2
b='@'
p='|'
t=c(b,'-'~e,b)
x=c(p,g~i,b,g~i,p)
h=sub(b,p,x)
a=lapply(a,function(q){r=nchar(q);l=(e-r)/2+1;if(r%%2<1)c(g~l,q,g~l+1)else c(g~l,q,g~l)})
cat(s,a[[1]],s,s,t,s,a[[2]],x,s,t,h,s,x,h,a[[3]],h,h,t,h,h,x,fill=length(t)*3,sep='')}

There's probably a better way to create the layout; I should try what options I have for data frames.

Try it online

CT Hall

Posted 2019-02-20T17:20:11.813

Reputation: 591

304 bytes – JAD – 2019-02-21T13:58:59.607

2

hats off to ya for doing a variable [tag:ascii-art] challenge in R...never fun to do. You can save 3 bytes by using i=max(1,nchar(a)%/%2). Generating a matrix and using write might be shorter (rather than a data.frame). I suggest using format with j="c" to auto-justify things, and strrep is a helpful one in this case as well. Maybe try the golfR chatroom to bounce ideas off?

– Giuseppe – 2019-02-21T20:40:41.343

Yeah, I didn't realize how hard it would be going into it. I learned a bit tho, mostly I should learn Python better, or start learning Perl :). I'd forgotten about strrep; I'll have to look into that. – CT Hall – 2019-02-21T22:46:22.710

2

Clean, 209 bytes

import StdEnv,Data.List
k=[' @|||||']
$l#m=max(maxList(map length l))3/2*2+1
=flatlines(transpose[(spaces(n*2)++g)%(0,6)\\n<-[1,0,2],g<-[k:[[c,'-':tl if(i==m/2)k['  '..]]\\c<-cjustify m(l!!n)&i<-[0..]]]++[k]])

Try it online!

Οurous

Posted 2019-02-20T17:20:11.813

Reputation: 7 916

2

Python 2, 188 bytes

a,b,c=l=input()
s=max(map(len,l))/2or 1
A='@'+'--'*s+'-@'
D=(' '*s).join
C=D('|@|')
D=D('|||')
d=str.center
S=s*2+3
for l in' '*S+d(a,S),' '*S+A,d(b,S)+C,A+D,C+D+d(c,S),D+D+A,D+D+C:print l

Try it online!

-5 thanks to TFeld.

Erik the Outgolfer

Posted 2019-02-20T17:20:11.813

Reputation: 38 134

2

PHP, 147 bytes

golfed 93 bytes off my initial idea, a straight forward <?=:

for(;~$v=_616606256046543440445[++$i];)echo$b="@   || "[$v],str_pad(($v&4?"|@":$argv)[$v&3],max(array_map(strlen,$argv))," -"[!$v],2),$b,"
"[$i%3];

takes names from command line arguments. Run with -nr or try it online.
Requires PHP 7; yields warnings in PHP 7.2 (and later, presumably). See the TiO for a +5 byte fix.

mapping:

0:@---@     = top border
1,2,3       = $argv with spaces
4: "| | |"  = default
5: "| @ |"  = below top
6: "     "  = empty

breakdown:

for(;~$v=_616606256046543440445[++$i];)echo # loop through map:
    $b="@   || "[$v],                       # print left border
    str_pad(                                # print padded string:
        ($v&4?"|@":$argv)[$v&3],                # string to be padded
        max(array_map(strlen,$argv)),           # pad length = max argument length
        " -"[!$v],                              # pad with: dashes if top border, spaces else
        2                                       # option: center text (pad on both sides)
    ),
    $b,                                     # print right border
    "\n"[$i%3]                              # add linebreak every three items
;

The pre-increment for $i saves me from any tricks for the newlines.
The blank for 6 can also be empty; so I did that.
But using $argv[0] for the top border string - was the nicest golf ever. (and saved 9 bytes!)

Titus

Posted 2019-02-20T17:20:11.813

Reputation: 13 814

2

Go, 436 bytes

Go is terrible for golf. But:

package main;import ("fmt";"os");func main(){;z:=os.Args;f:=3;for i:=1;i<4;i++{;if len(z[i])>f{;f=len(z[i]);};};f+=1-f%2;p:=(f-1)/2+1;b:="@";for j:=0;j<f;j++{;b+="-";};b+="@";x:=fmt.Sprintf("|%*v%*v",p,"@",p,"|");y:=fmt.Sprintf("|%*v%[1]*v",p,"|");fmt.Printf("%*v%*v\n%*v%v\n%*v%*v\n%v%v\n%v%v%*v\n%v%v%v\n%v%v%v",f+2,"",p+1+len(z[1])/2,z[1],f+2,"",b,p+1+len(z[2])/2,z[2],2*f+3-p-len(z[2])/2,x,b,y,x,y,p+1+len(z[3])/2,z[3],y,y,b,y,y,x)}

Broken down:

package main
import (
  "fmt"
  "os"
)
func main() {
  z:=os.Args
  f:=3
  for i:=1;i<4;i++{
    if len(z[i])>f{
      f=len(z[i])
    }
  }
  f+=1-f%2
  p:=(f-1)/2+1
  b:="@"
  for j:=0;j<f;j++{
    b+="-"
  }
  b+="@"
  x:=fmt.Sprintf("|%*v%*v",p,"@",p,"|")
  y:=fmt.Sprintf("|%*v%[1]*v",p,"|")

  fmt.Printf("%*v%*v\n%*v%v\n%*v%*v\n%v%v\n%v%v%*v\n%v%v%v\n%v%v%v",
  f+2,"",p+1+len(z[1])/2,z[1],
  f+2,"",b,
  p+1+len(z[2])/2,z[2],2*f+3-p-len(z[2])/2,x,
  b,y,
  x,y,p+1+len(z[3])/2,z[3],
  y,y,b,y,y,x)
}

greyShift

Posted 2019-02-20T17:20:11.813

Reputation: 221

1

Java 8, 399 394 373 Bytes

This solution is probably way too long, but it is a solution :)

static String r(String[]p){String s="";int l[]=new int[]{p[0].length(),p[1].length(),p[2].length()},m=Math.max(l[0],Math.max(l[1],l[2]))+2,i,q,j,a,k,t;if(m%2==0)m++;if(m==3)m=5;for(i=0;i<7;i++){for(q=0;q<3;q++)for(j=0;j<m;j++){a=(2*q+1)%3;k=2*a;t=(m-l[a])/2;s+=i==k?j>=t&j<t+l[a]?p[a].charAt(j-t):" ":i==k+1?j%(m-1)==0?"@":"-":i>=k+2?j%(m-1)==0?"|":j==m/2?i==k+2?"@":"|":" ":" ";}s+="\n";}return s;}

Saved 5 Bytes by directly iterating in order (a=1,0,2 instead of q=0,1,2; a=f(q))

static String r(String[]p){String s="";int l[]=new int[]{p[0].length(),p[1].length(),p[2].length()},m=Math.max(l[0],Math.max(l[1],l[2]))+2,i,j,a,k,t;if(m%2==0)m++;if(m==3)m=5;for(i=0;i<7;i++){for(a=1;a<4;a=a==1?0:a+2)for(j=0;j<m;j++){k=2*a;t=(m-l[a])/2;s+=i==k?j>=t&j<t+l[a]?p[a].charAt(j-t):" ":i==k+1?j%(m-1)==0?"@":"-":i>=k+2?j%(m-1)==0?"|":j==m/2?i==k+2?"@":"|":" ":" ";}s+="\n";}return s;}

Saved 21 Bytes thanks to @KevinCruijssen:

static String r(String[]p){String s="";int l[]=new int[3],m=0,i,j,a,k,t;for(String x:p)l[m++]=x.length();m=Math.max(l[0],Math.max(l[1],l[2]))+2;m+=m%2<1?1:m==3?2:0;for(i=0;i<7;i++,s+="\n")for(a=1;a<4;a=a==1?0:a+2)for(j=0,k=2*a,t=(m-l[a])/2;j<m;j++)s+=i==k?j>=t&j<t+l[a]?p[a].charAt(j-t):" ":i==k+1?j%~-m<1?"@":"-":i>=k+2?j%~-m<1?"|":j==m/2?i==k+2?"@":"|":" ":" ";return s;}

As @KevinCruijssen suggested, one could also use var instead of String in Java 10+ and save some extra Bytes. I don't do this for the simple reason that I don't have Java 10 yet :D also, lambdas could be used. But this would only reduce the amount of bytes if we would leave out assigning it to a Function<String[],String> variable.

In expanded form:

static String r(String[]p){
    String s=""; //The string that will be returned
    int l[]=new int[3], //An array containing the lengths of our three names
            m=0, //tmp variable for filling l
            i,j,a,k,t; //some declarations to save a few bytes lateron
    for(String x:p) l[m++]=x.length();
    m=Math.max(l[0],Math.max(l[1],l[2]))+2;
    m+=m%2<1? //ensure odd length of the podests
        1
        :m==3?2:0; //ensure the length is at least 3 (in my code, m is the length of the podests + 2)
    for(i=0;i<7;i++,s+="\n") //iterate by row
        for(a=1;a<4;a=a==1?0:a+2) //iterate by place: a=1,0,2
            for(j=0,k=2*a,t=(m-l[a])/2;j<m;j++) //iterate by column
                //k is the row number from top in which the a-th name goes
                //t is the column at which the name starts
                //now, append the right char:
                s+=i==k? //write the name
                    j>=t&j<t+l[a]?
                        p[a].charAt(j-t)
                        :" "
                    :i==k+1? //write the top of the podest ("@---@")
                        j%~-m<1?
                            "@"
                            :"-"
                    :i>=k+2? //write the bottom of the podest ("|  |@  |")
                        j%~-m<1? //the left and right edge of the podest
                            "|"
                            :j==m/2? //the center of the podest
                                i==k+2? //are we at the first row of the bottom?
                                    "@" //the case where we have to write "| @ |"
                                    :"|" //the case "| | |"
                                :" "
                        :" "
                ;
    return s;
}

The input has to be given as String-array of length 3. An example looks like this:

public static void main(String[] args){
    System.out.print(r(new String[]{"Anthony", "Bertram", "Carlos"}));
}

Output:

          Anthony          
         @-------@         
 Bertram |   @   |         
@-------@|   |   |         
|   @   ||   |   | Carlos  
|   |   ||   |   |@-------@
|   |   ||   |   ||   @   |

bruderjakob17

Posted 2019-02-20T17:20:11.813

Reputation: 141

1

Nice answer, and welcome to PPCG! +1 from me! Here some basic things to golf to make it 342 bytes: Java 8+ lambda instead of regular method; Java 10+ var instead of String; filled the length-array with a for-each loop; changed if(m%2==0)m++;if(m==3)m=5; to m+=m%2<1?m==2?3:1:0 for the same effect; changed all %nr==0 to %nr<1; changed the %(m-1) to %~-m; put everything inside the loop itself so the brackets {} can be removed.

– Kevin Cruijssen – 2019-02-21T14:49:29.903

If you haven't seen it yet, Tips for golfing in Java and Tips for golfing in <all languages> might both be interesting to read through. Enjoy your stay!

– Kevin Cruijssen – 2019-02-21T14:50:24.200

@KevinCruijssen alright, thank you very much! I'll update the post! – bruderjakob17 – 2019-02-21T14:53:53.773

Suggest m-l[a]>>1 instead of (m-l[a])/2 and i<k+2?" ":j%~-m<1?"|":j==m/2?i==k+2?"@":"|" instead of i>=k+2?j%~-m<1?"|":j==m/2?i==k+2?"@":"|":" " – ceilingcat – 2019-09-28T00:43:34.643

1

C(GCC) 302 293 292 289 287 bytes

-6 byte thanks to ceilingcat

#define P(h,n)r=w+2-L[n];i/h?printf("%*s%*s%*s",-~r/2,D,L[n],i>h?D:N[n],r/2,D):printf(~i/h?"@%s@":"|%*s%c%*s|",~i/h?D+1:w/2,D,i>h-3?64:'|',w/2,D);
f(int**N){char L[3],w=3,i=3,r,D[99]={};for(;i--;)w=w<(L[i]=strlen(N[i]))?L[i]|1:w;memset(D+1,45,w);for(i=7;i--;puts(D)){P(4,1)P(6,0)P(2,2)}}

Run it here

Ungolfed and explained (technically you can't have comments after back slashes in macros, so this won't run)

#define P(h,n)\
    r=w+2-L[n];\ //get leftover width
    i/h?\ //if i >= h
        printf("%*s%*s%*s",-~r/2,D,L[n],i>h?D:N[n],r/2,D):\//if too high print all spaces, otherwise center the name
        printf(~i/h?"@%s@":"|%*s%c%*s|",~i/h?D+1:w/2,D,i>h-3?64:'|',w/2,D);
//if (i == h - 1) print top row using D calculated if row right below top, else print '@'(64) in center, otherwise '|'
f(int**N){
    char
        L[3],//lengths of each string
        w=3,//width (init to minimum)
        i=3,//index, used in for loops
        l,//left padding
        r,//right padding
        D[99]={};//string of '-' of correct length (max 99) but first char is null for empty string
    for(;i--;)//i was set to 3 before, i will be {2,1,0}
        w=w<(L[i]=strlen(N[i]))?//set length to str len and compare to longest width so far
            L[i]|1://set it to length if longer, but make sure it is odd
            w;//do not replace
    memset(D+1,45,w); //set the first w bits of D to '-', leaves a null terminator
    for(i=7;i--;puts(D)){//i will be {6...0}
        P(4,1)//print second place, 4 high
        P(6,0)//print first place, 6 high
        P(2,2)//print thrid place, 2 high
    }
}

Here is the calling code

int main()
{
  char* N[3] = {"Tom", "Anne", "Sue"} ;
  f(N);
}

and output

         Tom         
       @-----@       
  Anne |  @  |       
@-----@|  |  |       
|  @  ||  |  |  Sue  
|  |  ||  |  |@-----@
|  |  ||  |  ||  @  |

rtpax

Posted 2019-02-20T17:20:11.813

Reputation: 411

Suggest for(;i--;memset(D+1,45,w))w=w<(L[i]=strlen(N[i]))?L[i]|1:w; instead of for(;i--;)w=w<(L[i]=strlen(N[i]))?L[i]|1:w;memset(D+1,45,w); – ceilingcat – 2019-04-08T01:47:50.907

1

PowerShell for Windows, 231 223 bytes

param($a)$w=($a|% le*|sort)[-1]
if(3-gt$w){$w=3}$w+=1-$w%2
0..6|%{$r=$_
-join($a|%{$m=' -'[5-eq($o=$r+2*(++$i%3))]
$e='     @|||||'[$o]
$x=(,''*4+$_,'','@'+,'|'*4)[$o]
"$e$($x|% *ft(($x.Length+$w)/2-.1)$m|% *ht $w $m)$e"})}

Try it online!

Input is array @('second','first','third'). Unrolled version:

param($arr)
$width=($arr|% length|sort)[-1]
if(3-gt$width){$width=3}
$width+=1-$width%2

0..6|%{ $row=$_                         # 7 rows
    -join($arr|%{                       # 3 joined columns. Each column array contains 11 lines.
        $offset = $row+2*(++$i%3)       # (2,4,0) -> offset in column array #   0:
        $middle = ' -'[5-eq$offset]                                         #   1:
        $edge   = '     @|||||'[$offset]                                    #   2:
        $center = ('','','','',$_,'','@','|','|','|','|')[$offset]          #   3:
                                                                            #   4:  name
        # pad $x to a center                                                #   5: @---@
        $center = $center|% PadLeft (($center.Length+$width)/2-.1) $middle  #   6: | @ |
        $center = $center|% PadRight $width $middle                         #   7: | | |
                                                                            #   8: | | |
        # add the $edge                                                     #   9: | | |
        "$edge$center$edge"                                                 #  10: | | |
    })
}

mazzy

Posted 2019-02-20T17:20:11.813

Reputation: 4 832

0

Stax, 43 bytes

¿⌐cF◄àë+±√¼∙]╔5B\d☺↨m█ewτ─º╞═ó○♣zG-█K↨ÄV┐§x

Run and debug it

recursive

Posted 2019-02-20T17:20:11.813

Reputation: 8 616