Code Golf – Banner Generation

code-golflanguage-agnosticrosetta-stone

When thanking someone, you don't want to just send them an e-mail saying "Thanks!", you want to have something FLASHY:

Input: THANKS!!
Output:
TTT H H AAA N N K K SSS !!! !!! 
 T  H H A A NNN K K S   !!! !!! 
 T  HHH AAA NNN KK  SSS !!! !!! 
 T  H H A A N N K K   S            
 T  H H A A N N K K SSS !!! !!! 

Write a program to generate a banner. You only have to generate upper-case A-Z along with spaces and exclamation points (what is a banner without an exclamation point?). All characters are made up of a 3×5 grid of the same character (so the S is a 3×5 grid made of S). All output should be on one row (so no newlines). Here are all the letters you need:

Input: ABCDEFGHIJKL
Output:
AAA BBB CCC DD  EEE FFF GGG H H III JJJ K K L
A A B B C   D D E   F   G   H H  I    J K K L
AAA BBB C   D D EE  FF  G G HHH  I    J KK  L
A A B B C   D D E   F   G G H H  I  J J K K L
A A BBB CCC DD  EEE F   GGG H H III JJJ K K LLL

Input: MNOPQRSTUVWX
Output:
M M N N OOO PPP QQQ RR  SSS TTT U U V V W W X X
MMM NNN O O P P Q Q R R S    T  U U V V W W  X
M M NNN O O PPP Q Q RR  SSS  T  U U V V WWW  X
M M N N O O P   QQQ R R   S  T  U U V V WWW  X
M M N N OOO P   QQQ R R SSS  T  UUU  V  WWW X X

Input: YZ!
Output:
Y Y ZZZ !!!
Y Y   Z !!!
YYY  Z  !!!
  Y Z
YYY ZZZ !!!

The winner is the shortest source code, as counted by the number of bytes it takes to store the file in utf-8 encoding. Source code should read input from stdin, output to stdout. You can assume input will only contain [A-Z! ]. If you insult the user on incorrect input, you get a 10 character discount =P.

I was going to require these exact 28 characters, but to make it more interesting, you can choose how you want them to look – whatever makes your code shorter! To prove that your letters do look like normal letters, show the output of the last three runs.


Shortest codes so far, in characters (utf8 encoding if non-ASCII present):

133 J

205 Python

209 Ruby

313 Haskell

345 C89

382 F#

Best Answer

J, 133 135 79 83 84 88 characters (utf-8 encoding)

;/5 3$"1(' ',.s){~"1#:3 u:(ucp'翇篭篯礧歮禧禤祯寭璗牯宭䤧彭忭筯篤筿殭秏璒孯孪寿咕寏犧'){~0>.64-~a.i.s=:

Usage:

    ;/5 3$"1(' ',.s){~"1#:3 u:(ucp'翇篭篯礧歮禧禤祯寭璗牯宭䤧彭忭筯篤筿殭秏璒孯孪寿咕寏犧'){~0>.64-~a.i.s=:'ABCDEFGHIJKLMNOPQRSTUVWXYZ !'
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│AAA│BBB│CCC│DD │EEE│FFF│GGG│H H│III│JJJ│K K│L  │M M│N N│OOO│PPP│QQQ│RR │SSS│TTT│U U│V V│W W│X X│Y Y│ZZZ│   │!!!│
│A A│B B│C  │D D│E  │F  │G  │H H│ I │  J│K K│L  │MMM│NNN│O O│P P│Q Q│R R│S  │ T │U U│V V│W W│ X │Y Y│  Z│   │!!!│
│AAA│BBB│C  │D D│EE │FF │G G│HHH│ I │  J│KK │L  │M M│NNN│O O│PPP│Q Q│RR │SSS│ T │U U│V V│WWW│ X │YYY│ Z │   │!!!│
│A A│B B│C  │D D│E  │F  │G G│H H│ I │J J│K K│L  │M M│N N│O O│P  │QQQ│R R│  S│ T │U U│V V│WWW│ X │  Y│Z  │   │   │
│A A│BBB│CCC│DD │EEE│F  │GGG│H H│III│JJJ│K K│LLL│M M│N N│OOO│P  │QQQ│R R│SSS│ T │UUU│ V │WWW│X X│YYY│ZZZ│   │!!!│
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘

    ;/5 3$"1(' ',.s){~"1#:3 u:(ucp'翇篭篯礧歮禧禤祯寭璗牯宭䤧彭忭筯篤筿殭秏璒孯孪寿咕寏犧'){~0>.64-~a.i.s=:'this is incorrect input.'
|index error

Explanation (NB. is comment in J):

;/              NB. String together along the third dimension...
5 3$"1          NB. ... reshape each line to 5x3...
(' ',.s)        NB. ... a space before each letter of the input string...
{~"1            NB. ... indexed using...
#:              NB. ... the (15 bit) binary representation of ...
3 u:            NB. ... the integer representation of...
(ucp'翇篭篯礧歮禧禤祯寭璗牯宭䤧彭忭筯篤筿殭秏璒孯孪寿咕寏犧')  ... the unicode versions of these code points...
{~              NB. ...indexed using...
0>.             NB. ...the max of 0 and...
64-~            NB. ...64 less than...
a.i.            NB. the ascii indexes of s
s=:             NB. Assign the input string to the variable s.