이 멋진 ASCII 예술 프레임


30

소개

좋은 사진에는 멋진 프레임이 있어야한다는 데 모두가 동의한다고 생각합니다. 그러나 ASCII-Art에 대한이 사이트의 대부분의 문제는 단지 원시 그림을 원하고 보존에 대해서는 신경 쓰지 않습니다.
ASCII-Art를 가지고 멋진 프레임으로 둘러싼 프로그램이 있다면 좋지 않을까요?

도전

ASCII 아트를 입력으로 사용하여 멋진 프레임으로 둘러싸인 프로그램을 작성하십시오.

예:

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

된다

╔ ======== ╗
║ ***** ║
*** *** ║
║ * ║
*** *** ║
║ ***** ║
╚ ======== ╝
  • 예와 같이 프레임에 정확히 동일한 문자를 사용해야합니다. ═ ║ ╔ ╗ ╚ ╝
  • 프레임의 상단과 하단이 입력의 첫 번째 줄과 마지막 줄 앞에 삽입됩니다.
  • 프레임의 왼쪽과 오른쪽 부분은 입력의 가장 넓은 라인에 정확히 하나의 공간 패딩이 있어야합니다.
  • 출력에 선행 또는 후행 공백이 없을 수 있습니다. 후행 줄 바꿈 만 허용됩니다.
  • 입력에 불필요한 선행 공백이 없다고 가정 할 수 있습니다.
  • 입력에 줄에 공백이없는 것으로 가정 할 수 있습니다.
  • 빈 입력을 처리 할 필요가 없습니다.
  • 입력은 인쇄 가능한 ASCII 문자와 줄 바꿈 만 포함합니다.

규칙

  • 기능 또는 전체 프로그램이 허용됩니다.
  • 입 / 출력의 기본 규칙 .
  • 표준 허점이 적용됩니다.
  • 이것은 이므로 바이트 수가 가장 적습니다. Tiebreaker는 이전에 제출되었습니다.

행복한 코딩!

귀하의 프로그램에 대한 입력으로 멋진 ASCII 프레임을 사용하는 것이 좋습니다!


29
A non-ASCII frame for ASCII art? Heresy!
Dennis

5
Very closely related. Same challenge, but only using a single (ASCII) character for the frame.
Martin Ender

