33
\$\begingroup\$

We're getting markdown tables! I assume this is what they look like:

 data
 data data data
---------------------
 | |
 | |
 | |
 | |

Your task is to make a program or function to generate one of these tables. You'll be given input (string, list of lines, list of characters, etc.) containing data, which looks like this:

datadata
 data
 data data
data data data

The data consists of spaces and non-overlapping datas. The data will not necessarily form neat stacks (it can float in midair). There is guaranteed to be data on the top and bottom lines, as well as some touching the left side. You can choose if the data is right padded with spaces or not.

The table will always be six characters wider than the data, padded three spaces on the left. The table top is directly below the bottom row of data, and is made up of a line of -s.

As for the legs, everyone knows taller tables can support more weight, so they'll need to be one unit tall for every data in the input. They will be made up of |s, one space in from the sides.

This is , so shortest answer in bytes per language wins!

Test cases

Input:

data

Output:

 data
----------
 | |

Input:

data data data
 data data data

Output:

 data data data
 data data data
---------------------
 | |
 | |
 | |
 | |
 | |
 | |

Input:

data
data

Output:

 data
 
 data
----------
 | |
 | |
asked Dec 4, 2020 at 4:44
\$\endgroup\$
10
  • 2
    \$\begingroup\$ May input contains extra spaces? For example " data ", "data \n data". \$\endgroup\$ Commented Dec 4, 2020 at 6:36
  • 2
    \$\begingroup\$ To be clear: we're outputting the input unchanged with the table as defined underneath it? \$\endgroup\$ Commented Dec 4, 2020 at 9:29
  • 1
    \$\begingroup\$ Some doubts: 1) Can we return just the "table string" from function and print the data-string using footer code? 2) @Shaggy - I think input must have to change as output has 3 spaces left-padding on every row! \$\endgroup\$ Commented Dec 4, 2020 at 9:51
  • 1
    \$\begingroup\$ Don't know about linking to testcase, I wrote and posted my answer before following the link and didn't fully understand the challenge until I saw the extra testcases. For clarity it's best to make them a part of the post. \$\endgroup\$ Commented Dec 4, 2020 at 11:45
  • 1
    \$\begingroup\$ @tsh The data is guaranteed to be touching the left side, the the first example wouldn't occur. You can choose how the right padding works, so you don't have to handle the second example you gave. \$\endgroup\$ Commented Dec 4, 2020 at 13:23

16 Answers 16

10
\$\begingroup\$

Perl 5 -lpF, (削除) 88 (削除ここまで) (削除) 74 (削除ここまで) 66 bytes

Because we're allowed to require the input to be padded on the right side, @DomHastings was able to shave 8 bytes off my method while eliminating the need for List::Util.

