Enmarca este bonito arte ASCII

30

Introducción

Creo que todos están de acuerdo en que las buenas fotos deben tener un marco agradable. Pero la mayoría de los desafíos en este sitio sobre ASCII-Art solo quieren la imagen en bruto y no les importa su preservación.
¿No sería bueno si tuviéramos un programa que toma algo de arte ASCII y lo rodea con un marco agradable?

El reto

Escriba un programa que tome algo de ASCII-Art como entrada y salga rodeado de un marco agradable.

Ejemplo:

*****
 ***
  * *
 ***
*****

se convierte

╔═══════╗
║ ***** ║
║ *** ║
║ * ║
║ *** ║
║ ***** ║
╚═══════╝
  • Debe usar exactamente los mismos caracteres para el marco que en el ejemplo: ═ ║ ╔ ╗ ╚ ╝
  • La parte superior e inferior del marco se insertan antes de la primera y después de la última línea de la entrada.
  • Las partes izquierda y derecha del marco deben tener un espacio exacto para la línea más ancha de la entrada.
  • Puede que no haya espacios en blanco iniciales o finales en la salida. Solo se permite una nueva línea final.
  • Puede suponer que la entrada no tiene espacios en blanco iniciales innecesarios.
  • Puede suponer que la entrada no tiene espacios en blanco finales en ninguna línea.
  • No tiene que manejar entradas vacías.
  • La entrada solo contendrá caracteres ASCII imprimibles y líneas nuevas.

Reglas

¡Feliz codificación!

Usando un gran ASCII-Art, que se produjo en cualquier desafío en este sitio, ¡se recomienda encarecidamente la entrada a su programa y mostrarlo con un marco agradable!

Denker
fuente
29
¿Un marco no ASCII para el arte ASCII? ¡Herejía!
Dennis
55
Muy estrechamente relacionado. El mismo desafío, pero solo con un único carácter (ASCII) para el marco.
Martin Ender
13
(Debo aclarar que no creo que sea un engaño. Tener que usar 6 caracteres diferentes hace que esto sea mucho más complicado. El otro desafío se puede resolver girando la cuadrícula y agregando #cuatro veces. Adaptar este enfoque aquí será difícil en el mejor de los casos , y no es viable en el peor.)
Martin Ender
66
@IsmaelMiguel He ganado el concurso anterior y no veo cómo podría adaptar mi respuesta anterior.
Martin Ender
2
Sospecho que DenkerAffe está asumiendo CP437 o algo donde los caracteres del marco también son de un byte.
Joshua

Respuestas:

6

CJam, 45 caracteres / 52 bytes

qN/_z,)[_)'═*N]2*C,3%'╔f+.\4/@@f{Se]'║S@2$N}*

Intentar evitar esos caros caracteres de 3 bytes fue ... interesante.

Pruébalo en línea

Explicación

qN/                   Split input by newline
_z,                   Zip and get length L, i.e. length of longest line
)                     Increment -> L+1
[_)'═*N]              Make two-element array of "═"*(L+2) and newline
2*                    Double the array, giving ["═"*(L+2) "\n" "═"*(L+2) "\n"]

C,                    range(12), i.e. [0 1 2 ... 11]
3%                    Every third element, i.e. [0 3 6 9]
'╔f+                  Add "╔" to each, giving "╔╗╚╝"
.\                    Vectorised swap with the previous array, giving
                      ["╔" "═"*(L+2) "╗" "\n" "╚" "═"*(L+2) "╝" "\n"]
4/                    Split into chunks of length 4

@@                    Move split input and L+1 to top
f{...}                Map with L+1 as extra parameter...
  Se]                   Pad line to length L+1, with spaces
  '║S                   Put "║" and space before it
  2$N                   Put "║" and newline after it

*                     Join, putting the formatted lines between the top and bottom rows
Sp3000
fuente
16

Haskell, 139 bytes

