Code Golf - π día


95

El reto

Directrices para code-golf en SO

El código más corto por número de caracteres para mostrar una representación de un círculo de radio Rusando el *carácter, seguido de una aproximación de π.

La entrada es un solo número R,.

Dado que la mayoría de las computadoras parecen tener una relación de casi 2: 1, solo debe generar líneas donde ysea ​​impar. Esto significa que cuando Rsea ​​extraño, debería imprimir R-1líneas. Hay un nuevo caso de prueba para R=13aclarar.

p.ej.

Input
    5
Output      Correct                          Incorrect

        3    *******                    4      *******
        1   *********                   2     *********
       -1   *********                   0    ***********
       -3    *******                   -2     *********
           2.56                        -4      *******
                                            3.44

Editar: debido a la confusión generalizada causada por valores extraños de R, se aceptará cualquier solución que pase los 4 casos de prueba que se indican a continuación

La aproximación de π se obtiene dividiendo el doble del número de *caracteres entre .
La aproximación debe ser correcta hasta al menos 6 dígitos significativos.
Se permiten ceros iniciales o finales, por lo que, por ejemplo , se acepta cualquiera de 3, para las entradas de y .3.00000000324

El recuento de códigos incluye entrada / salida (es decir, programa completo).

Casos de prueba

Input
    2
Output
     *** 
     *** 
    3.0

Input
    4
Output
      *****  
     ******* 
     ******* 
      *****  
    3.0

Input
    8
Output
         *******     
      *************  
     *************** 
     *************** 
     *************** 
     *************** 
      *************  
         *******     
    3.125

Input
    10
Output
          *********      
       ***************   
      *****************  
     ******************* 
     ******************* 
     ******************* 
     ******************* 
      *****************  
       ***************   
          *********      
    3.16

Caso de prueba adicional

Input
    13
Output

           *************       
        *******************    
       *********************   
      ***********************  
     ************************* 
     ************************* 
     ************************* 
     ************************* 
      ***********************  
       *********************   
        *******************    
           *************                                          
    2.98224852071

Es posible que desee aclarar si la "entrada" está en la línea de comandos o en stdin.
Greg Hewgill

1
@Greg Hewgill, siéntase libre de elegir el que sea más conveniente para el idioma que está usando :)
John La Rooy

@Greg Hewgill, Algunas (es decir, muy pocas) implementaciones de lenguaje de programación no tienen una noción de "línea de comando".
Joey Adams

1
Noto que pocas de las respuestas siguen la regla de solo poner líneas donde y es impar. Dado un valor impar de r (no se muestra en los casos de prueba), la mayoría generará líneas donde y es par.
MtnViewMark

6
Desafío de abuso de reglas: cree un código que sea más corto que el código de cualquier otra persona al admitir solo los 4 casos de prueba necesarios.
Brian

Respuestas:


15

En dc: 88 y 93 93 94 96102105129138141 caracteres

Por si acaso, estoy usando OpenBSD y algunas extensiones supuestamente no portátiles en este momento.

93 caracteres. Esto se basa en la misma fórmula que la solución FORTRAN (resultados ligeramente diferentes a los de los casos de prueba). Calcula X ^ 2 = R ^ 2-Y ^ 2 para cada Y

[rdPr1-d0<p]sp1?dsMdd*sRd2%--
[dd*lRr-vddlMr-32rlpxRR42r2*lpxRRAP4*2+lN+sN2+dlM>y]
dsyx5klNlR/p

88 caracteres. Solución iterativa. Coincide con casos de prueba. Para cada X e Y verifica si 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

Para correr dc pi.dc.

Aquí hay una versión anterior anotada:

# 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

1
No funciona con linux dc, pero puedo confirmar que funciona en openbsd . ¡Increíble!
John La Rooy

@Carlos, sí, el (operador seguro que es útil. lástima que no se haya implementado en el dc que viene con linux
John La Rooy

@gnibbler - "Una reescritura completa del comando dc usando las rutinas de números grandes bn (3) apareció por primera vez en OpenBSD 3.5". Yo no lo sabía. Se incluyen algunos buenos operadores nuevos, pero están marcados como "extensiones no portátiles".
Carlos Gutiérrez

Sí, el (operador solo tiene permitido arrojar 6 golpes!
Dan Andreatta

119

C: 131 caracteres

(Basado en la solución C ++ de 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);}

(Cambie i|=-na i-=npara eliminar el soporte de casos de números impares. Esto simplemente reduce el recuento de caracteres a 130).

Como un circulo:

      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;}