END{printf'-'x(@F+6)."
 |%@{[@F+3]}s"x$q,("|")x$q}s// /;$q+=y;d;

Try it online!

answered Dec 4, 2020 at 7:26
\$\endgroup\$
1
  • 1
    \$\begingroup\$ +1. You can save 8 bytes if you have right-padded input and use -F too! Try it online! \$\endgroup\$ Commented Dec 4, 2020 at 13:36
6
\$\begingroup\$

05AB1E, (削除) 31 (削除ここまで) (削除) 30 (削除ここまで) 28 bytes

¬g×ばつa×ばつ'|1®Í‚ǝIJ'd¢и«.c

-1 byte thanks to @ovs.

Input as a list of lines, right-padded with spaces to an equal length.

Try it online or verify all test cases.

Explanation:

¬ # Get the first line of the (implicit) input-list (without popping)
 g # Pop and push its length
 6+ # Add 6
 © # Store this value in variable `®` (without popping)
 ×ばつ '# Pop and create a string of that many "-"
 a # Append it to the list of lines×ばつ # Create a string consisting of `®` amount of spaces
 1 # Push 1
 ®Í # Push value `®` and decrease it by 2
 ‚ # Pair them together: [1,®-2]
 '| ǝ '# Insert a "|" at those (0-based) indices in the spaces-string
 IJ # Push the input-list, and join it to a single string
 'd¢ '# Count the amount of "d"s in it
 и # Repeat the legs-string that many times as list
 « # And merge the two lists together
.c # And finally centralize this list, which adds leading spaces where
 # necessary, and implicitly joins the list by newlines
 # (after which the result is output implicitly)
answered Dec 4, 2020 at 8:14
\$\endgroup\$
3
  • \$\begingroup\$ 30 bytes with manual printing. \$\endgroup\$ Commented Dec 4, 2020 at 9:19
  • \$\begingroup\$ Could you save anything by right padding the input with spaces so you'd just have to get the length of one line instead of the max length of all lines? \$\endgroup\$ Commented Dec 4, 2020 at 11:18
  • \$\begingroup\$ @Shaggy Thanks indirectly. 05AB1E doesn't really have any convenient builtins for right-padding unfortunately, except maybe the box builtin .B (split string by newlines, and pad trailing spaces so all strings are the same length). Not really useful directly with my current approach, but in combination with the .c (centralize) builtin, it does save a byte in the end. AND, because taking the input already right-padded is allowed in the rules, an additional byte can be saved by just dropping the .B. \$\endgroup\$ Commented Dec 4, 2020 at 11:58
5
\$\begingroup\$

APL (Dyalog Unicode), (削除) 60 57 56 55 (削除ここまで) 41 bytes

{3⌽↑(↓'-'⍪⍨' '∘,⍣6⊢⍵),↓(+/∊'d'⍷⍵)6⍴' | '}

Try it online!

Input as a character matrix.

-1 byte from ovs.

-14 bytes, following xash's answer.

Explanation(old)

{↑(' '∘, ̈↓⍵),(⊂a/'-'),(+/∊'d'⍷⍵)/⊂2⌽'| |'↑⍨a←6+⊃⌽⍴⍵}
 '| |' a set of table legs
 ↑⍨ pad to length
 a←6+⊃⌽⍴⍵ 6 + row size
 a← store in var a
 ⊂2⌽ rotate 2 steps and wrap
 ( )/ replicate that by:
 'd'⍷⍵ boolean matrix of occurrences of 'data' 
 +/∊ sum all the occurrences
 , concatenate with
 (⊂a/'-') '-' repeated a times
 (' '∘, ̈↓⍵), and the input padded with 3 spaces on the left
 ↑ convert to matrix(join with newlines)
answered Dec 4, 2020 at 7:34
\$\endgroup\$
0
4
\$\begingroup\$

Japt, (削除) 30 (削除ここまで) (削除) 28 (削除ここまで) 27 bytes

Hmm ... thought this would work out much shorter.

Takes input as an array of lines, right-padded with spaces and outputs an array of lines.

cU¬èd ô@S+i|i|úUÎÊ+3ÃvÈç-
û

Try it or run all test cases

cU¬èd ô@S+i|i|úUÎÊ+3ÃvÈç-\nû :Implicit input of array U
c :Concatenate
 U¬ : Join U
 èd : Count the "d"s
 ô : Range [0,count]
 @ : Map
 S : Space
 + : Append
 i : A space prepended with
 |i : A "|" prepended with
 |ú : A "|" right padded with spaces to length
 UÎÊ+3 : Length of first element of U plus 3
 Ã :End map
 v :Modify first element
 È :By passing it through the following function
 ç- : Fill with "-"
 \n :Reassign to U (saves a byte over having to close all the nested methods)
 û :Centre pad each element with spaces to the length of the longest
answered Dec 4, 2020 at 11:06
\$\endgroup\$
4
\$\begingroup\$

J, 41 bytes

0 3|.(' | '$~6,~1#.'d'=,),~'-',~' '&,.^:6

Try it online!

How it works

  • ' '&,.^:6 prepend a space to each row 6 times.
  • '-',~ append a new row filled with -.
  • 1#.'d'=, count the ds in the input.
  • ' | '$~6,~ shape | into dimensions count 6, so count rows of | |
  • ,~ append the leg rows to the tables, filling possible empty space on the right with .
  • 0 3|. shift every row 3 characters to the left.

Or in pictures:

data
 data
 data
----------
 data
----------
 | |
 data 
-----------
 | |
answered Dec 4, 2020 at 13:31
\$\endgroup\$
4
\$\begingroup\$

Ruby 2.7, (削除) 112 (削除ここまで) (削除) 98 (削除ここまで) (削除) 77 (削除ここまで) 74 bytes

Saved 6 bytes using String#count method, thanks to Razetime!
Saved 3 bytes using literal newline, thanks to Dingus!

->m{m.map{" "*3+_1}<<?-*(6+c=m[0].size)+"
 | #{" "*c} |"*(m*"").count(?d)}

Try it online!

  • TIO uses an older version of Ruby, while in Ruby 2.7, we've numbered parameters, i.e., _1, which saves 2 bytes.
answered Dec 4, 2020 at 8:54
\$\endgroup\$
3
  • 1
    \$\begingroup\$ -6, just counting d \$\endgroup\$ Commented Dec 4, 2020 at 9:22
  • 1
    \$\begingroup\$ -3 bytes with a literal newline, two literal spaces, and some rearrangement to avoid shouty map!. (I also simplified the footer a bit.) \$\endgroup\$ Commented Dec 4, 2020 at 11:28
  • \$\begingroup\$ @Dingus - I was trying newline in %[], didn't knew it works inside "" too! \$\endgroup\$ Commented Dec 4, 2020 at 13:36
3
\$\begingroup\$

Python 3.8, (削除) 113 (削除ここまで) (削除) 107 (削除ここまで) 95 bytes

Saved (削除) 6 (削除ここまで) a whopping 18 bytes thanks to Dom Hastings!!!

lambda l:[' '+a for a in l]+[(r:=6+len(l[0]))*'-']+''.join(l).count('d')*[' |'+(r-4)*' '+'|']

Try it online!

Inputs a list of right-space-padded strings and returns a list of strings.

answered Dec 4, 2020 at 11:36
\$\endgroup\$
3
  • 1
    \$\begingroup\$ +1 You can use len(a) instead of a.rfind('a') for -6 too! Try it online! \$\endgroup\$ Commented Dec 4, 2020 at 13:11
  • \$\begingroup\$ @DomHastings That's great and just realised I can require right padding for additional saves - thanks! :D \$\endgroup\$ Commented Dec 4, 2020 at 13:17
  • \$\begingroup\$ Oh yeah, that's even easier then: len(l[0]) and saves me 8 bytes in my answer, thanks! \$\endgroup\$ Commented Dec 4, 2020 at 13:28
3
\$\begingroup\$

Jelly, 36 bytes

Ỵ6x3¤;ṄƊ€ẈṀ+©3"-xṄṛċ"d®e®’,2¤\þị)| Y

Try it online!

Takes input as a single string.

This is disgustingly hacked together, but Jelly's never been particularly good at strings.

How it works

Ỵ6x3¤;ṄƊ€ẈṀ+©3"-xṄṛċ"d®e®’,2¤\þị)| Y - Main link. Takes s on the left
Ỵ - Split into a list of lines
 Ɗ€ - Over each line l:
 ¤ - Group together as a nilad:
 6 - " "
 x3 - [" ", " ", " "]
 ; - Prepend to l
 Ṅ - Print
 Ẉ - Get the lengths of each line
 Ṁ - Take the maximum
 + 3 - Add 3
 © - Save it to the register, r
 "- - "-"
 x - Repeat that many times
 Ṅ - Print
 ṛ - Discard everything and use s
 ċ"d - Count occurrences of "d", d
 ® - Yield the register, r
 \þ - Create an d×ばつr grid and to each cell (i, j):
 ¤ - Group into a nilad:
 ® - r
 ’ - r-1
 2 - 2
 , - [r-1, 2]
 e - Is i in [r-1, 2]?
 ị)| - Index each cell into "| "
 Y - Join by newlines
