12
\$\begingroup\$

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 since 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%#########]
\$\endgroup\$
2
  • \$\begingroup\$ How is input taken? Command line? Stdin? Any of the above? \$\endgroup\$
    – lochok
    Apr 2, 2012 at 3:33
  • \$\begingroup\$ @lochok I guess stdin would be a better choice. \$\endgroup\$
    – Ali1S232
    Apr 2, 2012 at 3:38

13 Answers 13

4
\$\begingroup\$

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.)

\$\endgroup\$
4
  • \$\begingroup\$ 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. \$\endgroup\$
    – grc
    Apr 3, 2012 at 0:41
  • \$\begingroup\$ @grc With 100 columns, each percent is a single bar (even if hidden by other elements such as the brackets or number/percent). \$\endgroup\$
    – ephemient
    Apr 3, 2012 at 1:49
  • \$\begingroup\$ Okay I get it now. Good job :) \$\endgroup\$
    – grc
    Apr 3, 2012 at 2:04
  • \$\begingroup\$ @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. \$\endgroup\$
    – Ali1S232
    Apr 25, 2012 at 18:09
3
\$\begingroup\$

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%###########]
\$\endgroup\$
3
  • \$\begingroup\$ I'm wondering how can I run your code. \$\endgroup\$
    – Ali1S232
    May 9, 2012 at 8:36
  • \$\begingroup\$ 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 \$\endgroup\$
    – primo
    May 9, 2012 at 13:07
  • \$\begingroup\$ 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. \$\endgroup\$
    – Ali1S232
    May 9, 2012 at 20:35
3
\$\begingroup\$

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%||||||||||]
\$\endgroup\$
2
\$\begingroup\$

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%###########################]
\$\endgroup\$
2
  • \$\begingroup\$ this is alway two chars too wide \$\endgroup\$ Apr 26, 2012 at 8:07
  • \$\begingroup\$ @padde Why do you think it's two chars too wide? There is a -2 in the first line. \$\endgroup\$
    – Howard
    Apr 27, 2012 at 0:25
2
\$\begingroup\$

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.

\$\endgroup\$
9
  • \$\begingroup\$ why didn't you use r=p.length()? \$\endgroup\$
    – Ali1S232
    Apr 2, 2012 at 7:09
  • \$\begingroup\$ what do you mean? \$\endgroup\$
    – grc
    Apr 3, 2012 at 0:17
  • \$\begingroup\$ nothing my bad, I just misunderstood you code. \$\endgroup\$
    – Ali1S232
    Apr 3, 2012 at 0:24
  • \$\begingroup\$ but your code doesn't seem to handle -12% case. \$\endgroup\$
    – Ali1S232
    Apr 3, 2012 at 0:25
  • \$\begingroup\$ What is it meant to do? At the moment it just prints an empty bar with the percentage. \$\endgroup\$
    – grc
    Apr 3, 2012 at 0:27
1
\$\begingroup\$

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%||||||||||||    ]
\$\endgroup\$
1
\$\begingroup\$

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% |||                                              ]
\$\endgroup\$
1
\$\begingroup\$

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);}
\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$
    – Ali1S232
    Apr 4, 2012 at 23:12
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

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%                                       ]
\$\endgroup\$
1
\$\begingroup\$

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%                                     ]
\$\endgroup\$
2
  • \$\begingroup\$ p should be a floating point value, between 0..1 \$\endgroup\$
    – Ali1S232
    Apr 11, 2012 at 14:21
  • \$\begingroup\$ @Gajet thanks for bringing to notice. Has been rectified :) \$\endgroup\$
    – l0n3sh4rk
    Apr 11, 2012 at 19:26
0
\$\begingroup\$

MATL, score 35.25 (47 * 0.75)

qqtl&O61bti*Xl:(HG100*V37hyn2/kyny+q&:(91w93v!c

Try it online!

Explanation:

         % implicit input, say w = 79
qq       % decrement input by 2 (to allow brackets on either side)
tl&O     % duplicate and create array with that many zeros
61       % Push '=' character
b        % bubble up w-2 from below
ti*      % duplicate and multiply by second input, say p = 0.15
         %  stack: [[0;0;0;...;0], 61, 77, 11.55]
Xl       % take minimum of (w-2) and (w-2)*p
         %  (used when p > 1, makes eligible for bonus)
:        % create range 1 to that value 
         %  stack: [[0;0;0;...;0], 61, [1 2 3 4 5 ... 11]]
(        % assign into the first array the value 61 ('=') at the 
         %  indices denoted by the third array
HG       % push second input again
100*V    % multiply by 100 and convert to string
37h      % append the '%' symbol to it
yn2/k    % compute half of the length of the output array
yny+q    % copy of that + length of the 'N%' string - 1
         % stack: [[61;61;61;...;0;0;0], '15%', 38, 40]
&:       % make a range from the first to the second (38 to 40)
(        % assign the 'N%' string at those places into the output array
91w93    % surround by '[' (ASCII 91) and ']' (93) characters
v!       % combine into a single array, make it horizontal for display, 
c        % change it to character type (implicitly displayed)
\$\endgroup\$
0
\$\begingroup\$

Excel VBA, 108*.75 = 81 bytes

A function that takes input from [A1] and [B1] and outputs to the console

s=""&[MID(IFERROR(REPT("",A1*B1),"")&REPT("",A1),2,A1-2)]&"":n=100*[B1]:Mid(s,([A1]-len(n))/2)=n &"%":?s

Output

with input [A1]=25 and [B1]=.76

76%

With input [A1:B1].Resize(1,2)=Split("32 -.5")

-50%

With input [A1:B1].Resize(1,2)=Split("40 10.01")

1001%
\$\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.