q=length
g x|l<-lines x,m<-maximum$q<$>l,s<-[-1..m]>>"═"='╔':s++"╗\n"++(l>>= \z->"║ "++z++([q z..m]>>" ")++"║\n")++'╚':s++"╝"

Como ejemplo, estoy enmarcando el muñeco de nieve "12333321" .

*Main> putStrLn $ g " _===_\n (O.O)\n/(] [)\\\n ( : )"
╔═════════╗
║  _===_  ║
║  (O.O)  ║
║ /(] [)\ ║
║  ( : )  ║
╚═════════╝

Cómo funciona:

bind
  l: input split into lines
  m: maximum line length
  s: m+2 times ═

build top line
prepend left frame to each line, pad with spaces, append right frame
build bottom line.
nimi
fuente
9

JavaScript (ES6), 138 bytes

Esto es 138 bytes en la codificación IBM866, que en el momento de la escritura todavía es compatible con Firefox, pero 152 en UTF-8.

s=>`╔${t='═'.repeat(w=2+Math.max(...(a=s.split`
`).map(s=>s.length)))}╗
${a.map(s=>('║ '+s+' '.repeat(w)).slice(0,w+1)).join`║
`}║
╚${t}╝`
Neil
fuente
1
¿Puedes codificar Javascript usando CP437 y aún ejecutarlo? Si no, entonces esto no es en realidad 138 bytes.
Mama Fun Roll
@ ӍѲꝆΛҐӍΛПҒЦꝆ Aunque no pude encontrar nada compatible con CP437, Firefox actualmente es compatible con IBM866, que también tiene estos caracteres de dibujo de recuadro, por lo que he actualizado mi respuesta.
Neil
De acuerdo, genial. Tener un voto a favor!
Mama Fun Roll
6

Bash, 173 171 150 148 147 bytes, 157 136 134 133 caracteres

