95

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 .
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
Community
  • 1
  • 1
John La Rooy
  • 295,403
  • 53
  • 369
  • 502

26 Answers26

119

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;}
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
46

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 &gt; @R]">
    <xsl:variable name="next">
      <!-- Go to next line.-->
      <s R="{@R}" y="{@y+1}" x="{-@R}" area="{@area}"/>
    </xsl:variable><!-- Print LF-->&#10;<xsl:apply-templates 
      select="msxsl:node-set($next)"/>
  </xsl:template>

  <!-- Are we done? -->
  <xsl:template match="s[@y &gt; @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 &lt; @R*@R"/>
    <!-- Print "*" or " "-->
    <xsl:choose>
      <xsl:when test="$inside">*</xsl:when>
      <xsl:otherwise>&#160;</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> 
Danko Durbić
  • 7,077
  • 5
  • 34
  • 39
35

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;
Community
  • 1
  • 1
mercator
  • 28,290
  • 8
  • 63
  • 72
  • 6
    That is by far the most unreadable code I've seen in my entire life – Chris Marisic Mar 14 '10 at 03:05
  • 13
    I guess you've never seen APL then. – Peter Wone Mar 14 '10 at 04:59
  • 5
    @Chris Marisic: Did you check the other questions/topics tagged `code-golf`? :) I've seen far more unreadable examples. – BalusC Mar 14 '10 at 06:51
  • 3
    @Peter:Unlike most, I've both seen and written APL. It takes a couple weeks to get accustomed to its special characters, but after that it can be quite readable. Even after a couple of decades to get accustomed, Perl is still much worse. – Jerry Coffin Mar 14 '10 at 07:26
  • I was only trying to be funny. I've always felt that Perl resembles nothing so much as line noise on a TTY. Some wag once dubbed it the world's first write-only language. – Peter Wone Mar 14 '10 at 08:19
  • So, is someone going to write an APL version then? – Nicholas Riley Mar 14 '10 at 08:40
  • 1
    111 chars, `$r=<>;$t+=$n=1+2*int sqrt($r**2-($u-2*$_)**2),print$"x($r-$n/2).'*'x$n.$/for(0..($u=$r-1+$r%2));print$t*2/$r**2` – Hasturkun Mar 14 '10 at 10:01
  • @Hasturkun: Updated. Nice use of `$"` and `$/`! I wouldn't have thought of that. – mercator Mar 14 '10 at 16:45
  • Using 'say' instead of print at the end of the loop would save the 3 characters used for printing newlines. – Sundar R Mar 15 '10 at 20:03
  • This version is currently printing the even rows when ever R is odd – John La Rooy Mar 15 '10 at 21:26
  • @sundar, hmmm, I did think about that, but I tested it by saving it to file, which then requires a `use`... I'll leave it. – mercator Mar 16 '10 at 08:44
  • You can run it using `perl -M5.01` – John La Rooy Mar 16 '10 at 09:02
  • @gnibbler, ah indeed, thanks... I'll have to think about the odd R tonight. I thought it was printing the right number of lines, though. The origin is in the center, between the middle two lines. Doesn't that mean that, for R=13, the top and bottom should be at (0,13) and (0,-13), making a total of 14 odd lines? Your example output only has 12 lines. – mercator Mar 16 '10 at 09:22
  • @mercator, Since I am printing '*' only for points inside the circle the top and bottom line would be blank. You can do 14 lines if you like, the blank lines are optional. – John La Rooy Mar 16 '10 at 10:34
  • To this day, Perl appears to be the most compressible language on planet Earth. – flq Mar 16 '10 at 10:53
  • @mercator, I've decided to make the odd number test case optional as it raises too many issues and violates the "fun" principle – John La Rooy Mar 16 '10 at 17:55
  • Change `$n` to some writable and inscrutable variable like `$;`. Then you can remove the space before `for`. – mob Mar 17 '10 at 18:07
  • So the C version is almost as short? So much for writing unreadable but compact Perl code I guess... – Prof. Falken Mar 18 '10 at 13:05
  • @gnibbler, I don't want to shoot down my own answer now, but what exactly are the issues with the odd numbers? The only issue I can see is whether it's okay to print stars on the circle itself too or not. That isn't made clear in the challenge and I didn't think about it until your comments. That issue only happens to occur on odd radiuses because of (0, ±R) and Pythagorean triples (http://mathworld.wolfram.com/PythagoreanTriple.html) such as (±12, ±5) on the R=13 circle. – mercator Mar 18 '10 at 21:35
  • @mercator, yeah, you are pretty spot on, and since there wasn't originally a testcase with a triple, it didn't seem fair to me to add extra conditions that would break answers already submitted. Especially as other people were basing their answers on existing ones. – John La Rooy Mar 18 '10 at 22:04
  • @gnibbler: instead of -M5.01, you can do -E instead. Save you four characters, if you pass it all on the command line. :) – Robert P Apr 07 '10 at 00:07
  • 1
    @NicholasRiley Here, sorry for the late reply :) http://stackoverflow.com/a/17823939/517371 – Tobia Jul 24 '13 at 01:53