answered Dec 4, 2020 at 14:13
\$\endgroup\$
3
\$\begingroup\$

Charcoal, (削除) 29 (削除ここまで) 25 bytes

WS⊞υι↑NoΣυdM←3Lθ←Fυ↑‖OOLθυ

Try it online! Link is to verbose version of code. Takes newline-terminated rectangular input. Explanation:

WS⊞υι

Input the data.

↑NoΣυdM←3

Print the left leg and the --- at the top of the left leg.

Print the middle part of the table.

←Fυ↑

Move the cursor to the top right of the data. The following reflection will then move it to the top left. (Moving here avoids confusion between the use of the arrows as movement and as modifiers for reflection or printing direction.)

‖OOLθ

Reflect to complete the right of the table.

υ

Print the data.

answered Dec 4, 2020 at 10:27
\$\endgroup\$
4
  • \$\begingroup\$ Hm.. you'd also misinterpreted the question statement (like me :P). Actually, it says to print n amount of legs, where n is number of times "data" appears in that multiline string/matrix. \$\endgroup\$ Commented Dec 4, 2020 at 10:35
  • \$\begingroup\$ @vrintle Thanks, I always seem to overlook something... \$\endgroup\$ Commented Dec 4, 2020 at 10:43
  • \$\begingroup\$ Japt should not be beating Charcoal in a challenge like this; try harder! :p \$\endgroup\$ Commented Dec 4, 2020 at 23:58
  • \$\begingroup\$ @Shaggy Yeah, I just spotted a trivial 4-byte saving without even trying... \$\endgroup\$ Commented Dec 5, 2020 at 0:12
