จัดวาง ASCII-Art ที่ดีนี้


30

บทนำ

ฉันคิดว่าทุกคนยอมรับว่ารูปภาพที่ดีต้องมีกรอบที่ดี แต่ความท้าทายส่วนใหญ่ในเว็บไซต์นี้เกี่ยวกับ ASCII-Art เพียงแค่ต้องการภาพที่ดิบและไม่สนใจว่ามันจะถูกสงวนไว้
มันจะไม่ดีถ้าเรามีโปรแกรมที่ใช้ ASCII-Art และล้อมรอบด้วยเฟรมที่ดี?

ความท้าทาย

เขียนโปรแกรมที่ใช้ ASCII-Art เป็นอินพุตและเอาต์พุตล้อมรอบด้วยเฟรมที่สวยงาม

ตัวอย่าง:

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

กลายเป็น

╔═══════╗
║ ***** ║
║ *** ║
║ * ║
║ *** ║
║ ***** ║
╚═══════╝
  • คุณต้องใช้ตัวอักษรเหมือนกันทุกประการกับเฟรมดังตัวอย่าง: ═ ║ ╔ ╗ ╚ ╝
  • ด้านบนและด้านล่างของเฟรมจะถูกแทรกก่อนบรรทัดแรกและหลังบรรทัดสุดท้ายของอินพุต
  • ส่วนด้านซ้ายและด้านขวาของเฟรมจะต้องมีช่องว่างหนึ่งช่องที่แน่นอนไปยังบรรทัดที่กว้างที่สุดของอินพุต
  • อาจไม่มีช่องว่างนำหน้าหรือต่อท้ายในเอาต์พุต อนุญาตเฉพาะบรรทัดขึ้นบรรทัดใหม่เท่านั้น
  • คุณอาจคิดว่าอินพุตไม่มีช่องว่างนำหน้าที่ไม่จำเป็น
  • คุณอาจคิดว่าอินพุตไม่มีช่องว่างต่อท้ายบนบรรทัดใด ๆ
  • คุณไม่ต้องจัดการกับอินพุตว่าง
  • ข้อมูลที่ป้อนจะมีเฉพาะอักขระ ASCII ที่พิมพ์ได้และบรรทัดใหม่

กฎระเบียบ

  • อนุญาตให้ใช้ฟังก์ชั่นหรือโปรแกรมเต็มรูปแบบ
  • กฎเริ่มต้นสำหรับอินพุต / เอาต์พุต
  • ช่องโหว่มาตรฐานใช้
  • นี่คือดังนั้นจำนวนไบต์ที่น้อยที่สุดจึงชนะ Tiebreaker เป็นการส่งก่อนหน้า

Happy Coding!

ใช้ ASCII-Art ที่ยอดเยี่ยมซึ่งสร้างขึ้นในความท้าทายใด ๆ บนเว็บไซต์นี้เพื่อสนับสนุนโปรแกรมของคุณและแสดงด้วยกรอบที่สวยงาม!


29
เฟรมที่ไม่ใช่ ASCII สำหรับงานศิลปะ ASCII หรือไม่? บาป!
เดนนิส

5
มีความสัมพันธ์กันอย่างใกล้ชิด ความท้าทายเดียวกัน แต่ใช้อักขระ (ASCII) เดียวสำหรับเฟรม
Martin Ender

