Search code examples
language-agnosticcode-golfrosetta-stone

Code Golf - π day


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

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