Code Golf - π gün


95

Meydan okuma

SO'da kod golfü için yönergeler

Karakteri Rkullanarak yarıçaplı bir dairenin temsilini görüntülemek için karakter sayısına göre en kısa kod ve *ardından yaklaşık π.

Giriş tek bir sayıdır R.

Çoğu bilgisayar neredeyse 2: 1 oranına sahip gibi göründüğünden, yalnızca tek olan satırları çıkarmalısınız y. Bu R, garip olduğunda R-1satır yazdırmanız gerektiği anlamına gelir . Açıklığa R=13kavuşturmak için yeni bir test çantası var .

Örneğin.

Input
    5
Output      Correct                          Incorrect

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

Düzenleme: Tek değerlerinin neden olduğu yaygın karışıklık nedeniyle R, aşağıda verilen 4 test senaryosunu geçen herhangi bir çözüm kabul edilecektir.

Π yaklaşımı, *karakter sayısının iki katına bölünmesiyle verilir .
Yaklaşım, en az 6 anlamlı basamağa doğru olmalıdır.
Lider veya sondaki sıfırlar bu yüzden, örneğin, herhangi bir izin verilir 3, 3.000000, 003girdileri kabul edilir 2ve 4.

Kod sayısı giriş / çıkışı içerir (yani, tam program).

Test Durumları

Input
    2
Output
     *** 
     *** 
    3.0

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

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

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

Bonus Test Örneği

Input
    13
Output

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

"Girdi" nin komut satırında mı yoksa stdin'de mi olduğunu açıklığa kavuşturmak isteyebilirsiniz.
Greg Hewgill

1
@Greg Hewgill, Kullandığınız dil için en uygun olanı seçmekten çekinmeyin :)
John La Rooy

@Greg Hewgill, Bazı (yani, çok az) programlama dili uygulamaları "komut satırı" nosyonuna sahip değildir.
Joey Adams

1
Cevaplardan çok azının, y'nin tek olduğu satırları koyma kuralına uyduğunu fark ettim. Tek bir r değeri verildiğinde (test durumlarında gösterilmemiştir), çoğu y'nin çift olduğu satırları çıkaracaktır!
MtnViewMark

6
Kural suistimali sorgulaması: Yalnızca gerekli 4 test durumunu destekleyerek başkalarının kodundan daha kısa kod oluşturun .
Brian

Yanıtlar:


15

Dc: 88 ve 93 93 94 96102105129138141 karakter

Her ihtimale karşı, bu noktada OpenBSD ve taşınabilir olmayan bazı uzantıları kullanıyorum.

93 karakter. Bu, FORTRAN çözümüyle aynı formüle dayanmaktadır (test durumlarından biraz farklı sonuçlar). Her Y için X ^ 2 = R ^ 2-Y ^ 2'yi hesaplar

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

88 karakter. Yinelemeli çözüm. Test durumlarını eşleştirir. Her X ve Y için X ^ 2 + Y ^ 2 <= R ^ 2 olup olmadığını kontrol eder

