12
\$\begingroup\$

I'm sure most of us have seen SQL results in a terminal, all neatly formatted into rows and columns. If you haven't, here's an example:

+----------+-----------+----------------+
| column 1 | column 2  | column 3       |
+----------+-----------+----------------+
| data     | more data | even more data |
| etc      | just goes | on and on      |
+----------+-----------+----------------+

Your goal for this challenge is, given the columns and row data for a table, draw the table in this style. There should be a horizontal line at the top and bottom of the table, and one right below the header row. There should be vertical lines between every column, and one on both sides of the table. You should use pipes for vertical lines, hyphens for horizontal lines, and plusses for where they intersect.

Specifics:

  • The data can be entered via stdin, or as the argument to a function, but it must be in some form of string
  • The data should be split by the string delimiter ;
  • The data will consist of only ASCII characters, is not quoted, and will not contain the delimiter.
  • The first row of the data will be used for column headers
  • The data will always have the same number of columns
  • The input will always contain at least two rows (one header, one data). You do not have to handle empty sets.
  • A trailing or preceding newline is permitted
  • Each column should be as wide as the widest element, padding shorter elements on the right (bonus -5% if you pad numbers on the left)
  • There should be 1 space of padding before and after the headers and data, except when the column is wider
  • You are not allowed to use the actual mysql program to generate the table
  • Standard loopholes apply

Sample Input:

column 1;column 2;column 3
hello;world;test
longer data;foo;bar

Output

+-------------+----------+----------+
| column 1    | column 2 | column 3 |
+-------------+----------+----------+
| hello       | world    | test     |
| longer data | foo      | bar      |
+-------------+----------+----------+

Scoring:

Lowest number of bytes wins, of course. -5% bonus for padding numbers on the left (see specifics).

\$\endgroup\$
4
  • \$\begingroup\$ Are they any time limits on the program run time? \$\endgroup\$
    – Downgoat
    Commented Sep 12, 2015 at 4:39
  • \$\begingroup\$ Nope; take as long as you want, as long as it actually finishes. \$\endgroup\$ Commented Sep 12, 2015 at 4:55
  • 1
    \$\begingroup\$ What should the output be if there's only one row of input? \$\endgroup\$
    – Zgarb
    Commented Sep 12, 2015 at 15:53
  • \$\begingroup\$ You can assume that there will always be at least two rows of input. MySQL doesn't even display a table for an empty set; you don't have to either. \$\endgroup\$ Commented Sep 12, 2015 at 17:18

2 Answers 2

2
\$\begingroup\$

CJam, 67 58 bytes

' qN/';f/ff+z_.{[z,):TS*'|+f.e|T'-*'++:T\(T@~T]}z{s_W=\N}/

Try it online in the CJam interpreter.

\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6), 262 bytes

f=x=>{w=[],o=z=>y(`| ${z[m]((c,i)=>(c+' '.repeat(w[i]-c.length))).join` | `} |`),(d=x.split`
`[m='map'](r=>r.split`;`))[m](r=>r[m]((c,i)=>w[i]=Math.max(c.length,w[i]||0)));(y=console.log)(s=`+${w[m](c=>'-'.repeat(c+2)).join`+`}+`);o(d.shift());y(s);d[m](o);y(s)}

Demo

Since it is ES6, this demo works in Firefox and Edge at this time. For some reason it does not work in Chrome/Opera even with experimental JavaScript features enabled.

// Snippet stuff
console.log = x => document.getElementsByTagName('output')[0].innerHTML += x + '\n';
document.getElementsByTagName('button')[0].addEventListener('click', () => {
  f(document.getElementById('I').value);
});


// Actual code
f = x => {
  w = [], o = z => y(`| ${z[m]((c,i)=>(c+' '.repeat(w[i]-c.length))).join` | `} |`), (d = x.split `
` [m = 'map'](r => r.split `;`))[m](r => r[m]((c, i) => w[i] = Math.max(c.length, w[i] || 0)));
  (y = console.log)(s = `+${w[m](c=>'-'.repeat(c+2)).join`+`}+`);
  o(d.shift());
  y(s);
  d[m](o);
  y(s)
}
<p>
  <textarea id=I cols=80 rows=15>column 1;column 2;column 3
hello;world;test
longer data;foo;bar</textarea>
</p>
<button type=button>Go</button>
<pre><output></output></pre>

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.