Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

I've designed a new font which I call PrettyFont. I've put much much time into perfecting it, but since I'm a working man I don't have time to finish it. Therefore it only contains 4 characters right now. One day when I've become rich it will become my life-long goal to finish it, but for now...

This is PrettyFont: (0, 1, 2, 3)

####  ##  #### ####
#  #   #  #  #    #
#  #   #    #   ###
#  #   #   #      #
####  ### #### ####

Each character is 4 pixels wide and 5 pixels high. Now! I want you to write me a program that outputs a number in PrettyFont so I can start sending designs to print.

Rules:

The input is a string number in base 4 (only characters 0-3), for example "01321". The program should be able to handle at least 10 characters in the string. BONUS points is given to the program that takes an actual base 10 integer instead of a string. EDIT clarification: the integer bonus means that one can enter any base 10 number, like 54321, and the program will convert it to base 4 and output it (in this case 31100301).

The output will be the number printed with PrettyFont. Example input and output:

> "321"
####
   #
 ###
   #
####

####
#  #
  # 
 #  
####

 ## 
  # 
  # 
  # 
 ###

Huge bonus to the program that can output it in a single row-fashion like this:

> "321"
#### ####  ## 
   # #  #   # 
 ###   #    # 
   #  #     # 
#### ####  ### 

The '#' character is not a requirement, and can be replaced by any character.

In vertical output, an empty row is required between each PrettyFont character. If anyone makes the horizontal output, one white space character ' ' or a tab character is required between each PrettyFont character.

This is code golf, shortest code wins! (I need it short because my office computer has limited storage.)

share|improve this question
1  
It's not exactly a duplicate, but the only fundamental difference between this and codegolf.stackexchange.com/questions/3628/… is the lookup table. –  Peter Taylor Aug 10 '12 at 18:11
1  
+1 to this just for the first paragraph :D –  daniero Aug 10 '12 at 19:17
    
PrettierFont - banner -c '#' 0123 –  Drake Clarris Aug 10 '12 at 19:58
1  
with 4 pixels wide you're gonna have issues with 'M' –  Cameron MacFarland Aug 12 '12 at 1:38
    
How many chars is bonus for taking 10 base number as input? –  mlatu Aug 12 '12 at 4:44
show 1 more comment

10 Answers 10

up vote 11 down vote accepted

k (118 117 72 71 69 66 chars)

I haven't made much of an effort to golf this yet but it achieves the desired horizontal output in not too many chars:

-1'" "/:'+(5 4#/:4 20#"# "@,/0b\:'0x066609ddd806db00e8e0)"I"$'0:0;

Takes input from stdin, prints output to stdout.

edit: By implementing a form of compression on the output "bitmap", I've reduced it to 72. The bitmap is now built by converting 64bit ints to binary and mapping the 0s and 1s to "#" or " ". I could do it from hex like a few of the other solutions but I think this would end up longer. Turns out hex is better.

Sample output for 012301:

####  ##  #### #### ####  ##
#  #   #  #  #    # #  #   #
#  #   #    #   ### #  #   #
#  #   #   #      # #  #   #
####  ### #### #### ####  ###

//edit: -6 char

share|improve this answer
    
Impressive. Shortest code yet! It might fit on my limited storage drive. Good job. –  Accatyyc Aug 10 '12 at 18:10
    
Down to 71. Given that the combined kdb+/q/k exe weighs in at a slim 392kB, this might be ideal for your limited storage drive ;) –  slackwear Aug 10 '12 at 18:58
add comment

Python3 (124)

s=input();[print(*["".join(" #"[0xf171ff429f72226f999f>>(20*int(x)+4*y+i)&1]for i in(3,2,1,0))for x in s])for y in range(5)]

Sorry, vertical was not interesting for me.

