6
\$\begingroup\$

I once hacked upstart on my Ubuntu box so that a colored, themeable ASCII Tux displayed on the screen with the boot messages scrolling beneath him. I'm curious to see what kind of ASCII art Linux Penguins you can come up with.

  • It must fit in a 80 x 25 terminal, without using the bottom line (thus 80 x 24)
  • Compact source code
  • Bonus: use color
  • Bonus: use variations on the standard Tux

Edit: As a clarification, by "compact source code" I meant smallest source code per number of lines of output. The answers so far have been good but it would be fun to get a diversity of penguins going.

\$\endgroup\$
1
  • 4
    \$\begingroup\$ Bonus points for the Windows flag. Penalty points for the Apple apple. \$\endgroup\$ Jan 1, 2012 at 2:28

9 Answers 9

19
\$\begingroup\$

Many script languages, 6 UTF-8 bytes

It doesn't print ASCII art, but...

"🐧"

The character in the quote is the unicode character penguin (U+1F427) (if you want to see the penguin above, download the Symbola font). It looks like this (but a lot smaller):

Penguin character shown with huge font size

\$\endgroup\$
6
  • \$\begingroup\$ +1 You deserve the award for shortest overall answer. I love things that are represented in single characters, but I didn't know about this one. \$\endgroup\$
    – Kazark
    Dec 31, 2011 at 20:28
  • 5
    \$\begingroup\$ Unicode art!!! We will soon be able to draw a complete zoo with only a short line of code! \$\endgroup\$
    – Joanis
    Dec 31, 2011 at 20:39
  • 3
    \$\begingroup\$ Is there a unicode-character for "Hello World"? \$\endgroup\$ Jan 1, 2012 at 23:15
  • 5
    \$\begingroup\$ @userunknown: With two!!! \uD83D\uDC4B\uD83C\uDF0F == fileformat.info/info/unicode/char/1f44b/index.htm + fileformat.info/info/unicode/char/1f30f/index.htm \$\endgroup\$
    – Joanis
    Jan 5, 2012 at 1:33
  • 1
    \$\begingroup\$ But that's not Tux! ...Or what diet has he been put on? \$\endgroup\$ Feb 2, 2012 at 20:36
11
\$\begingroup\$

Instead of attempting to print a given penguin, I hacked together a program to reduce ASCII art to a minimum production string in Python. I could do some crazy hacks with metaprogramming the environment to define variables for re-used strings, but this is good enough for now. It's Sunday, what can I say.

ASCII compiler - 882 - Python


#!/usr/bin/env python

import sys, re

d = "".join(sys.stdin.readlines()) # get all text (WARNING... BIG INPUTS POSSIBLE)
d = re.sub(r' +[\r\n]','',d)       # strip trailing spaces
i,j,c,o,f=0,0,d[0],"""#!/usr/bin/python
# -*- coding: UTF-8 -*-
print \"""",False      # set up vars

while (i <= j) and (j < len(d)):   # while the head cursor (j) is in bounds
 if(d[j] == c): j+=1               # if we are in a repetition be gready
 else:
  if c == "\\": c = "\\\\"         # generate repr()s of special case strings
  elif c == "\n": c = "\\n"
  elif c == "\r": c = ""           # bump \n\r
  elif c == "\"": c = "\\\""

  if((j-i)-9 > 0):                 # if the sequence is long enough to justify a repetition
   if(o): o += "\"+"
   o += "\""+c+"\"*{0}+\"".format(j-i)

  else: o += (c*(j-i))             # else just print the sucker
  i = j
  c = d[j]
o += "\""                          # system assumes an open quote at all times, close it

print o

Usage: cat ./tux.txt | python ./encode.py