1
Me gusta cómo agregaste círculos al código para convertirlo en un círculo. ¿Sería preferible +000?
Potatoswatter

felicitaciones, j * j ++ es un comportamiento indefinido
sellibitze

1
¿No sería solo un personaje ...?
Ponkadoodle

1
¿Cómo se main()toman cuatro intargumentos?
David R Tribble

2
@Load: 5.1.2.2.1 / 1: La función llamada al inicio del programa se nombra main. Se definirá ... o de alguna otra manera definida por la implementación . Entonces eso es porque la implementación puede aceptar este formulario.
kennytm

46

XSLT 1.0

Solo por diversión, aquí tienes una versión XSLT. No es realmente material de código de golf, pero resuelve el problema de una manera extraña-funcional-XSLT :)

<?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>

Si desea probarlo, guárdelo como pi.xslty abra el siguiente archivo XML en IE:

<?xml version="1.0"?> 
<?xml-stylesheet href="pi.xslt" type="text/xsl" ?> 
<R> 
  10 
</R> 

42
mis <ojos> </ojos>! Las gafas, ¡no hacen nada!
Jimmy

1
¡Maldita sea! Me temo que puede haber superado mi solución HyperCard por su singularidad: D
Joey Adams

7
No puedo creer que hayas dicho "abierto ... IE"
harpo

Je, sí, en el pasado, solo teníamos IE y XML con XSLT era la solución a todos nuestros problemas. ¡Buenos viejos tiempos! :)
Danko Durbić

XSL versión 1.0 wow, recuerdo que esperaba la versión 2, pero cuando salió ya había seguido adelante.
gradbot

35

Perl, 95 96 99 106 109 110 119 caracteres:

$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

(La nueva línea se puede eliminar y solo está ahí para evitar una barra de desplazamiento)

¡Hurra! ¡Versión circular!

    $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

Para los no iniciados, la versión larga:

#!/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;

6
Ese es, con mucho, el código más ilegible que he visto en toda mi vida
Chris Marisic

13
Supongo que nunca has visto APL entonces.
Peter Wone

5
@Chris Marisic: ¿Marcó las otras preguntas / temas etiquetados code-golf? :) He visto muchos más ejemplos ilegibles.
BalusC

3
@Peter: A diferencia de la mayoría, he visto y escrito APL. Lleva un par de semanas acostumbrarse a sus caracteres especiales, pero después de eso puede ser bastante legible. Incluso después de un par de décadas de acostumbrarse, Perl sigue siendo mucho peor.
Jerry Coffin

1
111 caracteres,$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

25

FORTRAN - 101 caracteres

$ 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

Espera, ¿pensé que el formateo era importante en Fortran? ¡Tienes letras en la columna 1!
Joel

La mayoría de la gente todavía está atrapada en Fortan77 por lo que he visto.
Joel

8
Me gusta cómo la versión circular se parece a la Estrella de la Muerte.
mskfisher

22

Código de máquina x86: 127 bytes

Ensamblador Intel: 490 caracteres

    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

Esta versión también maneja el caso de prueba adicional y tiene 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

12
¡Me encanta StackOverflow!
zengr

2
Es interesante que algunos de los lenguajes de alto nivel tengan recuentos de caracteres más cortos que el binario que produce.
Colin Valliant

3
@Alcari: Si incluyese todo el código en las bibliotecas que usan los lenguajes de nivel superior, sus recuentos de caracteres serían significativamente más altos. En ensamblador, hacer printf("%f",a/b)no es trivial, no hay una sola instrucción para hacer eso, y mi implementación anterior asume que 0 <= a / b <10 y que la operación es una división y que ayb son números enteros.
Skizz

19

Python: 101 104 107 110 caracteres

Basado en la otra versión de Python de 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

Créditos a AlcariTheMad por algunas de las matemáticas.


Ah, los impares están indexados con cero como medio, lo explica todo.

Bonus Python: 115 caracteres (pirateados rápidamente juntos)

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

Vaya, sí, '+' gana a -1 y, cualquier día. Otra técnica que saqué de mi mente porque casi nunca es lo correcto :-)
Nicholas Riley

He usado C en el pasado y nunca miré Python. Estos 104 caracteres son más legibles que el C ++ anterior. Asombroso. Tal vez debería aprender Python ...
Dean Rather