???/golf.py
1230012301203012030102301230
 ##  #### #### #### ####  ##  #### #### ####  ##  #### #### #### ####  ##  #### #### #### ####  ##  #### #### #### ####  ##  #### #### ####
  #  #  #    # #  # #  #   #  #  #    # #  #   #  #  # #  #    # #  #   #  #  # #  #    # #  #   #  #  # #  #    # #  #   #  #  #    # #  #
  #    #   ### #  # #  #   #    #   ### #  #   #    #  #  #  ### #  #   #    #  #  #  ### #  #   #  #  #   #   ### #  #   #    #   ### #  #
  #   #      # #  # #  #   #   #      # #  #   #   #   #  #    # #  #   #   #   #  #    # #  #   #  #  #  #      # #  #   #   #      # #  #
 ### #### #### #### ####  ### #### #### ####  ### #### #### #### ####  ### #### #### #### ####  ### #### #### #### ####  ### #### #### ####
share|improve this answer
    
Awesome one! Didn't expect so few characters for the horizontal one. Nice job. –  Accatyyc Aug 10 '12 at 18:05
1  
Thx. I guess my idea (hex-number and shifts) should be even shorter in Ruby implementation. –  Ev_genus Aug 10 '12 at 18:07
add comment

J, 84 82 81 80 75 69 characters