13
(ฉันควรจะอธิบายให้ชัดเจนว่าฉันไม่คิดว่ามันเป็นคนหลอกลวงต้องใช้ตัวละครต่าง ๆ 6 ตัวทำให้เรื่องนี้ยุ่งยากมากความท้าทายอื่นสามารถแก้ไขได้โดยหมุนกริดและต่อท้าย#สี่ครั้งการปรับวิธีการที่นี่จะยุ่งยากที่สุด และทำงานได้ไม่เลวร้ายที่สุด)
Martin Ender

6
@IsmaelMiguel ฉันชนะการแข่งขันก่อนหน้านี้และไม่เห็นว่าฉันจะปรับคำตอบเก่าของฉันได้อย่างไร
Martin Ender

2
ฉันสงสัยว่า DenkerAffe กำลังสมมติ CP437 หรือบางสิ่งที่ตัวอักษรเฟรมเป็นหนึ่งไบต์
Joshua

คำตอบ:


6

CJam, 45 ตัวอักษร / 52 ไบต์

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

การพยายามหลีกเลี่ยงตัวอักษร 3 ไบต์ที่มีราคาแพงนั้น ... น่าสนใจ

ลองออนไลน์

คำอธิบาย

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 ไบต์

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

ตัวอย่างเช่นฉันกรอบมนุษย์หิมะ "12333321"

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

มันทำงานอย่างไร:

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 ไบต์

นี่คือ 138 ไบต์ในการเข้ารหัส IBM866 ซึ่งขณะที่เขียนยังคงได้รับการสนับสนุนใน Firefox แต่เป็น 152 ใน 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
คุณสามารถเข้ารหัส Javascript ด้วย CP437 และยังสามารถใช้งานได้จริงหรือไม่? ถ้าไม่เช่นนั้นจะไม่ได้เป็นจริง 138 ไบต์
Mama Fun Roll

@ ӍѲꝆΛҐӍΛПҒЦꝆแม้ว่าฉันจะไม่พบสิ่งใดที่สนับสนุน CP437 ปัจจุบัน Firefox รองรับ IBM866 ซึ่งมีอักขระวาดกล่องเหล่านี้ดังนั้นฉันจึงได้อัปเดตคำตอบของฉัน
Neil

โอเคเยี่ยมเลย มี upvote!
Mama Fun Roll

6

Bash, 173 171 150 148 147 ไบต์, 157 136 134 133 ตัวอักษร

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╝

ตัวอย่างการดำเนินการ:

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

ตัวอย่างการรันจากสคริปต์:

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

1
ตัวอย่างของคุณมีเส้น emtpy ระหว่างเฟรมด้านล่างและอินพุตที่ไม่ถูกต้อง เฟรมด้านบนและด้านล่างจะต้องถูกแทรกโดยตรงก่อนและหลังอินพุต (เวอร์ชันก่อนหน้าของคุณคือ btw ที่ดี)
Denker

1
นีซ !, แต่คุณสามารถประหยัดประมาณ 5 ถ่านถ้า...?${#2}+2:n))แทนที่จะ+1ลดลง 2 คันและแทนprintf -v z %${n}s; printf -v z " %*.s" $n
F. Hauri

@Sukminder Ok ได้ทำการประกอบแล้ว แต่ต้องการให้แน่ใจว่าเนื่องจากอินพุตที่คุณแสดงไม่มีบรรทัดว่าง ฉันไม่ได้ต้องการให้คุณเคลียร์อินพุตของบรรทัดว่างนำหน้าหรือว่างเปล่าดังนั้นโปรแกรมของคุณจึงสมบูรณ์แบบ
Denker

5

AWK, 159 ไบต์

{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"╝"}

เห็นได้ชัดว่าawkสามารถพิมพ์ Unicode ถ้าคุณสามารถหาวิธีที่จะได้รับมันในรหัส


ตอนนี้ฉันมีไอเดียมากมายสำหรับท่อที่ยอดเยี่ยม ...
Sebb

@Sebb มันดูสนุกดี :)
Robert Benson

5

Perl, 111 ตัวอักษร

(คะแนนรวมถึง +5 สำหรับธงล่าม)

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

ก่อนอื่นเราจะพบความยาวบรรทัดที่ยาวที่สุด $nโดยการเรียงลำดับตัวเลขตามความยาวของทุกบรรทัด

เราตั้งค่า$lให้เป็นแถบส่วนหัว / ท้ายกระดาษ$nทำซ้ำของตัวละครเฟรมแนวนอน

จากนั้นเราพิมพ์แต่ละบรรทัดที่จัดรูปแบบเพื่อจัดชิดซ้ายในฟิลด์ความกว้าง $nคั่นกลางระหว่างอักขระเฟรม

ผล:

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

4

Pyth, 44 ตัวอักษร (58 ไบต์)

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

คำอธิบาย

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

ลองที่นี่


4

PHP 5.3, 209 ไบต์

ใช้งานได้กับการเข้ารหัสOEM 860เท่านั้น มันเป็น superset แบบขยายของ ASCII ที่ใช้ในโปรตุเกส DOS รุ่น เนื่องจากฉันโปรตุเกส (และฉันเคยชอบทำ "frames" เหล่านี้ใน Pascal) และนี่เป็นการเข้ารหัสแบบมาตรฐานฉันจึงดำเนินการต่อไปด้วย

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

นี่คือ base64:

PD9mb3JlYWNoKCRXPWV4cGxvZGUoJwonLCRhcmd2WzFdKWFzJHYpJE09bWF4KCRNLHN0cmxlbigkdikrMik7cHJpbnRmKCLilZQlJ+KVkHskTX1z4pWXCuKVkSUxXCR7JE19c+KVkQolMlwkcwrilZElMVwkeyRNfXPilZEK4pWaJTFcJCfilZB7JE19c+KVnSIsJycsam9pbignCicsYXJyYXlfbWFwKGZ1bmN0aW9uKCR2KXVzZSgkTSl7cmV0dXJuIHN0cl9wYWQoIiAkdiAiLCRNKTt9LCRXKSkpOw==

คำตอบนี้ขึ้นอยู่กับคำตอบของฉันใน: https://codegolf.stackexchange.com/a/57883/14732 (การยกของหนักทั้งหมดทำที่นั่นเพียงแค่ต้องกระตุกนิดหน่อย)


น่าประทับใจที่จะพูดน้อย :)
MonkeyZeus