@Dean: Uno de los principales objetivos de Python es que sea fácil de leer y escribir.
Colin Valliant

¿Ha pensado en usar exec con su respuesta de 104 caracteres también? :)
John La Rooy

Necesitaría lanzar mi propia compresión: zlib, marshalling, etc., todos salieron más grandes que el código real.
lunixbochs

12

Potencia Shell, 119 113 109 caracteres

($z=-($n=$args[($s=0)])..$n)|?{$_%2}|%{$l="";$i=$_
$z|%{$l+=" *"[$i*$i+$_*$_-lt$n*$n-and++$s]};$l};2*$s/$n/$n

y aquí hay una versión más bonita:

( $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

@Thor: Espero que no, pero esto debe ser lo más feo que he escrito en mi vida :)
Danko Durbić

3
Gracias por esa versión más bonita =)
Thor Hovden

10

HyperTalk: 237 caracteres

No se requiere ni se cuenta la sangría. Se agrega para mayor claridad. También tenga en cuenta que HyperCard 2.2 acepta los operadores relacionales no ASCII que utilicé.

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

Dado que HyperCard 2.2 no admite stdin / stdout, se proporciona una función en su lugar.


1
¿Hypercard, Sr. Adams? ¿Seriamente? Esto es muy inesperado.
Kawa

1
@Kawa: Por eso lo publiqué :) Además, el golf de código es una buena manera de crear un conjunto de pruebas en caso de que decida escribir un intérprete de HyperTalk en el futuro.
Joey Adams

¡Ja! Me gustaría ver eso, XD
Kawa

Si alguna vez decides escribir a ese intérprete, o quieres trabajar en uno existente, avísame y puedo agregar una mención sobre él en hypercard.org y tendré curiosidad por saber cómo va :-)
uliwitness

10

C #: 209202201 caracteres:

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);}}

No minificado:

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);
  }
}

No sé mucho C #, pero ¿no deberías poder usar string[]ay 1-r(en lugar de -1+r)?
kennytm

@Kenny: Tienes razón. :) Eso salva a tres personajes, y luego me las arreglé para deshacerme de cinco más.
Guffa

Lo primero que vi, lo perdí por completo -r+1.
Dykam

4
Además, también se ha visto x*xx+++y*y, pero es una locura diseccionarlo a primera vista.
Dykam

Me tomé la libertad de eliminar otro byte ;-)
Joey

10

Haskell 139 145 147 150 230 caracteres:

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

Manejo de números impares: 148 caracteres:

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 caracteres: (Basado en la versión C).

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 caracteres:

main = do {r <-read`fmap`getLine; let {p = putStr; d = 2 / fromIntegral r ^ 2; lyn = let cmx = if x> r then p "\ n" >> return m else if x * x + y * y <r * r luego p "*" >> c (m + d) (x + 1) else p "" >> cm (x + 1) in if y> r then print n else cn (-r) >> = l (y + 2)}; l (1-r`mod`2-r) 0}

No minificado:

main = do r <- leer `fmap` getLine
          deje p = putStr
              d = 2 / de Integral r ^ 2
              lyn = sea cmx = si x> r
                                  luego p "\ n" >> devuelve m
                                  de lo contrario, si x * x + y * y <r * r
                                       luego p "*" >> c (m + d) (x + 1)
                                       más p "" >> cm (x + 1)
                      en si y> r
                         luego imprime n
                         más cn (-r) >> = l (y + 2)
          l (1-r`mod`2-r) 0

Tenía la esperanza de que superara algunas de las versiones imperativas, pero parece que no puedo comprimirlo más en este punto.


Cortó 2 más eliminando la "d" y agregando 1 en lugar de ella y luego imprimiendo "2 * n / fromIntegral r ^ 2"
Steve

Afeitado 3 personajes con algunos trucos de Haskell. Me encanta que en Haskell a menudo no hay costo para varias líneas (nueva línea frente a punto y coma) y, por lo tanto, ¡nuestro código de golf es generalmente legible!
MtnViewMark

Estrictamente hablando, la versión de 145 caracteres solo funciona si la entrada es pareja. Pero muy bonito de cualquier forma.
Steve

Acortó la línea de E / S. Todavía debería ser posible guardar algunos caracteres más presionando la función defs en un bloque main = do {... let {...} ...}, creo.
comingstorm