13
(I should clarify I don't think it's a dupe. Having to use 6 different characters makes this a lot trickier. The other challenge can be solved by rotating the grid and appending # four times. Adapting such an approach here will be tricky at best, and not viable at worst.)
Martin Ender

6
@IsmaelMiguel I have won the previous contest and don't see how I could adapt my old answer at all.
Martin Ender

2
I suspect that DenkerAffe is assuming CP437 or something where the frame chars are also one byte.
Joshua

답변:


6

CJam, 45 chars / 52 bytes

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

Trying to avoid those expensive 3-byte chars was... interesting.

Try it online

Explanation

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

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++"╝"

As an example I'm framing snowman "12333321".

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

How it works:

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.

9

JavaScript (ES6), 138 bytes

This is 138 bytes in the IBM866 encoding, which at time of writing is still supported in Firefox, but 152 in 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}╝`

1
Can you actually encode Javascript using CP437 and still run it? If not, then this isn't actually 138 bytes.
Mama Fun Roll

@ӍѲꝆΛҐӍΛПҒЦꝆ Although I couldn't find anything supporting CP437, Firefox currently supports IBM866 which also has these box drawing characters, so I've updated my answer.
Neil

Okay, cool. Have an upvote!
Mama Fun Roll

6

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

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╝

Multiline:

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╝

Example execution:

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

Sample run from script:

$ cat bear2.txt 
     (()__(()
     /       \
    ( /    \  \
     \ o o    /
     (_()_)__/ \
    / _,==.____ \
   (   |--|      )
   /\_.|__|'-.__/\_
  / (        /     \
  \  \      (      /
   )  '._____)    /
(((____.--(((____/mrf
$ ./frame< bear2.txt 
╔═══════════════════════╗
║      (()__(()         ║
║      /       \        ║
║     ( /    \  \       ║
║      \ o o    /       ║
║      (_()_)__/ \      ║
║     / _,==.____ \     ║
║    (   |--|      )    ║
║    /\_.|__|'-.__/\_   ║
║   / (        /     \  ║
║   \  \      (      /  ║
║    )  '._____)    /   ║
║ (((____.--(((____/mrf ║
╚═══════════════════════╝

1
Your example has an emtpy line between the bottom frame and the input which is invalid. The top and bottom frames have to be inserted directly before and after the input (your previous version was fine btw).
Denker

1
Nice!, But you could save approx 5 char if ...?${#2}+2:n)) instead of +1, drop 2 spaces and printf -v z %${n}s; instead of printf -v z " %*.s" $n.
F. Hauri

@Sukminder Ok, was already assumnig that, but wanted to make that sure since the input you show does not contain an empty line. I did not demand that you clear the input of leading or traliing empty lines, so you program is perfectly fine.
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"╝"}

Apparently awk can print Unicode if you can figure out how to get it in the code.


I'm having so many ideas for awesome pipes now ...
Sebb

@Sebb That does seem like fun. :)
Robert Benson

5

Perl, 111 characters

(score includes +5 for the interpreter flags)

#!/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═╝";

First, we find the longest line length $n, by numerically sorting the lengths of all lines.

We set $l to be the header/footer bar to be $n repetitions of the horizontal frame character.

Then we print each line formatted to left-align in a field of width $n, sandwiched in between the frame characters.

Result:

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

4

Pyth, 44 chars (58 bytes)

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

Explanation

++\╔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+"╝")

Try it here.


4

PHP 5.3, 209 bytes

This only works using the encoding OEM 860. It is an Extended ASCII superset, used in Portuguese DOS versions. Since I'm Portuguese (and I used to love doing these "frames" in Pascal) and this is a standard encoding, I went ahead with this:

<?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)));

Here's the base64:

PD9mb3JlYWNoKCRXPWV4cGxvZGUoJwonLCRhcmd2WzFdKWFzJHYpJE09bWF4KCRNLHN0cmxlbigkdikrMik7cHJpbnRmKCLilZQlJ+KVkHskTX1z4pWXCuKVkSUxXCR7JE19c+KVkQolMlwkcwrilZElMVwkeyRNfXPilZEK4pWaJTFcJCfilZB7JE19c+KVnSIsJycsam9pbignCicsYXJyYXlfbWFwKGZ1bmN0aW9uKCR2KXVzZSgkTSl7cmV0dXJuIHN0cl9wYWQoIiAkdiAiLCRNKTt9LCRXKSkpOw==

This answer was based on my answer on: https://codegolf.stackexchange.com/a/57883/14732 (the heavy lifting was all made there, just had to twitch a bit).


Impressive to say the least :)
MonkeyZeus

The codes is 209 bytes/characters. 22+58+11+5+11+24+66+12=209 The last 12 is newlines and as it is DOS that means CRLF, or two bytes per newline. The charactercountonline site does not count newlines. Each of the non-ASCII glyphs are 1 byte in OEM 860.
Runium

@Sukminder Don't forget that (at least) Windows converts \n into \r\n, when opening the file in ASCII/text mode.
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+"╝")

Input:

hello
there
  !  

Output:

╔═══════╗
 hello 
 there 
   !   
╚═══════╝

Welcome to Progamming Puzzles & Code Golf! Nice first answer! You can always write functions instead of full programs (unless explicitly forbidden in the challenge) which might allow you to save some bytes by taking the input as argument. Also you might want to use Python 2, so you can save 2 bytes by going with print"╔"+h+"╗\n"+"".join(o)+"╚"+h+"╝".
Denker

Thanks. I couldn't figure out how to get the high-bytes working in Python2 (probably setting the codec environment variable would work but I'm not sure how that plays into golf byte counts). The function approach eliminates python2/3 differences but adds a byte in my best approach.
SumnerHayes

Okay, I got it down to 119 characters as a function; takes input as a string. My mini-markdown is obviously not up to snuff; Line 1 is the def, the rest (after the colon) is line 2, with a leading space. 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

Just update your post with the new version and the new score (struck the old score out with <s>...</s>). Also you can add <!-- language-all: lang-python --> before your code-block to add syntax highlighting to your code.
Denker

This doesn't work if the input is non-rectangular, while the question says that no line will have trailing whitespace.
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)

Looks shorter than 115 here, but working file includes 3-byte UTF-8 BOM mark signature, bumping it up to 115 bytes. If you were to run it in Python 3 you wouldn't need the BOM and it'd get down to 112 bytes.


Welcome to Programming Puzzles & Code Golf! Unfortunately, your code appears to assume that the input is rectangular, while the question says that no line will have trailing whitespace.
Dennis

I count 107 bytes. I don't think you need to include the "UTF-8 BOM mark signature".
CalculatorFeline

@CatsAreFluffy Are you using Python2? In Python3 all strings are unicode, but it's trickier with Python2.
Jenny Miller

Oops, I counted pipes as 2 bytes, but even after using an actual bytecounter, still only 111 bytes. Tell me where those 5 bytes came from.
CalculatorFeline

The UTF-8 BOM is 3 bytes (en.wikipedia.org/wiki/Byte_order_mark). My count was one high because my text editor was adding a trailing newline, so my solution is really only 115 bytes. You could leave off the leading BOM bytes and get it down to 112 if you were using Python3 (which counts all strings as unicode). But I don't know how you're seeing only 111 bytes. btw, here's how I added the BOM: sed -i '1s/^\(\xef\xbb\xbf\)\?/\xef\xbb\xbf/' codeGolf.py
Jenny Miller

1

C, 290 bytes

Golfed function B, with dependencies; takes input as null-terminated char*

#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);}

Somewhat-ungolfed function in full program

#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;
}

input

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

output

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

C golfing tips appreciated!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.