3
\$\begingroup\$

C (gcc), (削除) 204 (削除ここまで) (削除) 194 (削除ここまで) (削除) 187 (削除ここまで) (削除) 181 (削除ここまで) 174 bytes

174-byte solution thanks to @ceilingcat.

z,s,i;main(c,v)char**v;{for(;++z<c;)printf(" %s\n",v[z]);for(;c--;)for(s=0;z=v[c][s++];)i+=z=='d';for(;z++<strlen(v[1])+6;putchar(45));for(;i--;)printf("\n |%*c",z-4,'|');}

Try it online!

Takes each line of input as a right-padded command line argument.

answered Dec 4, 2020 at 16:55
\$\endgroup\$
0
2
\$\begingroup\$

Retina, 53 bytes

\`.+
 $& 
L$`d
$%=
T`p`-
*0円G`
T`-` 
%,T1,,-2` `|

Try it online! Takes rectangular input. Explanation:

\`.+
 $& 

Pad the input by 3 spaces on each side and print the result.

L$`d
$%=

Repeat each line by the count of its ds.

T`p`-

Change all the characters to -s.

*0円G`

Print the first line.

T`-` 

Change all the characters to spaces.

%,T1,,-2` `|

Change the (0-indexed) second and second last characters to |s and implicitly print the resulting legs.

answered Dec 4, 2020 at 10:47
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6), (削除) 105 (削除ここまで) 103 bytes

Expects a single string with right-padded lines.

s=>s[R='replace'](/^|t/g,c=>o+=`
`+(p=c?' | ':'---')+q[R](/./g,p[0])+p,o=s[R](/.+/g,s=>' '+(q=s)))&&o

Try it online!

Commented

s => // s = input string
s[R = 'replace']( // replace in s:
 /^|t/g, // match the beginning of the string
 // and each 't' (of 'data')
 c => // for each matching character c:
 o += // append to o:
 `\n` + ( // a line-feed
 p = // followed by p defined as:
 c ? // if c is not empty:
 ' | ' // ' | '
 : // else:
 '---' // '---'
 ) //
 + q[R](/./g, // followed by each character in q ...
 p[0]) // ... replaced with the 1st character of p
 + p, // followed by p
 o = // initialize the output string o:
 s[R]( // replace in s:
 /.+/g, s => // each line s
 ' ' // with 3 leading spaces
 + (q = s) // followed by s, which is copied in q
 ) // end of replace()
) && o // end of replace(); return o
answered Dec 4, 2020 at 12:06
\$\endgroup\$
1
\$\begingroup\$

Jelly, 38 bytes

Ỵ6x3¤;Ɱ©ẈṀ+3μ6ẋ"|2,-¦Wẋ3ċ"d¤;@"-xWƊ®;Y

Try it online!

answered Dec 4, 2020 at 14:12
\$\endgroup\$
1
\$\begingroup\$

Perl 5 + -pl055F, 53 bytes

A different approach to @Xcali's answer. Requires lines to be padded with spaces.

$;+=y/d//;say" $_"}{$\=$\x(6+($#x=@F))."
 | @x |"x$

Try it online!

Explanation

Firstly, -l055 sets $\ to '-', -p implicitly wraps wraps the code in while(<STDIN>){...;print;} and -F splits each line of input into chars in @F.

In the code, due to the implicit code added by -p, for each line of text increment $; with the number of d in the code then say the line with three leading spaces. The }{ breaks out of the implicit while and $\ is then set to $\ repeated 6+@F (whilst also setting $#x to @F's scalar value) times concatenated with a string consisting of: a leading newline, space, pipe (|), space, @x interpolated, space, pipe, which itself it repeated $; times.

@F, when used in a scalar context like this, returns the number of elements in @F - which is the number of chars in the line, since each line is space-padded this works fine. $#x is a 'magic' variable which contains the last index of @x and means that @x now contains @F+1 empty values. When an array is interpolated into a double-quoted string, its values are printed out with a space between each, so an empty array with @F+1 elements interpolated, results in a string consisting of @F spaces. This code ends with just $ because of the -p-added code which contains ; saving another byte.

answered Dec 4, 2020 at 13:25
\$\endgroup\$
1
\$\begingroup\$

Vyxal ao, 34 bytes

ƛ3Ip...L;G:3+\-*,‹‛ƛ↓しろいしかく⁋ẎL$I‛ |p‛|
+*

Try it Online! Probably not optimal, but beats Jelly :P

a flag is for multiline input; o forces implicit output even though there are print statements in the code.

ƛ3Ip...L;G:3+\-*,‹‛ƛ↓しろいしかく⁋ẎL$I‛ |p‛|
+* # Full program
ƛ ; # For each line in input (`a` flag):
 3Ip # Prepend 3 spaces
 ... # Print ^
 L # and return its length
G: # Take the maximum length from ^ and duplicate
 3+ # Add 3 to one copy
 \-*, # Print that many `-`s
 ‹ # Decrement the other maximum length copy for later
 しろいしかく⁋ # From inputs...
 ẎL # ...find the number of
 ‛ƛ↓ # ...`data`s (dictionary-compressed)
 $ # Swap number of "data"s for (maximum length - 1)
 I # Push that many spaces
 ‛ |p # Prepend " |" to ^
 ‛|\n+ # Append "|\n" to ^ (\n is an actual newline)
 * # Repeat as many times as the number of datas to make the legs
 # `o` flag - implicitly output the legs of the table
answered Dec 7, 2021 at 0:29
\$\endgroup\$
0
\$\begingroup\$

Pip, 36 bytes

P'-M@P*gWRsX3LXW*4N JgPsX#a+2WR'|WRs

Takes lines of input as command-line arguments; or, with the -r flag, as lines of stdin. Lines must be padded with spaces to the same length. Try it online!

Explanation

Let's break this into two halves: the data + tabletop, and the legs.

P'-M@P*gWRsX3
 g List of input lines
 WR Wrap each line in
 sX3 Three spaces
 P* Print each line
 @ Take the first one
 '-M List containing one hyphen for each character in that line
P Print (concatenated together by default)
LXW*4N JgPsX#a+2WR'|WRs
 Jg Join the lines of input into one string
 N Count occurrences in that string of
 XW Regex matching [a-zA-Z0-9]
 *4 repeated 4 times
L Loop that many times:
 a First line of input
 # Length
 +2 Plus 2
 sX String of that many spaces
 WR'| Wrap in pipe characters
 WRs Wrap in spaces
 P Print
answered Dec 3, 2021 at 22:45
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.