Tips for golfing ASCII art
Compression algorithms
You can apply LZMA compression to the string.
Many languages support it.
Run-length encoding
You can use processing instructions such as [char][number]
(e.g. b12
).
This compression algorithm is used here: https://codegolf.stackexchange.com/a/20589/10920
Further reading: http://en.wikipedia.org/wiki/Run-length_encoding
Integer packing
You can use arrays of integers to store small shapes such as:
// This is an invader!
// (SE line height makes it looks awful)
// ~158 characters
## ##
## ##
##############
#### ###### ####
######################
## ############## ##
## ## ## ##
#### ####
Each space will be translated into a 0
.
Each sharp will be translated into a 1
.
// ~58 characters
// Saved ~100 bytes!
[
196656, 49344, 262128, 999228,
4194303, 3407859, 3342387, 62400
]
Each bit is then read using bitwise operator &
.
The above algorithm could be improved by using a bigger integer base:
// ~44 characters
// Integers are in base 36.
// Use `_` as a separator (or a line break).
"47qo_122o_5m9c_lf0c_2hwcf_211ir_1zn03_1c5c"
Look for symmetry
Sometimes the required ASCII art is symmetric at some point. For example, Argyle ASCII Art requires an output similar to this:
/\ /\
/ \ /\ / \
/\/ \/ \/ \/\
\/\ /\ /\ /\/
\ / \/ \ /
\/ \/
One could just print this normally, but depending on the language, the code required can be shortened by only generating the top half of the result, reversing it and swapping /
and \
.
Try transposing
In ASCII Art Archery Arrows the result to print is this, scaled to a given n
:
/\
/ \
/ \
/ \
\ /
\____/
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
/| |\
/ | | \
/ | | \
/ | | \
/ | | \
/ |__| \
/ / \ \
/ / \ \
// \\
/ \
If we take a look at the arrow, we can see there's 8 kinds of lines:
/ \
\ /
\_/
| |
/ | | \
/ |_| \
/ / \ \
/ \
Let's try the same for its transpose.
///////
/ /
/\ / /
/ \ / /
/ _||||||||||||||||||||||
/ _ _
\ _ _
\ _||||||||||||||||||||||
\ / \ \
\/ \ \
\ \
\\\\\\\
Here, there are 10 kinds of lines.
/
/ /
/ \ / /
/ _|
/ _ _
\ _ _
\ _|
\ / \ \
\ \
\
But here's the catch: the bottom 5 are identical to the top 5, except for swapping /
and \
. As per the previous rule, you can first generate the first 5, copy, do the swap, and finally transpose to get the arrow. This can save a lot of code.
Control characters, escape sequences and console codes
Unless the question forbids them, the current consensus on Meta is that ASCII art challenges do not require a specific byte stream, but output that looks correct.
This means that we can use ASCII control characters, ANSI escape sequences and Linux console codes in our answers, assuming a supporting terminal.
Unless specified otherwise, the rest of this answer will explain the behavior of Linux terminals, which is what I have available for testing right now.
ASCII control characters
Support/interpretation varies from terminal to terminal and character to character. The most portable one ought to be the linefeed (\n
, \x0a
), which moves the character to the beginning of the next line.
Other useful characters include:
The vertical tab (
\v
,\x0b
) moves the cursor one position to the right, then one position down.$ echo -e 'a\vb' a b
The carriage return (
\r
,\x0d
) moves the cursor to the beginning of the current line. Any subsequent printable character will overwrite the first character of the current line.$ echo -e 'ab\rc' cb
The backspace (
\b
,\x08
) moves the cursor one position to the left. Any subsequent printable character will overwrite the character before the backspace.$ echo -e 'ab\bc' ac
The escape (
\e
,\x1b
) does nothing on its own, but forms part of ANSI escape sequences (optionally) and Linux console codes.
Many languages permit actual control characters in the source code.
ANSI escape sequences
(yet to come)
Linux console codes
While there are many more, the most useful console codes for ASCII art are probably these:
The sequence
\ec
will reset the terminal. This clears the screen, moes the cursor the upper left corner and sets fore- and background color, cursor blinking rate, etc. to their default values.The sequence
\eM
causes a reverse linefeed, i.e., the cursor will move one position up.$ echo -e '\na\eMb\n' b a
The sequence
\eH
sets the tab stop at the current column.$ echo -e ' \eHa\n\tb' a b