@comingstorm: ¡Genial! No sabía nada de readLn. Esto ayudará a muchos jugadores de golf de Haskell. @Steve: Sí, todavía estoy tratando de encontrar la forma más eficiente de solucionarlo.
MtnViewMark

10

Ruby, 96 caracteres

(basado en la solución C # de Guffa):

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 caracteres (bonificación):

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('*')

¡Gracias! Me avergüenza ver lo ilegible que puede ser Ruby ... :)
Mladen Jablanović

también puede usar en p slugar de puts s:)
John La Rooy

1
Buenas ideas nuevas allí: me gusta que esté usando g con 2 tamaños de paso diferentes y el <=> para evitar tener un código para convertir de lógica
John La Rooy

9

PHP: 117

Basado en 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;

8

Están pensando demasiado.

switch (r) {
   case 1,2:
      echo "*"; break;
   case 3,4:
      echo " ***\n*****\n ***"; break;
   // etc.
}

8
El recuento de personajes se sale de control, ¿no crees? :)
John La Rooy

7
No escala. ¡Inmantenible!
spoulson

Intenté comprimir el truco del caso de prueba tanto como sea posible y aún así terminó siendo un poco más grande que mi solución real: P
lunixbochs

5
+1, siempre haga lo más obvio primero ... si a alguien no le gusta, quejarse en voz alta de que la especificación no fue lo suficientemente clara
Mizipzor

Brian tuvo un intento semi serio de cubrir los casos de prueba de manera especial, también debe votar a favor de él si le gusta esta respuesta;) stackoverflow.com/questions/2457995
John La Rooy

7

J: 47 , 46 , 45

La misma idea básica que otras soluciones, es decir, r ^ 2 <= x ^ 2 + y ^ 2 , pero la notación orientada a matrices de J simplifica la expresión:

c=:({&' *',&":2*+/@,%#*#)@:>_2{.\|@j./~@i:@<:

Lo llamarías como c 2oc 8 o c 10etc.

Bono: 49

Para manejar entradas impares, por ejemplo 13, tenemos que filtrar en coordenadas x con valores impares, en lugar de simplemente tomar cada dos filas de salida (porque ahora los índices podrían comenzar en un número par o impar). Esta generalización nos cuesta 4 caracteres:

c=:*:({&' *'@],&":2%(%+/@,))]>(|@j./~2&|#])@i:@<:

Versión desminimizada:

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
)

Mejoras y generalizaciones debidas a Marshall Lochbam en los J Forums .


5

Python: 118 caracteres

Prácticamente un puerto sencillo de la versión Perl.

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

Para python2 solo puede usarr=input()
John La Rooy

No necesitas el espacio entre printy' '
John La Rooy

Bien, eso da miedo, ahora es más corto que la versión de Perl. (Olvidé por completo la "entrada" de mi mente porque normalmente es muy insegura ...)
Nicholas Riley

4

C ++: 169 caracteres

#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;}

No minificado:

#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;
}

(Sí, usar std :: en lugar de using namespace stdusar menos caracteres)

El resultado aquí no coincide con los casos de prueba en la publicación original, por lo que aquí hay uno que sí lo hace (escrito para facilitar la lectura). Considérelo una implementación de referencia (si a Poita_ no le importa):

#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 caracteres (con salida que creo que es correcta)

#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;}

El código se repite de -n an, por lo que para una entrada de, por ejemplo, 4, muestra un diámetro de 9, no 7 como se muestra en los casos de prueba.
Guffa

¿Es un requisito que su círculo coincida exactamente con los OP ?
Peter Alexander

3
Es posible que desee cambiarlo a lo #include <iostream.h>que básicamente es #include <iostream> -- using namespace std;por compatibilidad con compiladores antiguos de C ++.
Earlz

1
@Carlos, no escribí ese bit en particular, pero es un operador AND binario. Comprueba que el último bit esté configurado, lo que equivale a hacer i%2, pero es "más rápido". No es realmente más rápido porque el compilador lo haría de todos modos.
Peter Alexander

1
@Poita_: En realidad, i% 2 e i & 1 se comportan de manera diferente con números negativos. (-1) & 1 es 1, que es lo que queremos aquí. (-1)% 2 es -1 en mi sistema, y ​​esto se ajusta a C99. Por lo tanto, aunque if (i & 1) y if (i% 2) harán lo mismo, se debe tener cuidado con if (i% 2 == 1), que no funcionará cuando i sea negativo.
Joey Adams

3

PHP: 126132138

(basado en la solución Guffa C #)

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;

Lleno actual:

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;

Puede estar sin @antes primero $spero solo con error_reporting establecido en 0 (las salidas de aviso están estropeando el círculo)


¿Qué hace / $ r en echo $ s * 2 / $ r / $ r?
Davidosomething

OHH división ... el espaciado me desconcertó, pensé que era una taquigrafía de operador que nunca había visto
davidosomething

3

Rubí 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

Corre con $ ruby -p piday


Bonito, pero no imprime la aproximación pi
John La Rooy

No funciona en 1.9.1 e imprime comillas dobles alrededor del círculo.
Mladen Jablanović

Es normal que los programas de golf no funcionen en diferentes niveles de idioma. ¿Cuántos cg de Perl o Python funcionan en cada versión del lenguaje? Es interesante, sin embargo, que la razón es porque Integer|Floatya no coacciona el flotador en 1.9.
DigitalRoss

3

APL: 59

Esta función acepta un número y devuelve los dos elementos esperados. Funciona correctamente en casos de bonificación.

{⍪(⊂' *'[1+m]),q÷⍨2×+/,m←(2|v)⌿(q←⍵*2)>v∘.+v←2*⍨⍵-⍳1+2×⍵-1}

El dialecto es Dyalog APL, con origen de índice predeterminado. El nivel de habilidad es un novato despistado , así que si algún gurú de APL quiere reducirlo a 10 caracteres, ¡sé mi invitado!


Puede probarlo en línea en Try APL , simplemente péguelo y coloque un número después:

   {⍪(⊂' *'[1+m]),q÷⍨2×+/,m←(2|v)⌿(q←⍵*2)>v∘.+v←2*⍨⍵-⍳1+2×⍵-1} 13
      *************
   *******************
  *********************
 ***********************
*************************
*************************
*************************
*************************
 ***********************
  *********************
   *******************
      *************
2.98225

Aunque no conozco APL, parece más bonito que la versión J.
ahala

@ahala De hecho. APL es hermoso, tanto conceptual como estéticamente. Empecé a aprender J, pero me desanimó la locura aleatoria de ASCII. Un buen alma escribió un intérprete APL de código abierto para Node.js (npm install apl) que es bastante bueno. Calcula el código anterior con solo un cambio menor (no monádico , segundo carácter). Puede encontrar buena documentación de APL en todos los sitios de proveedores, como Dyalog.
Tobia

2

Y una entrada de bash: 181 186 190 caracteres

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

Ejecutar con eg bash py.sh 13


2

Python: 148 caracteres.

Intento fallido (es decir, no lo suficientemente corto) de abusar de las reglas y codificar los casos de prueba, como mencioné en la respuesta a la publicación original. Abusar de él con un lenguaje más detallado puede haber sido más fácil:

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]

2

antes de Cristo: 165 , 127 , 126 caracteres

Basado en la versión de Python.

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

(La nueva línea después de la última línea no se puede omitir aquí).


1
127 caracteres: r = leer (); para (i = 1; i <r * 2; escala = 6) {n = sqrt (2 * i r-i i); escala = 0; n = 1 + n / 1 * 2 ; i + = 2; j = rn / 2; t + = 2 * n; while (j--) ""; while (n -) "*"; ""}; t / r / r
Carlos Gutiérrez

El único problema aquí es que ahora falla para 0, pero de acuerdo con las reglas actuales, está bien.
przemoc

2

JavaScript (SpiderMonkey) - 118 caracteres

Esta versión acepta la entrada de stdin y pasa los casos de prueba adicionales

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)

Uso: cat 10 | js thisfile.js - vista previa de jsbin agrega un alias para print / readline para que pueda verlo en el navegador

Javascript: 213 163


Actualizado

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

Nadie dijo que tenía que renderizarse correctamente en el navegador, solo la salida. Como tal, eliminé las etiquetas previas y las optimicé aún más. Para ver la salida, debe ver la fuente generada o configurar su hoja de estilo en consecuencia. Pi es menos preciso de esta manera, pero ahora cumple con las especificaciones.


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

No minificado:

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>');

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);}}

No minificado:

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);
    }
}

Probablemente podría ahorrar ~ 50 caracteres reescribiendo esto en
Scala

1

GAWK: 136 , 132 , 126 , 125 caracteres

Basado en la versión de Python.

{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}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.