25

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
lambda
  • 3,295
  • 1
  • 26
  • 32
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
22

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
Skizz
  • 69,698
  • 10
  • 71
  • 108
  • 2
    It's interesting that some of the high level languages have shorter character counts than the binary this produces. – Colin Valliant Mar 17 '10 at 00:13
  • 3
    @Alcari: If you included all the code in the libraries the higher level languages use, their character counts would be significantly higher. In assembler, doing `printf("%f",a/b)` is not trivial, there's no single instruction to do that, and my implementation above assumes that 0 <= a/b < 10 and that the operation is a division and that a and b are integers. – Skizz Mar 17 '10 at 09:10
19

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
lunixbochs
  • 21,757
  • 2
  • 39
  • 47
15

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
Dan Andreatta
  • 3,611
  • 1
  • 22
  • 15
12

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
Community
  • 1
  • 1
Danko Durbić
  • 7,077
  • 5
  • 34
  • 39
10

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);
  }
}
Community
  • 1
  • 1
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
10

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.

Community
  • 1
  • 1
Joey Adams
  • 41,996
  • 18
  • 86
  • 115
  • 1
    Hypercard, Mr. Adams? Seriously? This is highly unexpected. – Kawa Mar 14 '10 at 11:10
  • 1
    @Kawa: That's kind of why I posted it :) Also, code golf is a good way to build up a test suite in case I decide to write a HyperTalk interpreter in the future. – Joey Adams Mar 14 '10 at 18:59
  • Hah! I'd like to see that, XD – Kawa Mar 15 '10 at 17:14
  • If you ever decide to write that interpreter, or want to join work on an existing one, let me know and I can add mention of it on hypercard.org and I'd be curious about how it goes :-) – uliwitness Oct 27 '13 at 13:07
10

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.

comingstorm
  • 25,557
  • 3
  • 43
  • 67
Steve
  • 1,541
  • 11
  • 17
  • Chopped off 2 more by getting rid of the "d" and adding 1 instead of it and then printing "2*n/fromIntegral r^2" – Steve Mar 14 '10 at 08:27
  • Shaved 3 characters off via a few Haskell tricks. I love that in Haskell there is often no cost to multiple lines (newline vs. semicolon) and hence our code-golf is generally readable! – MtnViewMark Mar 14 '10 at 16:26
  • Strictly speaking, the 145-char version only works if the input is even. But very nice either way. – Steve Mar 16 '10 at 07:31
  • Shortened the I/O line. It should still be possible to save a few more characters by pushing the function defs into a main=do{...let{...}...} block, I think. – comingstorm Mar 16 '10 at 08:18
  • @comingstorm: Cool! I didn't know about readLn. This will help many a Haskell code-golf. @Steve: Yup, I'm still trying to figure out the most efficient way to fix that. – MtnViewMark Mar 16 '10 at 14:19
  • How about `x y|y=' '|0<1='*'`for `x True=' ';x _='*'`? – fuz Mar 11 '11 at 11:29
  • @FUZxxl `x b|b=' ';x _='*'` is another suggestion, same length as yours. I also like `x b=last$'*':[' '|b]`, but it is three characters longer... – danr Apr 12 '12 at 12:28
10

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('*')
Community
  • 1
  • 1
Mladen Jablanović
  • 43,461
  • 10
  • 90
  • 113
9

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;
Jasper Bekkers
  • 6,711
  • 32
  • 46
8

You guys are thinking way too hard.

switch (r) {
   case 1,2:
      echo "*"; break;
   case 3,4:
      echo " ***\n*****\n ***"; break;
   // etc.
}
Matt Huggins
  • 81,398
  • 36
  • 149
  • 218
7

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.

Dan Bron
  • 2,313
  • 1
  • 22
  • 35
5

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
Community
  • 1
  • 1
Nicholas Riley
  • 43,532
  • 6
  • 101
  • 124
