Tell me more ×
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.

well, it's something similar to this question but with a little differences. you have to write a program to ask for width of progress bar and how much work is done. and then draw a progress bar with following features:

  • width indicates how many characters you have to use to draw progress bar

  • progress is given via a floating point value between 0..1.

  • first and last character in progress bar should be something different from all other character, for example "[" and "]"

  • your program should use two different characters to how much progress passed sine the start

  • you have to write how much work is done right in the middle of progress bar, using a decimal number + "%" sign.

bonus point for handling extreme inputs, such as 150% or -5% work done.

scoring number of characters * (1 without bonus or 0.75 width bonus)

some examples of valid outputs

79 0.15
[||||||||||||                         15%                                     ]

25 0.76
[##########76%#####.....]

39 -0.12
[                 -12%                 ]

25 7.6
[##########760%#########]
share|improve this question
How is input taken? Command line? Stdin? Any of the above? – lochok Apr 2 '12 at 3:33
@lochok I guess stdin would be a better choice. – Gajoo Apr 2 '12 at 3:38

11 Answers

up vote 1 down vote accepted

PHP 84 x 0.75 = 63

Edit: A less 'pretty' version, but it should be valid according to the rules:

[<?=str_pad(!fscanf(STDIN,~Ú›Ú™,$a,$b),$a*min(1,$b),~ß)|str_pad(100*$b.~Ú,$a,_,2)?>]

Output:

$ echo 79 0.15 | php progress-bar.php
[⌂⌂⌂⌂⌂⌂⌂⌂⌂⌂⌂___________________________15%______________________________________]
$ echo 25 0.76 | php progress-bar.php
[⌂⌂⌂⌂⌂⌂⌂⌂⌂⌂⌂76%⌂⌂⌂⌂⌂______]
$ echo 39 -0.12 | php progress-bar.php
[_________________-12%__________________]
$ echo 25 7.6 | php progress-bar.php
[⌂⌂⌂⌂⌂⌂⌂⌂⌂⌂760%⌂⌂⌂⌂⌂⌂⌂⌂⌂⌂⌂]


Original (98 x 0.75 = 73.5)

[<?=strtr(str_pad(!fscanf(STDIN,~Ú›Ú™,$a,$b),$a*min(1,$b),~ß)|str_pad(100*$b.~Ú,$a,~ü,2),~ü,~ß)?>]

Output:

$ echo 79 0.15 | php progress-bar.php
[###########                           15%                                      ]
$ echo 25 0.76 | php progress-bar.php
[###########76%#####      ]
$ echo 39 -0.12 | php progress-bar.php
[                 -12%                  ]
$ echo 25 7.6 | php progress-bar.php
[##########760%###########]
share|improve this answer
I'm wondering how can I run your code. – Gajoo May 9 '12 at 8:36
Save it as a php file. Send it the two paramaters as a space separated string as STDIN. For example: [windows/linux command prompt] echo 79 0.15 | php progress-bar.php You will need to have the php-cli (command line interface) installed. Most php installers for windows should have it included (or optional), linux with apt-get install php5-cli – primo May 9 '12 at 13:07
I've selected this answer since as far as I tested this one always worked as expected, while one that ephemient provided sometimes doesn't print the number exactly in the middle. – Gajoo May 9 '12 at 20:35

J, 78×0.75 = 58.5

'w p'=:_".1!:1]3
1!:2&4('%',~":100*p)(i.@[-<.@-:@-)&#}'[]'0 _1}' |'{~(w*p)>i.w
$ echo -n 79 0.15 | jconsole test.ijs
[|||||||||||                          15%                                     ]
$ echo -n 25 0.76 | jconsole test.ijs
[||||||||||76%|||||     ]   
$ echo -n 39 -0.12
[                 _12%                ]
$ echo -n 25 7.6 | jconsole test.ijs
[|||||||||760%||||||||||]   

(Negative numbers in J are prefixed by _, not -. Luckily, dyadic ". can parse both formats.)

share|improve this answer
Does this exclude the space taken by the percentage when it calculates the number of bars to display? Cause it seems to get different results from mine. – grc Apr 3 '12 at 0:41
@grc With 100 columns, each percent is a single bar (even if hidden by other elements such as the brackets or number/percent). – ephemient Apr 3 '12 at 1:49
Okay I get it now. Good job :) – grc Apr 3 '12 at 2:04
@ephemient now I've noticed in -0.12 case, you are printing 18 spaces at left part and 16 at right part. it means _12% is not exactly in the middle. – Gajoo Apr 25 '12 at 18:09

Perl, 96×¾ = 72

#!/usr/bin/perl -ap
formline'[@'.'|'x($F[0]-3).']',100*$F[1].'%';
$_=$^A;s# |(.)#$1//($-[0]<$F[0]*$F[1]?'|':$&)#eg

That's by traditional Perl golf rules (#! line not counted, except for the - and switches if any).

$ echo 79 0.15 | perl test.pl
[|||||||||||                          15%                                     ]
$ echo 25 0.76 | perl test.pl
[||||||||||76%|||||     ]
$ echo 39 -0.12 | perl test.pl
[                -12%                 ]
$ echo 25 7.6 | perl test.pl
[|||||||||760%||||||||||]
share|improve this answer

Ruby - score 93 (124 characters)

w=gets.to_i-2
f=$_[/ .+/].to_f
e=f<0?0:f>1?w:(f*w).to_i
b='#'*e+' '*(w-e)
b[(w-l=(s='%d%'%(100*f)).size)/2,l]=s
puts"[#{b}]"

Yet another ruby implementation. Reads input from STDIN in the form described above. You may exchange characters '#', ' ' and '[', ']' directly in the code.

45 0.88
[####################88%##############      ]

60 1.22
[###########################122%###########################]
share|improve this answer
this is alway two chars too wide – padde Apr 26 '12 at 8:07
@padde Why do you think it's two chars too wide? There is a -2 in the first line. – Howard Apr 27 '12 at 0:25

Python - 158 155 148 143 138 characters (score of 103.5)

x,y=raw_input().split()
x=int(x)-2
y=float(y)
p=`int(y*100)`+"%"
b="|"*int(x*y+.5)+" "*x
print"["+b[:(x-len(p))/2]+p+b[(x+len(p))/2:x]+"]"

It could be 30 characters shorter if the input was separated by a comma.

share|improve this answer
why didn't you use r=p.length()? – Gajoo Apr 2 '12 at 7:09
what do you mean? – grc Apr 3 '12 at 0:17
nothing my bad, I just misunderstood you code. – Gajoo Apr 3 '12 at 0:24
but your code doesn't seem to handle -12% case. – Gajoo Apr 3 '12 at 0:25
What is it meant to do? At the moment it just prints an empty bar with the percentage. – grc Apr 3 '12 at 0:27
show 4 more comments

Q,90 chars, no bonus

{-1 @[x#" ";(1+(!)(_)x*y;0;((_)x%2)+(!)(#)($)a;x-1);:;("|";"[";a:,[;"%"]($)(100*y);"]")];}

usage

q){-1 @[x#" ";(1+(!)(_)x*y;0;((_)x%2)+(!)(#)($)a;x-1);:;("|";"[";a:,[;"%"]($)(100*y);"]")];}[50;0.15]
[|||||||                 15%                     ]

q){-1 @[x#" ";(1+(!)(_)x*y;0;((_)x%2)+(!)(#)($)a;x-1);:;("|";"[";a:,[;"%"]($)(100*y);"]")];}[30;0.35]
[||||||||||    35%           ]

q){-1 @[x#" ";(1+(!)(_)x*y;0;((_)x%2)+(!)(#)($)a;x-1);:;("|";"[";a:,[;"%"]($)(100*y);"]")];}[40;0.85]
[|||||||||||||||||||85%||||||||||||    ]
share|improve this answer

Scala 149:

val w=readInt 
val p=readFloat
println(("["+"|"*(p*w).toInt+" "*((w-p*w).toInt)+"]").replaceAll("(^.{"+(w/2-3)+"}).{5}","$1 "+(p*100).toInt+("% ")))

ungolfed:

def progressbar (width: Int, pos: Double) {
  println ((
    "["+
    "|"*(pos*width).toInt+
    " "*((width-pos*width).toInt)+
    "]").
    replaceAll ("(^.{" + (width/2-3) + "}).{5}", "$1 " + (p * 100).toInt + ("% ")))}
}

I decided, for readability, you really need a space around the progress number:

(44 to 54).map (x => b (100, x/100.0))
[||||||||||||||||||||||||||||||||||||||||||||   44%                                                  ]
[|||||||||||||||||||||||||||||||||||||||||||||  45%                                                  ]
[|||||||||||||||||||||||||||||||||||||||||||||| 46%                                                  ]
[|||||||||||||||||||||||||||||||||||||||||||||| 47%                                                  ]
[|||||||||||||||||||||||||||||||||||||||||||||| 48%                                                  ]
[|||||||||||||||||||||||||||||||||||||||||||||| 49%                                                  ]
[|||||||||||||||||||||||||||||||||||||||||||||| 50%                                                  ]
[|||||||||||||||||||||||||||||||||||||||||||||| 51%                                                  ]
[|||||||||||||||||||||||||||||||||||||||||||||| 52% |                                                ]
[|||||||||||||||||||||||||||||||||||||||||||||| 53% ||                                               ]
[|||||||||||||||||||||||||||||||||||||||||||||| 54% |||                                              ]
share|improve this answer

C, 145 characters, score = 108.75

float p;s;m;char x[99];main(){scanf("%d%f",&s,&p);sprintf(x+s/2-1,"%.0f%%",p*100);for(;m<s;)x[++m]||(x[m]=m<p*s?35:32);x[s-1]=93;*x=91;puts(x);}
share|improve this answer
though I really liked your idea of sprintf, but it generates a minor problem, check your program with 20 1 inputs it will generate output of [#######100%######] in this case there are 7 sharps left of number and 5 sharps at right, so the number printed is not exactly in the middle. – Gajoo Apr 4 '12 at 23:12

node.js: 135chars, *0.75 for bonus points, so 101.25chars.

a=process.argv,i=a[2],p=a[3],o=i/2|0,f=i-i*p,x=['['];for(;i--;){x.push((i<f?' ':'|')+(i-o?'':p*100+'%'));}console.log(x.join('')+']');

ungolfed:

a = process.argv, // console inputs
i = a[2], // input 1 -> width
p = a[3], // input 2 -> percent complete
o = i / 2 | 0, // half of i, without any decimal places
f = i - i * p, // how far along the bar to draw spaces
x = ['[']; // start an array
while(i--){ // while i > 0
    x.push( // add to the array
    (i < f ? ' ' : '|') // a space, or | depending on how far along the bar we are
    + (i - o ? '' : p * 100 + '%')); // and if we're halfway, add the percentage complete
}
console.log(x.join('') + ']'); // then write out the array as a string, with a trailing ]

output:

D:\mercurial\golf\ascii>node progressBar.js 25 7.6
[|||||||||||||760%||||||||||||]

D:\mercurial\golf\ascii>node progressBar.js 39 -0.12
[                    -12%                   ]

D:\mercurial\golf\ascii>node progressBar.js 79 0.15
[|||||||||||                             15%                                       ]
share|improve this answer

PHP-128x0.75=>96

<?fscanf(STDIN,'%d%d',$w,$p);$v='[';for($i=1;$i<$w-1;)$v.=($i++==$w/2-1)?$p*($i+=2)/$i.'%':(($i<$w*$p/100)?'|':' ');echo"$v]";?>

<?fscanf(STDIN,'%d%f',$w,$p);$v='[';for($i=1;$i<$w-1;)$v.=($i++==$w/2-1)?$p*100*($i+=2)/$i.'%':(($i<$w*$p)?'|':' ');echo"$v]";?>

C, 149*0.75=111.75

main(w,i){float p;for(i=printf("[",scanf("%d%f",&w,&p));i<w-1;)(i++==w/2-1)?printf("%.0f%%",p*100*(i+=2)/i):printf("%c",i<=(p*w)?'|':' ');puts("]");}

Output:

80
0.75
[||||||||||||||||||||||||||||||||||||||75%||||||||||||||||||                   ]

80
7.60
[||||||||||||||||||||||||||||||||||||||760%|||||||||||||||||||||||||||||||||||||]


80
-0.12
[                                      -12%                                     ]
share|improve this answer
p should be a floating point value, between 0..1 – Gajoo Apr 11 '12 at 14:21
@Gajet thanks for bringing to notice. Has been rectified :) – l0n3_sh4rk Apr 11 '12 at 19:26

JavaScript 127 125, no bonus

l=9,p="0.99",f=l*p|0,m=l/2|0,x=["]"];for(;l--;)x.unshift(l>=f?"-":"+");x[m++]=p[2],x[m++]=p[3],x[m]="%";alert("["+x.join(""))
//[+++99%++-]

Usage: Change l=9 with other length and/or change p="0.99" with other percent

Note: end with zero 0.X0 instead of 0.X

share|improve this answer

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.