รหัสคือ 209 ไบต์ / ตัวอักษร 22+58+11+5+11+24+66+12=20912 บรรทัดสุดท้ายเป็นบรรทัดใหม่และเป็น DOS ที่หมายถึง CRLF หรือสองไบต์ต่อบรรทัดใหม่ charactercountonlineเว็บไซต์ไม่นับการขึ้นบรรทัดใหม่ ร่ายมนตร์ที่ไม่ใช่ ASCII แต่ละอันมีขนาด 1 ไบต์ใน OEM 860
Runium

@Sukminder อย่าลืมว่า (อย่างน้อย) Windows แปลง\nเป็น\r\nเมื่อเปิดไฟล์ในโหมด ASCII / text
Ismael Miguel

2

Python 3, 119 ไบต์

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 ไบต์

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

การป้อนข้อมูล:

hello
there
  !  

เอาท์พุท:

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

ยินดีต้อนรับสู่ Progamming Puzzles & Code Golf! คำตอบแรกที่ดี! คุณสามารถเขียนฟังก์ชั่นแทนโปรแกรมเต็มรูปแบบได้ตลอดเวลา (เว้นแต่จะถูกห้ามอย่างชัดเจนในการท้าทาย) ซึ่งอาจช่วยให้คุณสามารถบันทึกบางไบต์ได้โดยใช้อินพุตเป็นอาร์กิวเมนต์ นอกจากนี้คุณอาจต้องการใช้งูหลาม 2 เพื่อให้คุณสามารถบันทึก 2 print"╔"+h+"╗\n"+"".join(o)+"╚"+h+"╝"ไบต์โดยไปกับ
Denker

ขอบคุณ ฉันไม่สามารถหาวิธีการทำงานของไบต์สูงใน Python2 (อาจตั้งค่าตัวแปรสภาพแวดล้อมตัวแปลงสัญญาณจะทำงาน แต่ฉันไม่แน่ใจว่าวิธีการที่เล่นเป็นจำนวนไบต์ไบต์กอล์ฟ) วิธีการใช้งานช่วยลดความแตกต่างของ python2 / 3 แต่เพิ่มไบต์ในแนวทางที่ดีที่สุดของฉัน
SumnerHayes