1?dsMdd*sRd2%--sY[0lM-[dd*lYd*+lRr(2*d5*32+PlN+sN1+dlM!<x]dsxxAPlY2+dsYlM>y]
dsyx5klNlR/p

Koşmak için dc pi.dc.

İşte açıklamalı daha eski bir sürüm:

# 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
Linux dc ile çalışmıyor, ancak openbsd üzerinde çalıştığını doğrulayabilirim . Harika!
John La Rooy

@Carlos, evet (operatör kesinlikle kullanışlı. çok kötü, linux ile gelen dc'de uygulanmadan kalıyor
John La Rooy

@gnibbler - "DC komutunun bn (3) büyük sayı rutinleri kullanılarak tamamen yeniden yazılması ilk olarak OpenBSD 3.5'te ortaya çıktı." Bunu bilmiyordum. Bazı güzel yeni operatörler dahil edilmiştir, ancak bunlar "taşınabilir olmayan uzantılar" olarak işaretlenmiştir.
Carlos Gutiérrez

Evet, (tek başına operatörün 6 vuruş
atmasına

119

C: 131 karakter

(Joey'nin C ++ çözümüne göre)

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

(Değiştir i|=-niçin i-=ntek sayı vakalarının desteğini kaldırın. Bu sadece 130 için karakter sayısı azalır)

Daire olarak:

      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
Bir çevreye dönüştürmek için koda nasıl daire eklediğinizi beğendim. +000 tercih edilir mi?
Potatoswatter

tebrikler, j * j ++ tanımlanmamış bir davranış
sellibitze

1
bu sadece bir karakter olmaz mıydı ...?
Ponkadoodle

1
main()Dört intargüman nasıl alınır ?
David R Tribble

2
@Yükleme: 5.1.2.2.1 / 1: Program başlangıcında çağrılan işlev adlandırılır main. Tanımlanmalıdır… veya başka bir uygulama tanımlı şekilde . Bunun nedeni, uygulamanın bu formu kabul edebilmesidir.
kennytm

46

XSLT 1.0

Eğlenmek için işte bir XSLT sürümü. Gerçekten kod golf materyali değil, ancak sorunu garip-işlevsel-XSLT tarzı bir şekilde çözüyor :)

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

Test etmek istiyorsanız, farklı kaydedin pi.xsltve aşağıdaki XML dosyasını IE'de açın:

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

42
<eyes> </eyes>! Gözlükler <do> hiçbir şey </do>!
Jimmy

1
Dang! Korkarım ki HyperCard çözümümü benzersizliği için geçmiş olabilirsiniz: D
Joey Adams

7
"
Open

Heh, evet, o günlerde sadece IE vardı ve XSLT ile XML tüm sorunlarımızın çözümüydü. Eski güzel zamanlar! :)
Danko Durbić

XSL sürüm 1.0 vay, sürüm 2'yi dört gözle beklediğimi hatırlıyorum ama çıktığında çoktan devam etmiştim.
gradbot

35

Perl, 95 96 99 106 109 110 119 karakterler:

$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

(Yeni satır kaldırılabilir ve yalnızca bir kaydırma çubuğundan kaçınmak için vardır)

Yaşasın! Çember versiyonu!

    $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

Deneyimsizler için uzun versiyon:

#!/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
Bu, hayatım boyunca gördüğüm en okunamayan
koddu

13
Sanırım APL'yi hiç görmediniz.
Peter Wone

5
@Chris Marisic: Etiketli diğer soruları / konuları kontrol ettiniz mi code-golf? :) Çok daha okunamayan örnekler gördüm.
BalusC

3
@Peter: Çoğunun aksine, APL'yi hem gördüm hem de yazdım. Özel karakterlerine alışmak birkaç hafta sürüyor, ancak ondan sonra oldukça okunabilir hale geliyor. Birkaç on yıl alıştıktan sonra bile Perl hala çok daha kötü.
Jerry Coffin

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

$ 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

Bir dakika, Fortran'da biçimlendirmenin önemli olduğunu düşündüm. 1. sütunda harfler var!
Joel

Çoğu insan gördüklerime göre hala Fortan77'de takılıp kalıyor.
Joel

8
Daire versiyonunun Ölüm Yıldızı'na nasıl benzediğini seviyorum.
mskfisher

22

x86 Makine Kodu: 127 bayt

Intel Assembler: 490 karakter

    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

Bu sürüm, bonus test durumunu da ele alır ve 133 bayttır:

    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
StackOverflow'u seviyorum!
zengr

2
Bazı yüksek seviyeli dillerin, bunun ürettiği ikiliden daha kısa karakter sayılarına sahip olması ilginçtir.
Colin Valliant

3
@Alcari: Üst düzey dillerin kullandığı kitaplıklara tüm kodları dahil ederseniz, karakter sayıları önemli ölçüde daha yüksek olacaktır. Assembler'da yapmak printf("%f",a/b)önemsiz değildir , bunu yapacak tek bir talimat yoktur ve yukarıdaki uygulamam 0 <= a / b <10 olduğunu ve işlemin bir bölme ve a ve b'nin tamsayı olduğunu varsayar.
Skizz

19

Python: 101 104 107 110 karakter

Nicholas Riley'nin diğer Python sürümüne dayanmaktadır.

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

Bazı matematik için AlcariTheMad'e krediler.


Ah, tek sayılı olanlar ortada sıfır ile indeksleniyor, her şeyi açıklıyor.

Bonus Python: 115 karakter (hızla birlikte hacklenir)

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

Vay be, evet, '+' -1'i ve herhangi bir günde atar. Aklımdan çıkardığım bir başka teknik de, çünkü neredeyse hiçbir zaman yapılacak doğru şey değil :-)
Nicholas Riley

Geçmişte C kullandım ve Python'a hiç bakmadım. Bu 104 karakter, yukarıdaki C ++ 'dan daha okunabilir. İnanılmaz. Belki Python öğrenmeliyim ...
Dean Yerine

@Dean: Python'un ana hedeflerinden biri okuması ve yazması kolay olmaktır.
Colin Valliant

104 karakterlik cevabınızla exec kullanmayı da düşündünüz mü? :)
John La Rooy