q(){((n=${#2}>n?${#2}:n));};mapfile -tc1 -C q v;for((p=++n+1;p;--p));do z+=═;done;echo ╔$z╗;printf "║ %-${n}s║\n" "${v[@]}";echo ╚$z╝

Multilínea:

q() {
    (( n = ${#2} > n ? ${#2} : n))
}
mapfile -tc1 -C q v

for((p=++n+1;p;--p))
do 
    z+=═
done

echo ╔$z╗
printf "║ %-${n}s║\n" "${v[@]}"
echo ╚$z╝

Ejecución de ejemplo:

bash -c 'q(){((n=${#2}>n?${#2}:n));};mapfile -tc1 -C q v;for((p=++n+1;p;--p));do z+=═;done;echo ╔$z╗;printf "║ %-${n}s║\n" "${v[@]}";echo ╚$z╝'< bear.txt

Ejecución de muestra desde script:

$ cat bear2.txt 
     (()__(()
     /       \
    ( /    \  \
     \ o o    /
     (_()_)__/ \
    / _,==.____ \
   (   |--|      )
   /\_.|__|'-.__/\_
  / (        /     \
  \  \      (      /
   )  '._____)    /
(((____.--(((____/mrf
$ ./frame< bear2.txt 
╔═══════════════════════╗
║      (()__(()         ║
║      /       \        ║
║     ( /    \  \       ║
║      \ o o    /       ║
║      (_()_)__/ \      ║
║     / _,==.____ \     ║
║    (   |--|      )    ║
║    /\_.|__|'-.__/\_   ║
║   / (        /     \  ║
║   \  \      (      /  ║
║    )  '._____)    /   ║
║ (((____.--(((____/mrf ║
╚═══════════════════════╝
Runium
fuente
1
Su ejemplo tiene una línea vacía entre el marco inferior y la entrada que no es válida. Los marcos superior e inferior deben insertarse directamente antes y después de la entrada (su versión anterior estaba bien por cierto).
Denker
1
Bonita !, pero que podrían ahorrar aproximadamente 5 Char si ...?${#2}+2:n))en lugar de +1, la caída de 2 plazas y printf -v z %${n}s;en lugar de printf -v z " %*.s" $n.
F. Hauri
@Sukminder Ok, ya estaba asignando eso, pero quería asegurarme ya que la entrada que muestra no contiene una línea vacía. No exigí que borrara la entrada de líneas vacías iniciales o finales, por lo que su programa está perfectamente bien.
Denker
5

AWK, 159 bytes

{a[NR]=$0
x=length($0)
m=m<x?x:m
a[NR,1]=x}
END{for(;i<m+2;i++)t=t"═"
print"╔"t"╗"
for(j=1;j<NR;j++){f="║ %-"m"s ║\n"
printf f,a[j]}print"╚"t"╝"}

Aparentemente awkpuede imprimir Unicode si puede descubrir cómo obtenerlo en el código.

Robert Benson
fuente
Tengo tantas ideas para pipas increíbles ahora ...
Sebb
@Sebb Eso parece divertido. :)
Robert Benson
5

Perl, 111 caracteres

(la puntuación incluye +5 para las banderas de intérprete)

#!/usr/bin/perl -n0 -aF\n
$n=(sort{$b<=>$a}map length,@F)[0];$l="═"x$n;
print"╔═$l═╗\n",(map{sprintf"║ %-${n}s ║\n",$_}@F),"╚═$l═╝";

Primero, encontramos la longitud de línea más larga $n , ordenando numéricamente las longitudes de todas las líneas.

Establecemos $lser la barra de encabezado / pie de página para ser$n repeticiones del carácter de marco horizontal.

Luego imprimimos cada línea formateada para alinear a la izquierda en un campo de ancho $n , intercalado entre los caracteres del marco.

Resultado:

╔═══════════╗
║   |\_/|   ║
║  / @ @ \  ║
║ ( > * < ) ║
║  `>>x<<'  ║
║  /  O  \  ║
╚═══════════╝
Toby Speight
fuente
4

Pyth, 44 caracteres (58 bytes)

++\╔K*JhheSlR.z\═\╗jbm+\║+.[+;d;J\║.z++\╚K\╝

Explicación

++\╔K*JhheSlR.z\═\╗                          - print out the first line
           lR.z                              -        map(len, all_input())
          S                                  -       sorted(^)
         e                                   -      ^[-1]
       hh                                    -     ^+2
      J                                      -    autoassign J = ^
     *         \═                            -   ^*"═"
    K                                        -  autoassign K = ^
++\╔             \╗                          - imp_print("╔"+^+"╗")

                   jbm+\║+.[+;d;J\║.z        - print out the middle
                   jb                        - "\n".join(V)
                     m             .z        -  [V for d in all_input()]
                      +\║+       \║          -   "║"+V+"║"
                          .[   ;J            -    pad(V, " ", J)
                            +;d              -     " "+d

                                     ++\╚K\╝ - print out the end
                                     ++\╚K\╝ - imp_print("╚"+K+"╝")

Pruébalo aquí.

Azul
fuente
4

PHP 5.3, 209 bytes

Esto solo funciona con la codificación OEM 860 . Es un superconjunto ASCII extendido, usado en versiones portuguesas de DOS. Como soy portugués (y me encantaba hacer estos "marcos" en Pascal) y esta es una codificación estándar, seguí adelante con esto:

<?foreach($W=explode('
',$argv[1])as$v)$M=max($M,strlen($v)+2);printf("É%'Í{$M}s»
º%1\${$M}sº
%2\$s
º%1\${$M}sº
È%1\$'Í{$M}s¼",'',join('
',array_map(function($v)use($M){return str_pad(" $v ",$M);},$W)));

Aquí está la base64:

PD9mb3JlYWNoKCRXPWV4cGxvZGUoJwonLCRhcmd2WzFdKWFzJHYpJE09bWF4KCRNLHN0cmxlbigkdikrMik7cHJpbnRmKCLilZQlJ+KVkHskTX1z4pWXCuKVkSUxXCR7JE19c+KVkQolMlwkcwrilZElMVwkeyRNfXPilZEK4pWaJTFcJCfilZB7JE19c+KVnSIsJycsam9pbignCicsYXJyYXlfbWFwKGZ1bmN0aW9uKCR2KXVzZSgkTSl7cmV0dXJuIHN0cl9wYWQoIiAkdiAiLCRNKTt9LCRXKSkpOw==

Esta respuesta se basó en mi respuesta en: https://codegolf.stackexchange.com/a/57883/14732 (todo el trabajo pesado se hizo allí, solo tuve que moverme un poco).

Ismael Miguel
fuente
Impresionante por decir lo menos :)
MonkeyZeus
Los códigos son 209 bytes / caracteres. 22+58+11+5+11+24+66+12=209Los últimos 12 son líneas nuevas y, como es DOS, significa CRLF, o dos bytes por línea nueva. El sitio charactercountonline no cuenta nuevas líneas. Cada uno de los glifos no ASCII tiene 1 byte en OEM 860.
Runium
@Sukminder No olvide que (al menos) Windows se convierte \nen\r\n , al abrir el archivo en modo ASCII / texto.
Ismael Miguel
2

Python 3, 119 bytes

def f(x): 
 n='\n';s="║ ";e=" ║";h=(x.find(n)+2)*"═";return"╔"+h+"╗"+n+s+x.replace(n,e+n+s)+e+n+"╚"+h+"╝"

126 bytes

import sys
o=["║ %s ║\n"%j[:-1] for j in sys.stdin]
h="═"*(len(o[0])-3)
print("╔"+h+"╗\n"+"".join(o)+"╚"+h+"╝")

Entrada:

hello
there
  !  

Salida:

╔═══════╗
 hello 
 there 
   !   
╚═══════╝
SumnerHayes
fuente
¡Bienvenido a Progamming Puzzles & Code Golf! Buena primera respuesta! Siempre puede escribir funciones en lugar de programas completos (a menos que esté explícitamente prohibido en el desafío) que podrían permitirle guardar algunos bytes tomando la entrada como argumento. También es posible que desee utilizar Python 2, por lo que puede guardar 2 bytes yendo con print"╔"+h+"╗\n"+"".join(o)+"╚"+h+"╝".
Denker
Gracias. No pude descubrir cómo hacer que los bytes altos funcionen en Python2 (probablemente establecer la variable de entorno del códec funcionaría, pero no estoy seguro de cómo se juega en el conteo de bytes de golf). El enfoque de la función elimina las diferencias de python2 / 3 pero agrega un byte en mi mejor enfoque.
SumnerHayes
Bien, lo reduje a 119 caracteres como una función; toma la entrada como una cadena. Mi mini-markdown obviamente no está a la altura; La línea 1 es la definición, el resto (después del colon) es la línea 2, con un espacio inicial. def f(x): n='\n';s="║ ";e=" ║";h=(x.find(n)+2)*"═";return"╔"+h+"╗"+n+s+x.replace(n,e+n+s)+e+n+"╚"+h+"╝"
SumnerHayes
Simplemente actualice su publicación con la nueva versión y la nueva puntuación (eliminé la puntuación anterior con <s>...</s>). También puede agregar <!-- language-all: lang-python -->antes de su bloque de código para agregar resaltado de sintaxis a su código.
Denker
Esto no funciona si la entrada no es rectangular, mientras que la pregunta dice que ninguna línea tendrá espacios en blanco al final.
Dennis
2

Python 2, 115 bytes

def f(i):w='═'*(i.find('\n')+2);return'╔%s╗\n║ %s ║\n╚%s╝'%(w,' ║\n║ '.join(i.split('\n')),w)

Parece más corto que 115 aquí, pero el archivo de trabajo incluye la firma de la marca BOM UTF-8 de 3 bytes, aumentando hasta 115 bytes. Si lo ejecutara en Python 3, no necesitaría la lista de materiales y se reduciría a 112 bytes.

Jenny Miller
fuente
¡Bienvenido a Programming Puzzles & Code Golf! Desafortunadamente, su código parece suponer que la entrada es rectangular, mientras que la pregunta dice que ninguna línea tendrá espacios en blanco al final.
Dennis
Cuento 107 bytes. No creo que deba incluir la "firma de marca UTF-8 BOM".
CalculatorFeline
@CatsAreFluffy ¿Estás usando Python2? En Python3 todas las cadenas son unicode, pero es más complicado con Python2.
Jenny Miller
Vaya, conté las tuberías como 2 bytes, pero incluso después de usar un contador de bytes real, todavía solo 111 bytes. Dime de dónde provienen esos 5 bytes.
CalculatorFeline
La lista de materiales UTF-8 es de 3 bytes ( en.wikipedia.org/wiki/Byte_order_mark ). Mi recuento fue uno alto porque mi editor de texto estaba agregando una nueva línea final, por lo que mi solución es realmente solo 115 bytes. Puede dejar de lado los bytes BOM iniciales y bajarlo a 112 si estaba usando Python3 (que cuenta todas las cadenas como unicode). Pero no sé cómo estás viendo solo 111 bytes. por cierto, así es como agregué la lista de materiales: sed -i '1s/^\(\xef\xbb\xbf\)\?/\xef\xbb\xbf/' codeGolf.py
Jenny Miller
1

C, 290 bytes

Función de golf B, con dependencias; toma la entrada como char terminado en nulo *

#define l(s) strlen(s)
p(char*s,int n){while(n--)printf(s);}
B(char*s){char*t=strtok(s,"\n");int x=l(t),z=1;while(t=strtok(0,"\n"))z++,x=l(t)>x?l(t):x;p("╔",1);p("=",x+2);p("╗\n",1);while(z--)printf("║ %s", s),p(" ",x-l(s)),p(" ║\n",1),s+=l(s)+1;p("╚",1);p("=",x+2);p("╝\n",1);}

Función un poco descuidada en el programa completo

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 1024

// GOLF-BEGIN =>
#define l(s) strlen(s)
// since multibyte chars don't fit in char: use char* instead
void p (char*s,int n){ while(n--)printf(s); } 
void B (char *s){
    char *t = strtok(s,"\n");
    int x=l(t), z=1;
    while(t=strtok(0,"\n"))z++,x=l(t)>x?l(t):x;  
    // x is l(longest line), z is #lines
    p("╔",1);p("=",x+2);p("╗\n",1);
    while(z--)printf("║ %s", s),p(" ",x-l(s)),p(" ║\n",1),s+=l(s)+1;
    p("╚",1);p("=",x+2);p("╝\n",1);       
}
// <= GOLF-END

int main(int argc, char **argv) {
    char buffer[MAX];
    memset(buffer, 0, MAX);
    FILE *f = fopen(argv[1], "rb");
    fread(buffer, 1, MAX, f); 
    B(buffer);
    return 0;
}

entrada

     _.,----,._
   .:'        `:.
 .'              `.
.'                `.
:                  :
`    .'`':'`'`/    '
 `.   \  |   /   ,'
   \   \ |  /   /
    `\_..,,.._/'
     {`'-,_`'-}
     {`'-,_`'-}
     {`'-,_`'-}
      `YXXXXY'
        ~^^~

salida

╔======================╗
║      _.,----,._      ║
║    .:'        `:.    ║
║  .'              `.  ║
║ .'                `. ║
║ :                  : ║
║ `    .'`':'`'`/    ' ║
║  `.   \  |   /   ,'  ║
║    \   \ |  /   /    ║
║     `\_..,,.._/'     ║
║      {`'-,_`'-}      ║
║      {`'-,_`'-}      ║
║      {`'-,_`'-}      ║
║       `YXXXXY'       ║
║         ~^^~         ║
╚======================╝

C consejos de golf apreciados!

tucuxi
fuente