โอเคฉันได้รับมันลงไปที่ 119 ตัวอักษรเป็นฟังก์ชั่น; รับอินพุตเป็นสตริง เห็นได้ชัดว่า mini-markdown ของฉันไม่ได้ขึ้นอยู่กับกลิ่น บรรทัดที่ 1 คือ def ส่วนที่เหลือ (หลังโคลอน) คือบรรทัด 2 ที่มีช่องว่างนำหน้า 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

เพียงอัปเดตโพสต์ของคุณด้วยเวอร์ชันใหม่และคะแนนใหม่ (ให้คะแนนเก่าด้วย<s>...</s>) นอกจากนี้คุณสามารถเพิ่ม<!-- language-all: lang-python -->ก่อนโค้ดบล็อกของคุณเพื่อเพิ่มการเน้นไวยากรณ์ให้กับโค้ดของคุณ
Denker

สิ่งนี้ไม่ทำงานหากอินพุตไม่ใช่รูปสี่เหลี่ยมผืนผ้าในขณะที่คำถามบอกว่าไม่มีบรรทัดใดที่จะมีช่องว่างต่อท้าย
เดนนิส

2

Python 2, 115 ไบต์

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

ดูสั้นกว่า 115 ที่นี่ แต่ไฟล์ที่ใช้งานได้นั้นมีลายเซ็นของเครื่องหมาย UTF-8 BOM ขนาด 3 ไบต์และชนได้สูงสุด 115 ไบต์ ถ้าคุณต้องรันมันใน Python 3 คุณไม่จำเป็นต้องใช้ BOM และมันจะลดลงเหลือ 112 ไบต์


ยินดีต้อนรับสู่ Programming Puzzles & Code Golf! น่าเสียดายที่โค้ดของคุณดูเหมือนว่าสมมติว่าอินพุตเป็นสี่เหลี่ยมในขณะที่คำถามบอกว่าไม่มีบรรทัดใดที่จะมีช่องว่างต่อท้าย
เดนนิส

ฉันนับ 107 ไบต์ ฉันไม่คิดว่าคุณต้องใส่ "ลายเซ็นเครื่องหมาย UTF-8 BOM"
CalculatorFeline

@CatsAreFluffy คุณใช้ Python2 หรือไม่ ใน Python3 สตริงทั้งหมดเป็นยูนิโค้ด แต่มันมีเล่ห์เหลี่ยมกับ Python2
เจนนี่มิลเลอ

โอ๊ะฉันนับว่าเป็น 2 ไบต์ แต่แม้หลังจากใช้ bytecounter จริงแล้วก็ยังเหลือเพียง 111 ไบต์เท่านั้น บอกฉันทีว่า 5 ไบต์มาจากไหน
CalculatorFeline

UTF-8 BOM คือ 3 ไบต์ ( en.wikipedia.org/wiki/Byte_order_mark ) การนับของฉันสูงมากเนื่องจากโปรแกรมแก้ไขข้อความของฉันเพิ่มบรรทัดใหม่ที่ต่อท้ายดังนั้นโซลูชันของฉันจึงมีเพียง 115 ไบต์เท่านั้น คุณสามารถละทิ้งไบต์ BOM ชั้นนำและลดลงเหลือ 112 ถ้าคุณใช้ Python3 (ซึ่งนับสตริงทั้งหมดเป็นยูนิโค้ด) แต่ฉันไม่รู้ว่าคุณเห็นเพียง 111 ไบต์ได้อย่างไร btw นี่คือวิธีที่ฉันเพิ่ม BOM: sed -i '1s/^\(\xef\xbb\xbf\)\?/\xef\xbb\xbf/' codeGolf.py
Jenny Miller

1

C, 290 ไบต์

ฟังก์ชั่น Golfed ที่Bมีการอ้างอิง; รับอินพุตเป็น char ที่ยกเลิกด้วย null *

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

ฟังก์ชั่นค่อนข้างไม่ดีในโปรแกรมเต็มรูปแบบ

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

อินพุต

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

เอาท์พุต

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

เคล็ดลับการเล่นกอล์ฟ C ชื่นชม!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.