Kendi sıkıştırmamı döndürmem gerekiyordu - zlib, sıralama vb. Hepsi gerçek koddan daha büyük çıktı.
lunixbochs

12

Güç kalkanı, 119 113 109 karakter

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

ve işte daha güzel bir versiyon:

( $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: Umarım hayır, ama bu yazdığım en çirkin şey olmalı :)
Danko Durbić

3
Bu güzel sürüm için teşekkürler =)
Thor Hovden

10

HyperTalk: 237 karakter

Girinti gerekli değildir veya sayılmaz. Netlik için eklenmiştir. Ayrıca HyperCard 2.2'nin, kullandığım ASCII olmayan ilişkisel operatörleri kabul ettiğini unutmayın.

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

HyperCard 2.2, stdin / stdout'u desteklemediğinden, bunun yerine bir işlev sağlanır.


1
Hypercard, Bay Adams? Ciddi anlamda? Bu çok beklenmedik bir durum.
Kawa

1
@Kawa: İşte bu yüzden yayınladım :) Ayrıca, gelecekte bir HyperTalk tercümanı yazmaya karar verirsem diye kod golfü bir test paketi oluşturmanın iyi bir yoludur.
Joey Adams

Hah! Bunu görmek isterim, XD
Kawa

O tercümanı yazmaya karar verirseniz veya mevcut bir tercümanın üzerinde çalışmaya katılmak isterseniz, bana bildirin ve
hypercard.org'da bundan bahsedebilirim ve

10

C #: 209202201 karakter:

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

Küçültülmemiş:

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

C # 'i pek bilmiyorum ama string[]ave 1-r(yerine -1+r) kullanabilmeniz gerekmez mi ?
kennytm

@Kenny: Haklısın. :) Bu üç karakter kurtarıyor ve sonra beş karakterden daha kurtulmayı başardım.
Guffa

İlk şeyi fark ettim, tamamen ıskaladım -r+1.
Dykam

4
Ayrıca, ben de görüldü x*xx+++y*y, ancak ilk bakışta incelemek çılgınca bir şey.
Dykam

Başka bir baytı ortadan kaldırmanın özgürlüğünü yaşadım ;-)
Joey

10

139 Haskell 145 147 150 230 karakter:

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

Tek sayıları işleme: 148 karakter:

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 karakter: (C sürümüne göre.)

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

main = do {r <-read`fmap`getLine; let {p = putStr; d = 2 / fromIntegral r ^ 2; lyn = let cmx = eğer x> r ise p "\ n" >> x ise m başka döndür * x + y * y <r * r sonra p "*" >> c (m + d) (x + 1) else p "" >> cm (x + 1), eğer y> r ise o zaman n başka yazdır cn (-r) >> = l (y + 2)}; l (1-r`mod`2-r) 0}

Küçültülmemiş:

main = do r <- `fmap` getLine'ı okuyun
          p = putStr olsun
              d = 2 / integralden r ^ 2
              lyn = let cmx = eğer x> r
                                  sonra p "\ n" >> dönüş m
                                  aksi takdirde x * x + y * y <r * r
                                       sonra p "*" >> c (m + d) (x + 1)
                                       başka p "" >> cm (x + 1)
                      y> r ise
                         sonra n yazdır
                         başka cn (-r) >> = l (y + 2)
          l (1-r`mod`2-r) 0

Bazı zorunlu sürümleri yeneceğini umuyordum, ancak bu noktada daha fazla sıkıştıramıyorum.


"D" harfini kaldırıp yerine 1 ekleyerek ve ardından "2 * n / fromIntegral r ^ 2" yazdırarak 2 tane daha kesildi
Steve

Birkaç Haskell numarasıyla 3 karakteri tıraş ettim. Haskell'de genellikle birden fazla satıra (satırsonu ve noktalı virgül) maliyetin olmaması ve bu nedenle kod golfümüzün genel olarak okunabilir olmasını seviyorum!
MtnViewMark

145 karakterli versiyon, yalnızca giriş çift ise çalışır. Ama her iki şekilde de çok güzel.
Steve