My Tux - 1009 chars with spaces


                    ..- - .              
                   '        `.           
                  '.- .  .--. .          
                 |: _ | :  _ :|          
                 |`(@)--`.(@) |          
                 : .'     `-, :          
                 :(_____.-'.' `          
                 : `-.__.-'   :          
                 `  _.    _.   .         
                /  /  `_ '  \    .       
               .  :          \\   \      
              .  : _      __  .\   .     
             .  /             : `.  \    
            :  /      '        : `.  .   
           '  `      :          : :  `.  
         .`_ :       :          / '   |  
         :' \ .      :           '__  :  
      .--'   \`-._    .      .' :    `).  
    ..|       \   )          :   '._.'  : 
   ;           \-'.        ..:         / 
   '.           \  - ....-   |        '  
      -.         :   _____   |      .'   
        ` -.    .'--       --`.   .'     
            `--                --        

Compiled Tux - 878 - Python


print " "*20+"..- - .\n"+" "*19+"'"+" "*8+"`.\n"+" "*18+"'.- .  .--. .\n"+" "*17+"|: _ | :  _ :|\n"+" "*17+"|`(@)--`.(@) |\n"+" "*17+": .'"+" "*5+"`-, :\n"+" "*17+":("+"_"*5+".-'.' `\n"+" "*17+": `-.__.-'   :\n"+" "*17+"`  _."+" "*4+"_.   .\n"+" "*16+"/  /  `_ '  \\"+" "*4+".\n"+" "*15+".  :"+" "*10+"\\\\   \\\n"+" "*14+".  : _"+" "*6+"__  .\\   .\n"+" "*13+".  /"+" "*13+": `.  \\\n"+" "*12+":  /"+" "*6+"'"+" "*8+": `.  .\n"+" "*11+"'  `"+" "*6+":"+" "*10+": :  `.\n"+" "*9+".`_ :"+" "*7+":"+" "*10+"/ '   |\n"+" "*9+":' \\ ."+" "*6+":"+" "*11+"'__  :\n"+" "*6+".--'   \\`-._"+" "*4+"."+" "*6+".' :"+" "*4+"`).\n"+" "*4+"..|"+" "*7+"\\   )"+" "*10+":   '._.'  :\n   ;"+" "*11+"\\-'."+" "*8+"..:"+" "*9+"/\n   '."+" "*11+"\\  - "+"."*4+"-   |"+" "*8+"'\n"+" "*6+"-."+" "*9+":   "+"_"*5+"   |"+" "*6+".'\n"+" "*8+"` -."+" "*4+".'--"+" "*7+"--`.   .'\n"+" "*12+"`--"+" "*16+""

Edit 1: Sadly, while this is efficient for large ASCII art files, as with many compression schemes its performance is lackluster to say the least when presented with very small inputs. The "standard" penguin featured thus far "compresses" to 100 chars of Python which while much better than Brainf*ck is still nothing to brag about considering that the penguin itself is a mere 75 chars by my count.

Edit 2: Also as with many compression schemes the incremental gain is minimal. When I tested my compiler against several ASCII files I seem to get a mere 9-10% improvement over the source.

Edit 3: Re: kolmogorov complexity. After some quality time thinking and attempting to golf the base penguin, I have come to the conclusion that the optimal representation is 87 characters long, adding 12 to the actual penguin.

print """    .--.
   |o_o |
   |:_/ |
  //   \ \
 (|     | )
/'|_   _/'\
\___)=(___/"""

The python string repetition syntax for one character, say "a"*5, consumes 4+log10(n) characters in the best case (non-special characters) and 5+log10(n) for characters such as the newline or tab which require the string "\n" not a quoted single char. Therefor to achieve a compression greater than 0%, a character repetition greater than 9 characters in length must exist. (assuming that the repetition is part of a substring which must be terminated with a quote and added to with + and restarted with the same symbols, thus adding 4 to the cost of a repetition) A trivial examination of the penguin above reveals that no such string exists, therefore no compression is possible using string repetition and the best one can do is leverage the tripple quoted string syntax to represent newlines in one char not two.

Edit 4: Fixed edit 3 to reflect the relatively high probability of repetitions internal to some superstring, requiring a repetition like "+'a'*15+" which is of length 6+len(repr(a))-2+log10(n), updated compiler. (the -2 is required because repr() double-quotes everything)

Edit 5: Grabbed the ASCII art collection HERE, and threw together the BASH script below. Pulled a 12% compression average over the entire collection.

