16
\$\begingroup\$

Your goal is to output an ASCII art pie chart. This is code-golf, so the shortest program (counting the bytes of the source code, not the characters) wins.

No external softwares or APIs are allowed. Only the native ones of each language.

The starting angle and the direction (clockwise/anticlockwise) of the circle are not important. The output can look oval because the height of a character is always superior to its width.

The "background" (characters at the left or the right of the pie) must be spaces.

As input, you have three variables (please post the code for initializing it. The initialization of these variables is not counted in your score) :

  • k : Array of characters. Each character is the one which has to be used on the pie chart
  • v : Array of floats. It's the percentage of each character. The length of v is equal to the length of k. The sum of it's elements is always 1.0
  • r : Integer > 1. It's the radius of the pie chart.

Bonus : Subtract 20% of your score if your can output an incomplete pie (in case the \$(\sum_{i=1}^{|v|} v_i)<1\$).

\$\endgroup\$
6
\$\begingroup\$

Python: 255 chars - 20% = 204

from math import*
def s(k,v,a):
 if not v:return ' '
 if a<v[0]:return k[0]
 return s(k[1:],v[1:],a-v[0])
def p(k,v,r):
 d=range(-r,r)
 for y in d:
  t=""
  for x in d:
   if x*x+y*y<r*r:
    a=atan2(y,x)/pi/2+.5
    t=t+s(k,v,a)
   else:t=t+" "
  print t

Examples:

>>> pie.p("ABCD", [0.25,0.125,0.125,0.125],8)

     AAABBBB    
   AAAAABBBBBB  
  AAAAAABBBBBCC
  AAAAAABBBBCCC
 AAAAAAABBBCCCCC
 AAAAAAABBCCCCCC
 AAAAAAABCCCCCCC
        DDDDDDDD
          DDDDDD
           DDDDD
            DDDD
             DD
              D


>>>


>>> pie.p(".$!@", [0.3,0.3,0.3,0.1],6)

   .....$$  
  ......$$$
 ......$$$$$
 ......$$$$$
 ......$$$$$
 @@@@@$$$$$$
 @@@@!!!$$$$
 @@@!!!!!$$$
 @!!!!!!!!!$
  !!!!!!!!!
   !!!!!!!  
>>>
\$\endgroup\$
  • \$\begingroup\$ This can be reduced to 231 bytes by replacing the function s with a lambda s=lambda k,v,a:' 'if not v else k[0]if a<v[0]else s(k[1:],v[1:],a-v[0]) and using a semi-colon to put the if statement on one line if x*x+y*y<r*r:a=atan2(y,x)/pi/2+.5;t=t+s(k,v,a) \$\endgroup\$ – Anonymous No Lifer Jun 25 '16 at 11:07
7
\$\begingroup\$

JavaScript, 259

d=r*2;M=Math;R=M.round;p=[];for(y=0;y<d;y++){p[y]=[];for(x=0;x<d;x++)p[y][x]=" "}t=0;i=-1;for(f=0;f<1;f+=1/(r*20)){if(f>t)t+=v[++i];a=M.PI*2*f;for(j=0;j<r;j++)p[R(M.sin(a)*j)+r][R(M.cos(a)*j)+r]=k[i]}s="";for(y=0;y<d;y++){for(x=0;x<d;x++)s+=p[y][x];s+="\n";}s

Works in Firefox scratchpad.

First example

Input :

var k = ["#", "+",  "$",  "X"];
var v = [0.2, 0.4, 0.15, 0.25];
var r = 10;

Output :

       $$$XXXX      
     $$$$$XXXXXX    
    $$$$$$XXXXXXX   
   $$$$$$$XXXXXXXX  
  +$$$$$$$XXXXXXXXX 
  ++$$$$$$XXXXXXXXX 
 +++++$$$$XXXXXXXXXX
 ++++++$$$XXXXXXXXXX
 +++++++$$XXXXXXXXXX
 +++++++++XXXXXXXXXX
 ++++++++++#########
 +++++++++++########
 +++++++++++########
  ++++++++++####### 
  +++++++++++###### 
   ++++++++++#####  
    +++++++++####   
     ++++++++###    
       +++++++      

Second example :

Input :

var k = ["A",  "B", "C" ];
var v = [0.5, 0.25, 0.25];
var r = 5;

Output :

   BBCCC  
  BBBCCCC 
 BBBBCCCCC
 BBBBCCCCC
 BBBBCCCCC
 AAAAAAAAA
 AAAAAAAAA
  AAAAAAA 
   AAAAA  
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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