Desenhar uma tabela de saída SQL

12

Tenho certeza que a maioria de nós já viu resultados SQL em um terminal, todos ordenadamente formatados em linhas e colunas. Se você não tiver, aqui está um exemplo:

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

Seu objetivo para esse desafio é, considerando as colunas e os dados da linha de uma tabela, desenhe a tabela nesse estilo. Deve haver uma linha horizontal na parte superior e inferior da tabela e uma logo abaixo da linha do cabeçalho. Deve haver linhas verticais entre todas as colunas e uma nos dois lados da tabela. Você deve usar tubos para linhas verticais, hífens para linhas horizontais e pontos positivos para onde eles se cruzam.

Específicos:

  • Os dados podem ser inseridos via stdin ou como argumento para uma função, mas devem estar em alguma forma de string
  • Os dados devem ser divididos pelo delimitador de string ;
  • Os dados consistirão apenas em caracteres ASCII, não serão citados e não conterão o delimitador.
  • A primeira linha dos dados será usada para cabeçalhos de coluna
  • Os dados sempre terão o mesmo número de colunas
  • A entrada sempre conterá pelo menos duas linhas (um cabeçalho, um dado). Você não precisa lidar com conjuntos vazios.
  • Uma nova linha à direita ou anterior é permitida
  • Cada coluna deve ter a largura do elemento mais largo, preenchendo os elementos mais curtos à direita (bônus -5% se você digitar números à esquerda)
  • Deve haver 1 espaço de preenchimento antes e depois dos cabeçalhos e dados, exceto quando a coluna for mais larga
  • Você não tem permissão para usar o mysqlprograma real para gerar a tabela
  • Aplicam-se brechas padrão

Entrada de amostra:

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

Resultado

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

Pontuação:

O menor número de bytes vence, é claro. Bônus de -5% para números de preenchimento à esquerda (veja detalhes).

Glenn Smith
fonte
Existem limites de tempo no tempo de execução do programa?
Downgoat 12/09/15
Não; demore o tempo que quiser, contanto que realmente termine.
Glenn Smith
1
Qual deve ser a saída se houver apenas uma linha de entrada?
Zgarb 12/09/2015
Você pode assumir que sempre haverá pelo menos duas linhas de entrada. O MySQL nem exibe uma tabela para um conjunto vazio; você também não precisa.
Glenn Smith

Respostas:

2

CJam, 67 58 bytes

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

Experimente on-line no intérprete CJam .

Dennis
fonte
2

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

Por ser o ES6, esta demonstração funciona no Firefox e Edge no momento. Por algum motivo, ele não funciona no Chrome / Opera, mesmo com os recursos experimentais de JavaScript ativados.

// 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>

rink.attendant.6
fonte