Code Golf - π day
-
19-09-2019 - |
Question
The Challenge
Guidelines for code-golf on SO
The shortest code by character count to display a representation of a circle of radius R
using the *
character, followed by an approximation of π.
Input is a single number, R
.
Since most computers seem to have almost 2:1 ratio you should only output lines where y
is odd. This means that when R
is odd you should print R-1
lines. There is a new testcase for R=13
to clarify.
eg.
Input
5
Output Correct Incorrect
3 ******* 4 *******
1 ********* 2 *********
-1 ********* 0 ***********
-3 ******* -2 *********
2.56 -4 *******
3.44
Edit: Due to widespread confusion caused by odd values of R
, any solutions that pass the 4 test cases given below will be accepted
The approximation of π is given by dividing twice the number of *
characters by R²
.
The approximation should be correct to at least 6 significant digits.
Leading or trailing zeros are permitted, so for example any of 3
, 3.000000
, 003
is accepted for the inputs of 2
and 4
.
Code count includes input/output (i.e., full program).
Test Cases
Input
2
Output
***
***
3.0
Input
4
Output
*****
*******
*******
*****
3.0
Input
8
Output
*******
*************
***************
***************
***************
***************
*************
*******
3.125
Input
10
Output
*********
***************
*****************
*******************
*******************
*******************
*******************
*****************
***************
*********
3.16
Bonus Test Case
Input
13
Output
*************
*******************
*********************
***********************
*************************
*************************
*************************
*************************
***********************
*********************
*******************
*************
2.98224852071
Solution
In dc: 88 and 93 93 94 96 102 105 129 138 141 chars
Just in case, I am using OpenBSD and some supposedly non-portable extensions at this point.
93 chars. This is based on same formula as FORTRAN solution (slightly different results than test cases). Calculates X^2=R^2-Y^2 for every Y
[rdPr1-d0<p]sp1?dsMdd*sRd2%--
[dd*lRr-vddlMr-32rlpxRR42r2*lpxRRAP4*2+lN+sN2+dlM>y]
dsyx5klNlR/p
88 chars. Iterative solution. Matches test cases. For every X and Y checks if X^2+Y^2<=R^2
1?dsMdd*sRd2%--sY[0lM-[dd*lYd*+lRr(2*d5*32+PlN+sN1+dlM!<x]dsxxAPlY2+dsYlM>y]
dsyx5klNlR/p
To run dc pi.dc
.
Here is an older annotated version:
# Routines to print '*' or ' '. If '*', increase the counter by 2
[lN2+sN42P]s1
[32P]s2
# do 1 row
# keeping I in the stack
[
# X in the stack
# Calculate X^2+Y^2 (leave a copy of X)
dd*lYd*+
#Calculate X^2+Y^2-R^2...
lR-d
# .. if <0, execute routine 1 (print '*')
0>1
# .. else execute routine 2 (print ' ')
0!>2
# increment X..
1+
# and check if done with line (if not done, recurse)
d lM!<x
]sx
# Routine to cycle for the columns
# Y is on the stack
[
# push -X
0lM-
# Do row
lxx
# Print EOL
10P
# Increment Y and save it, leaving 2 copies
lY 2+ dsY
# Check for stop condition
lM >y
]sy
# main loop
# Push Input value
[Input:]n?
# Initialize registers
# M=rows
d sM
# Y=1-(M-(M%2))
dd2%-1r-sY
# R=M^2
d*sR
# N=0
0sN
[Output:]p
# Main routine
lyx
# Print value of PI, N/R
5klNlR/p
OTHER TIPS
C: 131 chars
(Based on the C++ solution by Joey)
main(i,j,c,n){for(scanf("%d",&n),c=0,i|=-n;i<n;puts(""),i+=2)for(j=-n;++j<n;putchar(i*i+j*j<n*n?c++,42:32));printf("%g",2.*c/n/n);}
(Change the i|=-n
to i-=n
to remove the support of odd number cases. This merely reduces char count to 130.)
As a circle:
main(i,j,
c,n){for(scanf(
"%d",&n),c=0,i=1|
-n;i<n;puts(""),i+=
0x2)for(j=-n;++j<n;
putchar(i*i+j*j<n*n
?c++,0x02a:0x020));
printf("%g",2.*c/
n/n);3.1415926;
5358979;}
XSLT 1.0
Just for fun, here's an XSLT version. Not really code-golf material, but it solves the problem in a weird-functional-XSLT-kind of way :)
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" >
<xsl:output method="html"/>
<!-- Skip even lines -->
<xsl:template match="s[@y mod 2=0]">
<xsl:variable name="next">
<!-- Just go to next line.-->
<s R="{@R}" y="{@y+1}" x="{-@R}" area="{@area}"/>
</xsl:variable>
<xsl:apply-templates select="msxsl:node-set($next)"/>
</xsl:template>
<!-- End of the line?-->
<xsl:template match="s[@x > @R]">
<xsl:variable name="next">
<!-- Go to next line.-->
<s R="{@R}" y="{@y+1}" x="{-@R}" area="{@area}"/>
</xsl:variable><!-- Print LF--> <xsl:apply-templates
select="msxsl:node-set($next)"/>
</xsl:template>
<!-- Are we done? -->
<xsl:template match="s[@y > @R]">
<!-- Print PI approximation -->
<xsl:value-of select="2*@area div @R div @R"/>
</xsl:template>
<!-- Everything not matched above -->
<xsl:template match="s">
<!-- Inside the circle?-->
<xsl:variable name="inside" select="@x*@x+@y*@y < @R*@R"/>
<!-- Print "*" or " "-->
<xsl:choose>
<xsl:when test="$inside">*</xsl:when>
<xsl:otherwise> </xsl:otherwise>
</xsl:choose>
<xsl:variable name="next">
<!-- Add 1 to area if we're inside the circle. Go to next column.-->
<s R="{@R}" y="{@y}" x="{@x+1}" area="{@area+number($inside)}"/>
</xsl:variable>
<xsl:apply-templates select="msxsl:node-set($next)"/>
</xsl:template>
<!-- Begin here -->
<xsl:template match="/R">
<xsl:variable name="initial">
<!-- Initial state-->
<s R="{number()}" y="{-number()}" x="{-number()}" area="0"/>
</xsl:variable>
<pre>
<xsl:apply-templates select="msxsl:node-set($initial)"/>
</pre>
</xsl:template>
</xsl:stylesheet>
If you want to test it, save it as pi.xslt
and open the following XML file in IE:
<?xml version="1.0"?>
<?xml-stylesheet href="pi.xslt" type="text/xsl" ?>
<R>
10
</R>
Perl, 95 96 99 106 109 110 119 characters:
$t+=$;=1|2*sqrt($r**2-($u-2*$_)**2),say$"x($r-$;/2).'*'x$;for 0..
($u=($r=<>)-1|1);say$t*2/$r**2
(The newline can be removed and is only there to avoid a scrollbar)
Yay! Circle version!
$t+=$;=
1|2*sqrt($r**
2-($u-2*$_)**2)
,say$"x($r-$;/2
).'*'x$;for 0..
($u=($r=<>)-1|1
);$pi=~say$t*
2/$r**2
For the uninitiated, the long version:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
# Read the radius from STDIN
my $radius = <>;
# Since we're only printing asterisks on lines where y is odd,
# the number of lines to be printed equals the size of the radius,
# or (radius + 1) if the radius is an odd number.
# Note: we're always printing an even number of lines.
my $maxline = ($radius - 1) | 1;
my $surface = 0;
# for ($_ = 0; $_ <= $maxline; $_++), if you wish
for (0 .. $maxline) {
# First turn 0 ... N-1 into -(N/2) ... N/2 (= Y-coordinates),
my $y = $maxline - 2*$_;
# then use Pythagoras to see how many stars we need to print for this line.
# Bitwise OR "casts" to int; and: 1 | int(2 * x) == 1 + 2 * int(x)
my $stars = 1 | 2 * sqrt($radius**2-$y**2);
$surface += $stars;
# $" = $LIST_SEPARATOR: default is a space,
# Print indentation + stars
# (newline is printed automatically by say)
say $" x ($radius - $stars/2) . '*' x $stars;
}
# Approximation of Pi based on surface area of circle:
say $surface*2/$radius**2;
FORTRAN - 101 Chars
$ f95 piday.f95 -o piday && echo 8 | ./piday
READ*,N
DO I=-N,N,2
M=(N*N-I*I)**.5
PRINT*,(' ',J=1,N-M),('*',J=0,M*2)
T=T+2*J
ENDDO
PRINT*,T/N/N
END
READ*,N
K=N/2*2;DO&
I=1-K,N,2;M=&
(N*N-I*I)**.5;;
PRINT*,(' ',J=&
1,N-M),('*',J=&
0,M*2);T=T+2*J;
ENDDO;PRINT*&
,T/N/N;END;
!PI-DAY
x86 Machine Code: 127 bytes
Intel Assembler: 490 chars
mov si,80h
mov cl,[si]
jcxz ret
mov bx,10
xor ax,ax
xor bp,bp
dec cx
a:mul bx
mov dl,[si+2]
sub dl,48
cmp dl,bl
jae ret
add ax,dx
inc si
loop a
mov dl,al
inc dl
mov dh,al
add dh,dh
mov ch,dh
mul al
mov di,ax
x:mov al,ch
sub al,dl
imul al
mov si,ax
mov cl,dh
c:mov al,cl
sub al,dl
imul al
add ax,si
cmp ax,di
mov al,32
ja y
or al,bl
add bp,2
y:int 29h
dec cl
jnz c
mov al,bl
int 29h
mov al,13
int 29h
sub ch,2
jnc x
mov ax,bp
cwd
mov cl,7
e:div di
cmp cl,6
jne z
pusha
mov al,46
int 29h
popa
z:add al,48
int 29h
mov ax,bx
mul dx
jz ret
dec cl
jnz e
ret
This version handles the bonus test case as well and is 133 bytes:
mov si,80h
mov cl,[si]
jcxz ret
mov bx,10
xor ax,ax
xor bp,bp
dec cx
a:mul bx
mov dl,[si+2]
sub dl,48
cmp dl,bl
jae ret
add ax,dx
inc si
loop a
mov dl,al
rcr dl,1
adc dl,dh
add dl,dl
mov dh,dl
add dh,dh
dec dh
mov ch,dh
mul al
mov di,ax
x:mov al,ch
sub al,dl
imul al
mov si,ax
mov cl,dh
c:mov al,cl
sub al,dl
imul al
add ax,si
cmp ax,di
mov al,32
jae y
or al,bl
add bp,2
y:int 29h
dec cl
jnz c
mov al,bl
int 29h
mov al,13
int 29h
sub ch,2
jnc x
mov ax,bp
cwd
mov cl,7
e:div di
cmp cl,6
jne z
pusha
mov al,46
int 29h
popa
z:add al,48
int 29h
mov ax,bx
mul dx
jz ret
dec cl
jnz e
ret
Python: 101 104 107 110 chars
Based on the other Python version by Nicholas Riley.
r=input()
t=0
i=1
exec"n=1+int((2*i*r-i*i)**.5)*2;t+=2.*n/r/r;print' '*(r-n/2)+'*'*n;i+=2;"*r
print t
Credits to AlcariTheMad for some of the math.
Ah, the odd-numbered ones are indexed with zero as the middle, explains everything.
Bonus Python: 115 chars (quickly hacked together)
r=input()
t=0
i=1
while i<r*2:n=1+int((2*i*r-i*i)**.5)*2;t+=2.*n/r/r;print' '*(r-n/2)+'*'*n;i+=2+(r-i==2)*2
print t
Powershell, 119 113 109 characters
($z=-($n=$args[($s=0)])..$n)|?{$_%2}|%{$l="";$i=$_
$z|%{$l+=" *"[$i*$i+$_*$_-lt$n*$n-and++$s]};$l};2*$s/$n/$n
and here's a prettier version:
( $range = -( $R = $args[ ( $area = 0 ) ] ) .. $R ) |
where { $_ % 2 } |
foreach {
$line = ""
$i = $_
$range | foreach {
$line += " *"[ $i*$i + $_*$_ -lt $R*$R -and ++$area ]
}
$line
}
2 * $area / $R / $R
HyperTalk: 237 characters
Indentation is not required nor counted. It is added for clarity. Also note that HyperCard 2.2 does accept those non-ASCII relational operators I used.
function P R
put""into t
put 0into c
repeat with i=-R to R
if i mod 2≠0then
repeat with j=-R to R
if i^2+j^2≤R^2then
put"*"after t
add 1to c
else
put" "after t
end if
end repeat
put return after t
end if
end repeat
return t&2*c/R/R
end P
Since HyperCard 2.2 doesn't support stdin/stdout, a function is provided instead.
C#: 209 202 201 characters:
using C=System.Console;class P{static void Main(string[]a){int r=int.Parse(a[0]),s=0,i,x,y;for(y=1-r;y<r;y+=2){for(x=1-r;x<r;s+=i)C.Write(" *"[i=x*x+++y*y<=r*r?1:0]);C.WriteLine();}C.Write(s*2d/r/r);}}
Unminified:
using C = System.Console;
class P {
static void Main(string[] arg) {
int r = int.Parse(arg[0]), sum = 0, inside, x, y;
for (y = 1 - r; y < r; y += 2) {
for (x = 1 - r; x < r; sum += inside)
C.Write(" *"[inside = x * x++ + y * y <= r * r ? 1 : 0]);
C.WriteLine();
}
C.Write(sum * 2d / r / r);
}
}
Haskell 139 145 147 150 230 chars:
x True=' ';x _='*'
a n=unlines[[x$i^2+j^2>n^2|j<-[-n..n]]|i<-[1-n,3-n..n]]
b n=a n++show(sum[2|i<-a n,i=='*']/n/n)
main=readLn>>=putStrLn.b
Handling the odd numbers: 148 chars:
main=do{n<-readLn;let{z k|k<n^2='*';z _=' ';c=[[z$i^2+j^2|j<-[-n..n]]|i<-[1,3..n]];d=unlines$reverse c++c};putStrLn$d++show(sum[2|i<-d,i=='*']/n/n)}
150 chars: (Based on the C version.)
a n=unlines[concat[if i^2+j^2>n^2then" "else"*"|j<-[-n..n]]|i<-[1-n,3-n..n]]
main=do n<-read`fmap`getLine;putStr$a n;print$2*sum[1|i<-a n,i=='*']/n/n
230 chars:
main=do{r<-read`fmap`getLine;let{p=putStr;d=2/fromIntegral r^2;l y n=let c m x=if x>r then p"\n">>return m else if x*x+y*y<r*r then p"*">>c(m+d)(x+1)else p" ">>c m(x+1)in if y>r then print n else c n(-r)>>=l(y+2)};l(1-r`mod`2-r)0}
Unminified:
main = do r <- read `fmap` getLine let p = putStr d = 2/fromIntegral r^2 l y n = let c m x = if x > r then p "\n" >> return m else if x*x+y*y<r*r then p "*" >> c (m+d) (x+1) else p " " >> c m (x+1) in if y > r then print n else c n (-r) >>= l (y+2) l (1-r`mod`2-r) 0
I was kinda hoping it would beat some of the imperative versions, but I can't seem to compress it any further at this point.
Ruby, 96 chars
(based on Guffa's C# solution):
r=gets.to_f
s=2*t=r*r
g=1-r..r
g.step(2){|y|g.step{|x|putc' * '[i=t<=>x*x+y*y];s+=i}
puts}
p s/t
109 chars (bonus):
r=gets.to_i
g=-r..r
s=g.map{|i|(g.map{|j|i*i+j*j<r*r ?'*':' '}*''+"\n")*(i%2)}*''
puts s,2.0/r/r*s.count('*')
PHP: 117
Based on dev-null-dweller
for($y=1-$r=$argv[1];$y<$r;$y+=2,print"\n")for($x=1-$r;$x<$r;$x++)echo$r*$r>$x*$x+$y*$y&&$s++?'*':' ';echo$s*2/$r/$r;
You guys are thinking way too hard.
switch (r) {
case 1,2:
echo "*"; break;
case 3,4:
echo " ***\n*****\n ***"; break;
// etc.
}
J: 47, 46, 45
Same basic idea as other solutions, i.e. r^2 <= x^2 + y^2, but J's array-oriented notation simplifies the expression:
c=:({&' *',&":2*+/@,%#*#)@:>_2{.\|@j./~@i:@<:
You'd call it like c 2
or c 8
or c 10
etc.
Bonus: 49
To handle odd input, e.g. 13
, we have to filter on odd-valued x coordinates, rather than simply taking every other row of output (because now the indices could start at either an even or odd number). This generalization costs us 4 characters:
c=:*:({&' *'@],&":2%(%+/@,))]>(|@j./~2&|#])@i:@<:
Deminimized version:
c =: verb define
pythag =. y > | j./~ i:y-1 NB. r^2 > x^2 + y^2
squished =. _2 {.\ pythag NB. Odd rows only
piApx =. (2 * +/ , squished) % y*y
(squished { ' *') , ": piApx
)
Improvements and generalizations due to Marshall Lochbam on the J Forums.
Python: 118 characters
Pretty much a straightforward port of the Perl version.
r=input()
u=r+r%2
t=0
for i in range(u):n=1+2*int((r*r-(u-1-2*i)**2)**.5);t+=n;print' '*(r-n/2-1),'*'*n
print 2.*t/r/r
C++: 169 characters
#include <iostream>
int main(){int i,j,c=0,n;std::cin>>n;for(i=-n;i<=n;i+=2,std::cout<<'\n')for(j=-n;j<=n;j++)std::cout<<(i*i+j*j<=n*n?c++,'*':' ');std::cout<<2.*c/n/n;}
Unminified:
#include <iostream>
int main()
{
int i,j,c=0,n;
std::cin>>n;
for(i=-n;i<=n;i+=2,std::cout<<'\n')
for(j=-n;j<=n;j++)
std::cout<<(i*i+j*j<=n*n?c++,'*':' ');
std::cout<<2.*c/n/n;
}
(Yes, using std:: instead of using namespace std
uses less characters)
The output here doesn't match the test cases in the original post, so here's one that does (written for readability). Consider it a reference implementation (if Poita_ doesn't mind):
#include <iostream>
using namespace std;
int main()
{
int i, j, c=0, n;
cin >> n;
for(i=-n; i<=n; i++) {
if (i & 1) {
for(j=-n; j<=n; j++) {
if (i*i + j*j <= n*n) {
cout << '*';
c++;
} else {
cout << ' ';
}
}
cout << '\n';
}
}
cout << 2.0 * c / n / n << '\n';
}
C++: 168 characters (with output I believe is correct)
#include <iostream>
int main(){int i,j,c=0,n;std::cin>>n;for(i=-n|1;i<=n;i+=2,std::cout<<"\n")for(j=-n;j<=n;j++)std::cout<<" *"[i*i+j*j<=n*n&&++c];std::cout<<2.*c/n/n;}
PHP: 126 132 138
(based on Guffa C# solution)
126:
for($y=1-($r=$argv[1]);$y<$r;$y+=2,print"\n")for($x=1-$r;$x<$r;$s+=$i,++$x)echo($i=$x*$x+$y*$y<=$r*$r)?'*':' ';echo$s*2/$r/$r;
132:
for($y=1-($r=$argv[1]);$y<$r;$y+=2){for($x=1-$r;$x<$r;@$s+=$i,++$x)echo($i=$x*$x+$y*$y<=$r*$r?1:0)?'*':' ';echo"\n";}echo$s*2/$r/$r;
138:
for($y=1-($r=$argv[1]);$y<$r;$y+=2){for($x=1-$r;$x<$r;@$s+=$i){$t=$x;echo($i=$t*$x++ +$y*$y<=$r*$r?1:0)?'*':' ';}echo"\n";}echo$s*2/$r/$r;
Current full:
for( $y = 1 - ( $r = $argv[1]); $y < $r; $y += 2, print "\n")
for( $x = 1-$r; $x < $r; $s += $i, ++$x)
echo( $i = $x*$x + $y*$y <= $r*$r) ? '*' : ' ';
echo $s*2 /$r /$r;
Can be without @
before first $s
but only with error_reporting set to 0 (Notice outputs is messing the circle)
Ruby 1.8.x, 93
r=$_.to_f
q=0
e=r-1
(p(('*'*(n=1|2*(r*r-e*e)**0.5)).center r+r)
q+=n+n
e-=2)while-r<e
p q/r/r
Run with $ ruby -p piday
APL: 59
This function accepts a number and returns the two expected items. Works correctly in bonus cases.
{⍪(⊂' *'[1+m]),q÷⍨2×+/,m←(2|v)⌿(q←⍵*2)>v∘.+v←2*⍨⍵-⍳1+2×⍵-1}
Dialect is Dyalog APL, with default index origin. Skill level is clueless newbie, so if any APL guru wants to bring it down to 10 characters, be my guest!
You can try it online on Try APL, just paste it in and put a number after it:
{⍪(⊂' *'[1+m]),q÷⍨2×+/,m←(2|v)⌿(q←⍵*2)>v∘.+v←2*⍨⍵-⍳1+2×⍵-1} 13
*************
*******************
*********************
***********************
*************************
*************************
*************************
*************************
***********************
*********************
*******************
*************
2.98225
And a bash entry: 181 186 190 chars
for((y=-(r=$1,r/2*2);y<=r;y+=2));do for((x=-r;x<=r;++x));do((x*x+y*y<r*r))&&{((++n));echo -n '*';}||echo -n " ";((x<r))||echo;done;done;((s=1000,p=n*2*s/r/r,a=p/s,b=p%s));echo $a.$b
Run with e.g. bash py.sh 13
Python: 148 characters.
Failed (i.e. not short enough) attempt to abuse the rules and hardcode the test cases, as I mentioned in reply to the original post. Abusing it with a more verbose language may have been easier:
a=3.0,3.125,3.16
b="1","23","3677","47899"
r=input()
for i in b[r/3]+b[r/3][::-1]:q=1+2*int(i);print ' '*(int(b[r/3][-1])-int(i))+'*'*q
print a[r/5]
bc: 165, 127, 126 chars
Based on the Python version.
r=read()
for(i=-1;r*2>i+=2;scale=6){n=sqrt(2*i*r-i*i)
scale=0
n=1+n/1*2
j=r-n/2
t+=2*n
while(j--)" "
while(n--)"*"
"
"}
t/r/r
(New line after the last line cannot be omitted here.)
JavaScript (SpiderMonkey) - 118 chars
This version accepts input from stdin and passes the bonus test cases
r=readline()
for(t=0,i=-r;i<r;i++)if(i%2){for(s='',j=-r;j<r;j++){t+=q=i*i+j*j<r*r
s+=q?'*':' '}print(s)}print(t*2/r/r)
Usage: cat 10 | js thisfile.js
-- jsbin preview adds an alias for print/readline so you can view in browser
Javascript: 213 163
Updated
r=10;m=Math;a=Array;t=0;l=document;for(i=-r;i<r;i+=2){w=m.floor(m.sqrt(r*r-i*i)*2);t+=w*2;l.writeln(a(m.round(r-w/2)).join(' ')+a(w).join('*'));}l.writeln(t/(r*r))
Nobody said it had to render correctly in the browser - just the output. As such I've removed the pre tags and optimised it further. To view the output you need to view generated source or set your stylesheet accordingly. Pi is less accurate this way, but it's now to spec.
r=10;m=Math;a=Array;t=0;s='';for(i=-r;i<r;i++){w=m.floor((m.sqrt(m.pow(r,2)-m.pow(i,2)))*2);t+=w;if(i%2){z=a(m.round(r-w/2)).join(' ')+a(w).join('*');s+=z+'\n';}}document.write('<pre>'+(s+(t/m.pow(r,2)))+'</pre>')
Unminified:
r=10;
m=Math;
a=Array;
t=0;
s='';
for(i=-r;i<r;i++){
w=m.floor((m.sqrt(m.pow(r,2)-m.pow(i,2)))*2);
t+=w;
if(i%2){
z=a(m.round(r-w/2)).join(' ')+a(w).join('*');
s+=z+'\n';
}
}
document.write('<pre>'+(s+(t/m.pow(r,2)))+'</pre>');
Java: 234
class C{public static void main(String[] a){int x,y,s=0,r=Integer.parseInt(a[0]);for(y=1-r;y<r;y+=2){for(x=1-r;x<r;++x){boolean b=x*x+y*y<=r*r;s+=b?1:0;System.out.print(b?'*':' ');}System.out.println();}System.out.println(s*2d/r/r);}}
Unminified:
class C{
public static void main(String[] a){
int x,y,s=0,r=Integer.parseInt(a[0]);
for(y=1-r;y<r;y+=2){
for(x=1-r;x<r;++x) {
boolean b=x*x+y*y<=r*r;
s+=b?1:0;
System.out.print(b?'*':' ');
}
System.out.println();
}
System.out.println(s*2d/r/r);
}
}
GAWK: 136, 132, 126, 125 chars
Based on the Python version.
{r=$1
for(i=-1;r*2>i+=2;print""){n=1+int((2*i*r-i*i)**.5)*2
t+=2*n/r/r
printf"%*s",r-n/2,""
while(n--)printf"%c","*"}print t}