G / Ç hattı kısaltıldı. Defs fonksiyonunu bir main = do {... let {...} ...} bloğuna iterek birkaç karakter daha kaydetmenin yine de mümkün olduğunu düşünüyorum.
comingstorm

@comingstorm: Harika! ReadLn'yi bilmiyordum. Bu, birçok Haskell kod golfüne yardımcı olacaktır. @Steve: Evet, hala bunu düzeltmenin en verimli yolunu bulmaya çalışıyorum.
MtnViewMark

10

Yakut, 96 karakter

(Guffa'nın C # çözümüne göre):

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

Teşekkürler! Ruby'nin ne kadar okunamaz olabileceğini görmek beni utandırıyor ... :)
Mladen Jablanović

p syerine kullanabilirsiniz puts s:)
John La Rooy

1
Güzel yeni fikirler - 2 farklı adım boyutuna sahip g ve <=> kodunu mantıksaldan dönüştürmek için kod kullanmaktan kaçınmak hoşuma gidiyor
John La Rooy

9

PHP: 117

Dev-null-dweller'a göre

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

Çok fazla düşünüyorsunuz.

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

8
Karakter sayımı biraz kontrolden çıkıyor, sence de öyle değil mi? :)
John La Rooy

7
Ölçeklenmiyor. Sürdürülemez!
spoulson

Test
senaryosunu

5
+1, her zaman en bariz şeyi ilk önce yap ... eğer birisi beğenmezse, şartnamenin yeterince net olmadığından yüksek sesle şikayet et
Mizipzor

Brian, test vakalarını özel olarak incelemek için yarı ciddi bir girişimde bulundu, bu cevabı beğendiyseniz, onun da üzerine oy vermelisiniz;) stackoverflow.com/questions/2457995
John La Rooy

7

J: 47 , 46 , 45

Diğer çözümlerle aynı temel fikir, yani r ^ 2 <= x ^ 2 + y ^ 2 , ancak J'nin dizi odaklı gösterimi ifadeyi basitleştirir:

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

Sen gibi derdim c 2ya c 8ya c 10vs.

Bonus: 49

13Tek sayı girdisini işlemek için, örneğin , çıktıların diğer tüm satırlarını almak yerine tek değerli x koordinatlarını filtrelemeliyiz (çünkü artık endeksler çift veya tek sayıdan başlayabilir). Bu genelleme bize 4 karaktere mal oluyor:

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

Küçültülmüş versiyon:

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
)

J Forumlarında Marshall Lochbam nedeniyle yapılan iyileştirmeler ve genellemeler .


5

Python: 118 karakter

Perl versiyonunun oldukça basit bir portu.

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

Python2 için şunu kullanabilirsinizr=input()
John La Rooy

Sen arasında boşluk gerekmez printve' '
John La Rooy

Tamam, bu korkutucu, artık Perl versiyonundan daha kısa. ("Girdi" yi tamamen aklımdan çıkardım çünkü normalde çok güvensizdir ...)
Nicholas Riley

4

C ++: 169 karakter

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

Küçültülmemiş:

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

(Evet, using namespace stddaha az karakter kullanmak yerine std :: kullanmak )

Buradaki çıktı, orijinal gönderideki test senaryolarıyla eşleşmiyor, işte uyan bir tane (okunabilirlik için yazılmıştır). Bunu bir referans uygulaması olarak kabul edin (Poita_ aldırmazsa):

#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 karakter (doğru olduğuna inandığım çıktıyla)

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

Kod, -n'den n'ye döngüler, bu nedenle örneğin 4'ün bir girişi için, test durumlarında gösterildiği gibi 7 değil, 9'luk bir çap görüntüler.
Guffa

Çevrenizin OP'lere tam olarak uyması bir gereklilik mi?
Peter Alexander

3
#include <iostream.h>Temelde #include <iostream> -- using namespace std;eski C ++ derleyicileriyle uyumluluk için olanı değiştirmek isteyebilirsiniz .
Earlz

1
@Carlos, o kısmı yazmadım ama bu bir ikili AND operatörü. Yapmakla eşdeğer olan i%2, ancak "daha hızlı" olan son bitin ayarlandığını kontrol eder . Gerçekten daha hızlı değil çünkü derleyici yine de yapardı.
Peter Alexander

1
@Poita_: Aslında, i% 2 ve i & 1 negatif sayılarla farklı davranıyor. (-1) & 1 1'dir, burada istediğimiz de budur. (-1)% 2 benim sistemimde -1 ve bu C99 ile uyumlu. Dolayısıyla, if (i & 1) ve if (i% 2) aynı şeyi yapacak olsa da, i negatif olduğunda işe yaramayacak if (i% 2 == 1) konusunda dikkatli olunmalıdır.
Joey Adams