' #'{~(,4,.(4*".,' ',.1!:1[1)+/i.4){"1#:63231 37521 37415 37441 63487

Takes input from the keyboard:

   ' #'{~(,4,.(4*".,' ',.1!:1[1)+/i.4){"1#:63231 37521 37415 37441 63487 63487
0123210
 ####  ##  #### #### ####  ##  ####
 #  #   #  #  #    # #  #   #  #  #
 #  #   #    #   ###   #    #  #  #
 #  #   #   #      #  #     #  #  #
 ####  ### #### #### ####  ### ####

Magic numbers FTW (or for the second place in this case) :-)

share|improve this answer
    
Very nice... very nice... I'm impressed! Many good answers today. Maybe my designer-prints will turn out fine. –  Accatyyc Aug 10 '12 at 20:46
    
You could encode all digits into one binary number and do a reshape on the result to get the corresponding number matrices. –  FUZxxl Aug 11 '12 at 20:04
    
@FUZxxl I did try to find the number for the full 80 bits, but #: didn't seem to work for that size of number. #:1166416635908028473935870 and #:1166416635908028473931775 both give the same answer for me. –  Gareth Aug 12 '12 at 8:35
add comment

C - 164 151 characters horizontal

On IDEone: http://ideone.com/gljc3

The code (164 bytes):

i,j;main(){char n[99];gets(n);for(;j<5;++j){for(i=0;n[i];++i)printf("%.4s ","#####  # ##   #  ### #     #"+4*("01110233340135006460"[(n[i]-48)*5+j]-48));puts("");}}

enter image description here

EDIT - 151 bytes

I added the suggestions from the comments and then some. It isn't exactly safe (0-length array that I gets() in to...) though.

char i,j=5,n[];main(){for(gets(n);j--;)for(i=puts("");n[i];printf("%.4s ","#####  # ##   #  ### #     #"+4*(0x1A600BA136E0248>>15*n[i++]-720+3*j&7)));}

Note, i=puts("") is undefined behavior since I'm treating void as int! It consistently returns 0 on my version of MinGW, but it returns 1 on the compiler IDEOne uses.

Accepts decimal, outputs base 4 (167 bytes)

char i,j=5,n[];main(p){for(itoa(atoi(gets(n)),n,4);j--;)for(i=puts("");n[i];printf("%.4s ","#####  # ##   #  ### #     #"+4*(0x1A600BA136E0248>>15*n[i++]-720+3*j&7)));}
share|improve this answer
    
Ooh, a short one in C! That will surely run in under a minute on my old CPU. Good one. –  Accatyyc Aug 11 '12 at 7:33
    
Couldn't you save 3 chars by removing "!=0"? –  a3nm Aug 11 '12 at 21:20
    
Yea, thanks. I didn't catch that one. –  Kaslai Aug 12 '12 at 0:11
    
Put gets within for (save 1). Move puts to the external for's increment and save braces. Save paranthesis: (n[i]-48)*5+j->n[i]*5-240+j, same trick with +4*(... –  ugoren Aug 12 '12 at 10:03
    
Okay down to 153 bytes. Not too bad for C I guess. –  Kaslai Aug 13 '12 at 2:53
show 2 more comments

Ruby, 0123 chars + a bonus ([0123] vs '#')

f=15
0.upto(4){|n|$*[0].chars{|x|$><<"%4s "%eval(:f6ff929192279241f7ff[x.to_i+4*n]).to_i.to_s(2).tr(?0,' ').tr(?1,x)}
puts}

Example:

% ruby ./font.rb 01231231
0000  11  2222 3333  11  2222 3333  11  
0  0   1  2  2    3   1  2  2    3   1  
0  0   1    2   333   1    2   333   1  
0  0   1   2      3   1   2      3   1  
0000  111 2222 3333  111 2222 3333  111
% ruby ./font.rb 01231231102020103201301203212302230
0000  11  2222 3333  11  2222 3333  11   11  0000 2222 0000 2222 0000  11  0000 3333 2222 0000  11  3333 0000  11  2222 0000 3333 2222  11  2222 3333 0000 2222 2222 3333 0000 
0  0   1  2  2    3   1  2  2    3   1    1  0  0 2  2 0  0 2  2 0  0   1  0  0    3 2  2 0  0   1     3 0  0   1  2  2 0  0    3 2  2   1  2  2    3 0  0 2  2 2  2    3 0  0 
0  0   1    2   333   1    2   333   1    1  0  0   2  0  0   2  0  0   1  0  0  333   2  0  0   1   333 0  0   1    2  0  0  333   2    1    2   333 0  0   2    2   333 0  0 
0  0   1   2      3   1   2      3   1    1  0  0  2   0  0  2   0  0   1  0  0    3  2   0  0   1     3 0  0   1   2   0  0    3  2     1   2      3 0  0  2    2      3 0  0 
0000  111 2222 3333  111 2222 3333  111  111 0000 2222 0000 2222 0000  111 0000 3333 2222 0000  111 3333 0000  111 2222 0000 3333 2222  111 2222 3333 0000 2222 2222 3333 0000 

EDIT: Ruby, 87 chars

0.upto(4){|n|$*[0].bytes{|x|$><<"%04b0"%:f6ff929192279241f7ff[x-48+4*n].to_i(16)}
puts}

enter image description here

share|improve this answer
    
A creative one! Very nice. This will look fabulous in my designs. Have an upvote. –  Accatyyc Aug 11 '12 at 7:31
    
Tricky! Will take me some time to understand it. –  manatwork Aug 13 '12 at 15:30
add comment

Ruby

Vertical: 116 characters

f="f999f62227f924ff171f".chars.map{|c|c.hex.to_s(2).rjust(4).tr"01"," #"}
$<.chars{|c|i=c.to_i*5;$><<f[i,5]*$/+$/*2}

Sample run:

bash-4.2$ echo -n 321 | ruby -e 'f="f999f62227f924ff171f".chars.map{|c|c.hex.to_s(2).rjust(4).tr"01"," #"};$<.chars{|c|i=c.to_i*5;$><<f[i,5]*$/+$/*2}'
####
   #
 ###
   #
####

####
#  #
  # 
 #  
####

 ## 
  # 
  # 
  # 
 ###

Horizontal: 150 148 characters

f="f999f62227f924ff171f".chars.map{|c|c.hex.to_s(2).rjust(4).tr"01"," #"}
o=(0..4).map{""}
$<.chars{|c|5.times{|j|o[j]<<f[c.to_i*5+j]+" "}}
$><<o*$/

Sample run:

bash-4.2$ echo -n 321 | ruby -e 'f="f999f62227f924ff171f".chars.map{|c|c.hex.to_s(2).rjust(4).tr "01"," #"};o=(0..4).map{""};$<.chars{|c|5.times{|j|o[j]<<f[c.to_i*5+j]+" "}};$><<o*$/'
#### ####  ##  
   # #  #   #  
 ###   #    #  
   #  #     #  
#### ####  ### 
share|improve this answer
    
I was going to encode it like that. Don't think I can beat this is my language though! –  Griffin Aug 10 '12 at 16:34
add comment

Mathematica 174 145 139 118 119 123 chars

Now works with input in base 10 (Integer bonus). Earlier versions can be found in edits.


Using ArrayPlot:

With ArrayPlot we can directly convert the 1's and 0's to black and white squares, saving a few chars in the process. For example, with n = 58021, which is 32022211 in base 4:

i = IntegerDigits; i[n, 4] /. Thread@Rule[0~Range~3, ArrayPlot /@ ((PadLeft[#, 4] & /@ i[#, 2]) & /@ (i@{89998, 62227, 89248, 81718} /. {8 -> 15}))]

integer bonus


Explanation

Input is program parameter, n.

Zero can be represented by {{1,1,1,1},{1,0,0,1},{1,0,0,1},{1,0,0,1},{1,1,1,1} or by the hex counterpart f999f.

The expression, f999f62227f924ff171f, holds the information to display all the numbers {0,1,2,3}. (Note: it begins with f999f, which as we noted, is zero in disguise.) Because Mathematica does not recognize this as a number, I used 89998622278924881718 (in four integer strings) instead, broke up the number into its integer digits, and then used 15 in every place an 8 appeared. (That allowed me to use digits instead of strings throughout.)

share|improve this answer
1  
Your output doesn't match the input. –  Mr Lister Aug 10 '12 at 17:28
    
Can't you just transpose that for the vertical bonus? –  Griffin Aug 10 '12 at 17:36
    
As I understand the rules, the bonus is for the horizontal configuration. –  David Carraher Aug 10 '12 at 20:34
    
Mr. Lister Good catch. I copied and pasted the picture of zero in the place of 1. –  David Carraher Aug 10 '12 at 20:35
    
My bad, misread. –  Griffin Aug 10 '12 at 21:39
show 7 more comments

Mathematica, 112 107 103

My take on David's method.

i=IntegerDigits;Grid/@i@n/.Thread[0~Range~3->("#"i[i@#/.8->15,2,4]&/@{89998,62227,89248,81718}/.0->"")]

Mathematica graphics

105 with the BONUS:

(for n = 54321)

i=IntegerDigits;Grid/@n~i~4/.Thread[0~Range~3->("#"i[i@#/.8->15,2,4]&/@{89998,62227,89248,81718}/.0->"")]

Mathematica graphics

share|improve this answer
    
Very nice indeed. So few characters with the bonus. Good work! –  Accatyyc Aug 12 '12 at 17:02
add comment

Python 2.7

Vertical 160

for i in input():print['****\n*  *\n*  *\n*  *\n****',' ** \n  * \n  * \n  * \n***','****\n*  *\n  * \n *  \n****','****\n   *\n ***\n   *\n****'][int(i)]+'\n'

Horizontal 234 216

x=[['****\n*  *\n*  *\n*  *\n****',' ** \n  * \n  * \n  * \n ***','****\n*  *\n  * \n *  \n****','****\n   *\n ***\n   *\n****'][int(i)]for i in input()]
for i in range(5):print' '.join([y.split('\n')[i]for y in x])

Both take input as a quoted string on stdin

example:
$./pretty
"0123"

share|improve this answer
    
How you run this? I get errors. Python 2: "TypeError: 'int' object is not iterable", Python 3: "TypeError: 'builtin_function_or_method' object is not subscriptable". –  manatwork Aug 10 '12 at 16:57
    
@manatwork This is in python 2.7, I have edited the answer to make that clear. –  Matt Aug 10 '12 at 17:07
    
@manatwork Also, it looks like you may have been entering the numbers without quotes around them ie: 0123. You should try entering "0123" on stdin. –  Matt Aug 10 '12 at 17:18
    
Got it working now. Sorry, that quoting trick was not evident for me. –  manatwork Aug 10 '12 at 17:32
    
@manatwork in python versions before 3 the input() function evaluates the input as if it were a python expression. If the quotes are not there, the program tries to iterate over an integer, giving you the error you got. –  Matt Aug 10 '12 at 17:42
add comment

APL (58 57)

{' #'[1+5 4⍴1022367 401959 1020495 988959[1+⍎⍵]⊤⍨20⍴2]}¨⍞

Output:

0123
 ####   ##   ####  #### 
 #  #    #   #  #     # 
 #  #    #     #    ### 
 #  #    #    #       # 
 ####   ###  ####  #### 
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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