#!/bin/bash
l=$(find ./art/ -type f)
len=$(find ./art/ -type f | wc -l)
s=0

for i in $l; do
    chars=$(cat $i | wc -c)
    out=$(cat $i | python ./encode.py | wc -c)
    c=$(calc "1-(($out-42)/$chars)" | sed s/'~'/''/g)
    s=$(calc "$s+$c")
    cat $i | python ./encode.py | python 2> /dev/null
    echo -e "$i, $c\t|$?"
done;
echo $(calc "$s/$len")

Edit 6: Added the UTF-8 specification header to all compiler output and removed those chars from the test script's count because they are spec-required.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Wow, you deserve like a 1000 bonus points. \$\endgroup\$
    – Kazark
    Jan 2, 2012 at 17:04
8
\$\begingroup\$

Haskell - 14 characters

main=putStr"."

The penguin this program displays is in the far distance.

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Actually, that penguin is not only in the far background, but also looking away from us. \$\endgroup\$
    – PhiNotPi
    Jan 1, 2012 at 2:32
  • 4
    \$\begingroup\$ Looks very similar to the ass hole of a gnu from not that far away, if you ask me ... \$\endgroup\$ Jan 1, 2012 at 23:19
  • \$\begingroup\$ Wow...Is it waving ? Can we do this in PHP for 1 byte ? \$\endgroup\$
    – smanna
    Apr 13, 2017 at 16:02
5
\$\begingroup\$

brainfuck, 311 chars (44.4 sc/ol)

(where "sc/ol" stands for "source characters per output line")

++++++++++[>++++++>++++>++++>+>+++>+++++++++>++++++++++++>+++++++++++
<<<<<<<<-]>>>>>++....<<++++++.-..+.>.>...>>++++.>+.<<+++++.>>.<<<.>>.
<<<.>...>>.<<<<<<--.>>>>>.<<<+.>>.>>.<<<.>..<<..>>...>---.<.>.<<.>.<<
<.>>>>>.<<.....>>.<<.<<<+.>>.<.<--.>>>>>.<+++.<...>.<<<.<.>>>>---.<<.
>>.+++...<<<<++.<+++.>-.>>>>...<<<.

Same tux as CMP:

    .--.
   |o_o |
   |:_/ |
  //   \ \
 (|     | )