4

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;}
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
  • The code loops from -n to n, so for an input of for example 4 it displays a diameter of 9, not 7 as shown in the test cases. – Guffa Mar 13 '10 at 23:48
  • Is it a requirement that your circle matches the OP's *exactly*? – Peter Alexander Mar 14 '10 at 00:03
  • @Poita_, Yes the asterisks should match exactly for the test cases given. Extra whitespace to the right doesn't matter though – John La Rooy Mar 14 '10 at 01:00
  • 3
    You may wish to change it to `#include ` which basically is `#include -- using namespace std;` for compatibility with old C++ compilers. – Earlz Mar 14 '10 at 05:18
  • what is the & operator doing in line 9 -> " if (i & 1) " – Carlos Mar 14 '10 at 17:29
  • 1
    @Carlos, I didn't write that particular bit, but it's a binary AND operator. It checks that the last bit is set, which is equivalent to doing `i%2`, but is "faster". It's not really faster because the compiler would do it anyway. – Peter Alexander Mar 14 '10 at 19:54
  • 1
    @Poita_: Actually, i%2 and i&1 behave differently with negative numbers. (-1)&1 is 1, which is what we want here. (-1)%2 is -1 on my system, and this conforms to C99. Thus, although if (i&1) and if (i%2) will do the same thing, one must be careful with if (i%2 == 1), which won't work when i is negative. – Joey Adams Mar 14 '10 at 22:45
  • Sometimes the different precedence of `&` vs `%` can be exploited for golfing – John La Rooy Mar 15 '10 at 01:24
  • You can save at least 8 characters if you use "#define o std::cout<<" and then replace all "std::cout<<" with "o " – Grant Peters Mar 15 '10 at 06:12
  • Wouldn't puts() give you 10 fewer characters? – Robert Davis Mar 16 '10 at 18:33
  • @Robert, no because that requires that you include stdlib.h. – Peter Alexander Mar 16 '10 at 19:40
  • @Poita That depends on the compiler/linker. GCC 4.3.3 does _not_ require _any_ includes to use `puts`. I can do it with `printf` too, but I actually get a warning [`int printf(const char*)` != int `printf(const char*,...)`]. Any undeclared c-function defaults to returning `int` and taking whatever arguments it is used with. The linker then has to figure out the implementation of `int puts(const char*)`. Since gcc always links against standard libs (unless -nostdlib) this is easy. – KitsuneYMG Mar 17 '10 at 13:15
  • Well I think it's only fair that the code does not depend on compiler idiosyncrasies. – Peter Alexander Mar 17 '10 at 13:58
3

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
Tobia
  • 17,856
  • 6
  • 74
  • 93
  • Although I dont know APL, It looks prettier than the J version. – ahala Jul 25 '13 at 01:10
  • @ahala Indeed. APL is beautiful, both conceptually and aesthetically. I started learning J, but was turned off by the random ASCII craziness. A good soul wrote an open source APL interpreter for Node.js (npm install apl) that's pretty good. It computes the above code with just a minor change (no monadic `⍪`, 2nd char.) You can find good APL documentation on all vendor sites, such as Dyalog. – Tobia Jul 25 '13 at 01:20
3

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)

Community
  • 1
  • 1
dev-null-dweller
  • 29,274
  • 3
  • 65
  • 85
3

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

DigitalRoss
  • 143,651
  • 25
  • 248
  • 329
  • Nice one, but it doesn't print out the pi approximation – John La Rooy Mar 21 '10 at 22:14
  • It doesn't work in 1.9.1, and prints double quotes around the circle. – Mladen Jablanović Mar 22 '10 at 18:30
  • It's normal for golf programs not to work on a wildly different language levels. How many Perl or Python c-g's work on every version of the language? It is interesting, though, turns out the reason is because `Integer|Float` no longer coerces the float on 1.9. – DigitalRoss Mar 23 '10 at 13:55
2

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>');
gnarf
  • 105,192
  • 25
  • 127
  • 161
Iain Fraser
  • 6,578
  • 8
  • 43
  • 68
2

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

Dan Andreatta
  • 3,611
  • 1
  • 22
  • 15
2

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]
Brian
  • 25,523
  • 18
  • 82
  • 173
2

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

przemoc
  • 3,759
  • 1
  • 25
  • 29
1

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);
    }
}
dogbane
  • 266,786
  • 75
  • 396
  • 414
1

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}
przemoc
  • 3,759
  • 1
  • 25
  • 29