3

PHP: 126132138

(Guffa C # çözümüne göre)

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;

Şu anki dolu:

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;

@İlk önce olmadan olabilir, $sancak yalnızca error_reporting 0 olarak ayarlanmışsa (Notice outputs, messing the circle)


echo $ s * 2 / $ r / $ r'de / $ r ne yapar;
davidosomething

OHH bölümü ... boşluk beni
şaşırttı,

3

Yakut 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

İle çalıştırın $ ruby -p piday


Güzel bir örnek, ancak pi
tahminini

1.9.1'de çalışmaz ve dairenin çevresine çift tırnak işareti koyar.
Mladen Jablanović

Golf programlarının çılgınca farklı dil seviyelerinde çalışmaması normaldir. Dilin her sürümünde kaç Perl veya Python cg çalışır? İlginçtir, bunun nedeni Integer|Floatartık 1.9'daki float'ı zorlamamasıdır.
DigitalRoss

3

APL: 59

Bu işlev bir sayıyı kabul eder ve beklenen iki öğeyi döndürür. Bonus durumlarda düzgün çalışır.

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

Diyalekt, varsayılan dizin orijinli Dyalog APL'dir. Beceri seviyesi bilgisiz acemidir , bu yüzden herhangi bir APL gurusu onu 10 karaktere indirmek isterse, konuğum olun!


Try APL'de çevrimiçi deneyebilirsiniz , sadece yapıştırın ve arkasına bir sayı girin:

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

APL'yi bilmeme rağmen, J versiyonundan daha güzel görünüyor.
ahala

@ahala Gerçekten. APL hem kavramsal hem de estetik olarak güzeldir. J öğrenmeye başladım, ancak rastgele ASCII çılgınlığı tarafından kapatıldım. İyi bir ruh, Node.js (npm install apl) için oldukça iyi bir açık kaynak APL yorumlayıcısı yazdı. Yukarıdaki kodu sadece küçük bir değişiklikle hesaplar (monadik yok , 2. karakter.) Dyalog gibi tüm satıcı sitelerinde iyi APL belgeleri bulabilirsiniz.
Tobia

2

Ve bir bash girdisi: 181 186 190 karakter

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

Örn. İle çalıştırın bash py.sh 13


2

Python: 148 karakter.

Orijinal gönderiye yanıt olarak bahsettiğim gibi, başarısız oldu (yani yeterince kısa değil) kuralları kötüye kullanma ve test senaryolarını sabit kodlama girişimi. Daha ayrıntılı bir dille kötüye kullanmak daha kolay olabilirdi:

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

bc: 165 , 127 , 126 karakter

Python sürümüne göre.

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

(Son satırdan sonraki yeni satır burada ihmal edilemez.)


1
127 karakter: r = oku (); for (i = 1; i <r * 2; ölçek = 6) {n = sqrt (2 * i r-i i); ölçek = 0; n = 1 + n / 1 * 2 ; i + = 2; j = rn / 2; t + = 2 * n; while (j--) ""; while (n -) "*"; ""}; t / r / r
Carlos Gutiérrez

Buradaki tek sorun, artık 0 için başarısız olması, ancak mevcut kurallara göre sorun değil.
przemoc

2

JavaScript (SpiderMonkey) - 118 karakter

Bu sürüm stdin'den girdi kabul eder ve bonus test durumlarını geçer

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)

Kullanım: cat 10 | js thisfile.js - jsbin önizleme , tarayıcıda görüntüleyebilmeniz için yazdırma / okuma satırı için bir takma ad ekler

Javascript: 213 163


Güncellenmiş

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

Tarayıcıda doğru şekilde oluşturulması gerektiğini kimse söylemedi - sadece çıktı. Bu nedenle ön etiketleri kaldırdım ve daha da optimize ettim. Çıktıyı görüntülemek için, oluşturulan kaynağı görüntülemeniz veya stil sayfanızı buna göre ayarlamanız gerekir. Pi bu şekilde daha az doğrudur, ancak şimdi spesifikasyona göre.


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

Küçültülmemiş:

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

Küçültülmemiş:

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

Bunu
Scala'da

1

GAWK: 136 , 132 , 126 , 125 karakter

Python sürümüne göre.

{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}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.