/'|_   _/'\
\___)=(___/

I inserted CRs to get rid of the scrollbar, but I didn't count them.

It's most probably still not optimal. I leave the maths to someone else. It's all in the choice of initial numbers/characters (to save increments and decrements) and in which order to place them (to save pointer moves).

\$\endgroup\$
1
  • \$\begingroup\$ I was just trying to find a smaller tux but, without spending too much time, it seems to be the smallest tux-looking tux around. Look at the small ones here, for example: ascii-art.de/ascii/jkl/linux.txt Not so tuxy. \$\endgroup\$
    – Joanis
    Dec 31, 2011 at 17:54
4
\$\begingroup\$

Brainfuck - 378

++++[>++++++++<-]>[>+>++>+++>++++<<<<<+>-]<[>+<-]++++++++++
>....>++++++++++++++.-..+.<<.
>...>>>>----.-------------.<-.>.<<<<.>>>>+++++++++++++.<<<<<.
>...>>>>.<<------.>.<<+.<.>>>>.<<<<<.
>..>..<...>>>---.<<<.>>>.<<<<.
>.>-------.>>>.<<<<.....>>>>.<<<<.>+.<<.
>>++++++.<+++++++.>>>>.<+++.<<<-------...>>>.<<.<+++++++.>>>---.<<<<.
>>>>.+++...<<------.>+++.<-.>>...<<+++++++.<<.

Prints this:

    .--.
   |o_o |
   |:_/ |
  //   \ \
 (|     | )
/'|_   _/'\
\___)=(___/

Hand coded from an image I found on wikipedia. Unfortunately I have no facility to provide color.

\$\endgroup\$
5
  • \$\begingroup\$ +1 Hand-coded—I like it! Looks good for being so small! Also extremely impressed by the esoteric language (tho mildly offended by its name). \$\endgroup\$
    – Kazark
    Dec 28, 2011 at 22:47
  • \$\begingroup\$ Again, I'm impressed that you managed to write this within two hours. \$\endgroup\$
    – Joey Adams
    Dec 28, 2011 at 23:06
  • \$\begingroup\$ I really got lucky here. Saw the question right when it popped up, and it is actually not that hard to set up an array of seed values and spit out the proper characters in order. \$\endgroup\$
    – captncraig
    Dec 28, 2011 at 23:48
  • \$\begingroup\$ It prints this, with a 4 * 7 block of spaces to the left. Removing these, you save 28 dots, plus maybe some pointer moves. I'll post my bf version too. \$\endgroup\$
    – Joanis
    Dec 31, 2011 at 3:23
  • \$\begingroup\$ Good point. It saved me just a bit more than 28 because I didn't have to reset the character to space on the final line. \$\endgroup\$
    – captncraig
    Jan 3, 2012 at 15:54
3
\$\begingroup\$

Try:

#!/bin/bash
sudo apt-get install cowsay
echo | cowsay -f tux.cow "Welcome"

This returns the exact same ascii as in the first answer.

\$\endgroup\$
1
  • \$\begingroup\$ Well, it returns the same Penguin, with a dialog box saying "Welcome". \$\endgroup\$
    – Kazark
    Dec 29, 2011 at 18:15
3
\$\begingroup\$

This was inspired by @trinithis's answer with the small penguin in the distance. Getting a little closer, it appears he has turned to the side:

Bash – 7 characters

echo \&
\$\endgroup\$
2
\$\begingroup\$

Brainfuck - 446 (441 if omit >>>>>. which prints \n)

++++++++[>++++++>>++++>>>-------->+>++++<<<<<<<<-]>-[->+>>++>++>
++++<<<<<]>>.....>+......>>>++.<<<<....<.>......>>--.>>.>...<<.<
<<.<.>>>.<<..<.>>>.<<.>>>.>.>...<<.<<<...>..<...>>>.>.>...<<.<<<
..<.>..>>.>>>..<<.>.<<<<...<.>.<.>>....>.<<.>>.>>.<<<<..<.>.<.>>
>.<....<<.>>>.<<.>>.>>.<<<<.<.>.<.>........>>.<<.>>.>>.>.<<.>>.<
<.>>........<<.>>.<<.>.<<<<<.>.>>.>.>>........<<.<<<<.>.>>.>>.<.
<<<..>>.<........<<.>..>>>.>.<<.<...<<.>......>>.<...<<.>>>>>.

This prints

     ______
    /      \
   | /\  /\ |
   |   __   |
   |  /  \  |
   / /____\ \
  / /\____/\ \
 / /        \ \
 | |        | |
/ \|        |/ \
|  \________/  |
\___/      \___/

Therefore, it's 37.1667 (36.75 if the code printing last \n is omitted) letters per line.

\$\endgroup\$
3
  • \$\begingroup\$ +1 First answer to use a different Tux. Did you do the ASCII art yourself, or get it from somewhere else? I'm amazed to get so many Brainfuck answers—guess it is really good for code golfing, if you are good enough to use it. \$\endgroup\$
    – Kazark
    Dec 31, 2011 at 19:35
  • 2
    \$\begingroup\$ @Kazark Actually, BF is well known for how not good it is for golf. It gets used here often because it is very challenging to hand code, and thus shows off programming ability. \$\endgroup\$
    – PhiNotPi
    Dec 31, 2011 at 19:43
  • 1
    \$\begingroup\$ @Kazark I drew this ASCII art myself to minimize number of characters used. I used BrainFuck because it's challenging.. \$\endgroup\$
    – JiminP
    Dec 31, 2011 at 19:50
1
\$\begingroup\$

PHP, 1 byte

Tux in a distance

.

Thanks to original by Thomas Eding
Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ What does this do in PHP? \$\endgroup\$
    – Kazark
    Apr 13, 2017 at 16:56
  • \$\begingroup\$ It prints the character to STDOUT @Kazark \$\endgroup\$
    – smanna
    Apr 14, 2017 at 1:37

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