Code Golf - ngày π


95

Các thách thức

Hướng dẫn chơi gôn mã trên SO

Mã ngắn nhất tính theo số ký tự để hiển thị biểu diễn của một vòng tròn bán kính Rbằng cách sử dụng* ký tự, theo sau là một giá trị xấp xỉ của π.

Đầu vào là một số duy nhất, R .

Vì hầu hết các máy tính dường như có tỷ lệ gần như 2: 1, bạn chỉ nên xuất các dòng ở vị trí ylẻ. Điều này có nghĩa là khi Rlà số lẻ, bạn nên in R-1dòng. Có một testcase mới choR=13 để làm rõ.

ví dụ.

Input
    5
Output      Correct                          Incorrect

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

Chỉnh sửa: Do sự nhầm lẫn phổ biến gây ra bởi các giá trị lẻ củaR , bất kỳ giải pháp nào vượt qua 4 trường hợp kiểm tra được đưa ra bên dưới sẽ được chấp nhận

Tính gần đúng của π được cho bằng cách chia hai lần số *ký tự cho .
Giá trị gần đúng phải đúng với ít nhất 6 chữ số có nghĩa.
Đầu hay ở cuối số không được phép, vì vậy ví dụ bất kỳ 3, 3.000000, 003được chấp nhận cho đầu vào của 24.

Số lượng mã bao gồm đầu vào / đầu ra (tức là chương trình đầy đủ).

Các trường hợp kiểm tra

Input
    2
Output
     *** 
     *** 
    3.0

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

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

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

Kiểm tra phần thưởng

Input
    13
Output

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

Bạn có thể muốn làm rõ xem "đầu vào" nằm trên dòng lệnh hay trên stdin.
Greg Hewgill

1
@Greg Hewgill, Hãy thoải mái chọn ngôn ngữ nào thuận tiện nhất cho ngôn ngữ bạn đang sử dụng :)
John La Rooy

@Greg Hewgill, Một số (tức là rất ít) triển khai ngôn ngữ lập trình không có khái niệm về "dòng lệnh".
Joey Adams

1
Tôi nhận thấy rằng một số câu trả lời tuân theo quy tắc chỉ đặt ra những dòng có y là số lẻ. Cho một giá trị lẻ của r (không được hiển thị trong các trường hợp thử nghiệm), hầu hết sẽ xuất ra các dòng trong đó y là chẵn!
MtnViewMark

6
Thử thách lạm dụng quy tắc: Tạo mã ngắn hơn mã của bất kỳ ai khác bằng cách chỉ hỗ trợ 4 trường hợp thử nghiệm bắt buộc.
Brian

Câu trả lời:


15

Trong dc: 88 và 93 93 94 96 102 105 129 138 141 ký tự

Đề phòng trường hợp, tôi đang sử dụng OpenBSD và một số tiện ích mở rộng được cho là không di động tại thời điểm này.

93 ký tự. Điều này dựa trên công thức tương tự như giải pháp FORTRAN (kết quả hơi khác so với các trường hợp thử nghiệm). Tính X ^ 2 = R ^ 2-Y ^ 2 cho mọi Y

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

88 ký tự. Giải pháp lặp lại. Đối sánh các trường hợp thử nghiệm. Với mọi X và Y kiểm tra xem 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

Để chạy dc pi.dc.

Đây là phiên bản có chú thích cũ hơn:

# 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
Không hoạt động với linux dc, nhưng tôi có thể xác nhận nó hoạt động trên openbsd . Tuyệt vời!
John La Rooy

@Carlos, vâng, người (điều hành chắc chắn rất tiện. quá xấu nó vẫn chưa thực hiện trong dc mà đi kèm với linux
John La Rooy

@gnibbler - "Việc viết lại hoàn toàn lệnh dc bằng cách sử dụng các quy trình số lớn bn (3) lần đầu tiên xuất hiện trong OpenBSD 3.5." Tôi không biết điều đó. Một số nhà khai thác mới tốt được bao gồm, nhưng chúng được đánh dấu là "phần mở rộng không di động".
Carlos Gutiérrez

Yeah, (điều hành một mình được phép đổ 6 đột quỵ!
Dan Andreatta

119

C: 131 ký tự

(Dựa trên giải pháp C ++ của 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);}

(Thay đổi i|=-nthành i-=nđể loại bỏ hỗ trợ của các trường hợp số lẻ. Điều này chỉ làm giảm số lượng ký tự xuống 130.)

Như một vòng kết nối:

      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
Tôi thích cách bạn thêm vòng kết nối vào mã để biến nó thành một vòng kết nối. +000 có thích hợp hơn không?
Potatoswatter

xin chúc mừng, j * j ++ là undefined hành vi
sellibitze

1
đó sẽ không chỉ là một ký tự ...?
Ponkadoodle

1
Làm thế nào để main()có bốn intđối số?
David R Tribble vào

2
@Load: 5.1.2.2.1 / 1: Hàm được gọi khi khởi động chương trình được đặt tên main. Nó sẽ được định nghĩa… hoặc theo một số cách thức triển khai khác được xác định . Vì vậy, đó là bởi vì triển khai có thể chấp nhận biểu mẫu này.
kennytm

46

XSLT 1.0

Chỉ cho vui thôi, đây là phiên bản XSLT. Không hẳn là tài liệu về mã-gôn, nhưng nó giải quyết vấn đề theo cách-chức-năng-XSLT kỳ lạ :)

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

Nếu bạn muốn kiểm tra nó, hãy lưu nó dưới dạng pi.xsltvà mở tệp XML sau trong IE:

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

42
<eyes> </eyes> của tôi! Kính bảo hộ, chúng <do> không có gì </do>!
Jimmy

1
Dang! Tôi sợ bạn có thể đã bị đánh đập giải pháp HyperCard tôi cho độc đáo: D
Joey Adams

7
Tôi không thể tin rằng bạn nói "mở ... IE"
Harpo

Heh, vâng, trước đây, chúng ta chỉ có IE và XML với XSLT là giải pháp cho mọi vấn đề của chúng ta. Ngày xưa tốt đẹp! :)
Danko Durbić

XSL phiên bản 1.0 wow, tôi nhớ mình đã mong chờ phiên bản 2 nhưng đến khi nó ra mắt thì tôi đã chuyển sang.
gradbot

35

Perl, 95 96 99 106 109 110 119 nhân vật:

$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

(Dòng mới có thể bị xóa và chỉ ở đó để tránh thanh cuộn)

Yay! Phiên bản vòng tròn!

    $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

Đối với người chưa bắt đầu, phiên bản dài:

#!/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
Đó là bởi đến nay các mã không đọc được nhất mà tôi đã nhìn thấy trong toàn bộ cuộc sống của tôi
Chris Marisic

13
Tôi đoán bạn chưa bao giờ thấy APL sau đó.
Peter Wone

5
@Chris Marisic: Bạn đã kiểm tra các câu hỏi / chủ đề khác được gắn thẻ code-golfchưa? :) Tôi đã thấy nhiều ví dụ khó đọc hơn.
BalusC

3
@Peter: Không giống như hầu hết, tôi vừa xem và viết APL. Phải mất một vài tuần để làm quen với các ký tự đặc biệt của nó, nhưng sau đó nó có thể khá dễ đọc. Ngay cả sau vài thập kỷ để làm quen, Perl vẫn còn tệ hơn nhiều.
Jerry Coffin

1
111 ký tự,$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 ký tự

$ 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

Chờ đã, tôi mặc dù định dạng rất quan trọng trong Fortran? Bạn có các chữ cái trong cột 1!
Joel

Hầu hết mọi người vẫn bị mắc kẹt trên Fortan77 từ những gì tôi đã thấy.
Joel

8
Tôi thích cách phiên bản hình tròn trông giống như Death Star.
mskfisher

22

x86 Mã máy: 127 byte

Intel Assembler: 490 ký tự

    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

Phiên bản này cũng xử lý trường hợp thử nghiệm thưởng và có kích thước 133 byte:

    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
Tôi yêu StackOverflow!
zengr

2
Thật thú vị khi một số ngôn ngữ cấp cao có số lượng ký tự ngắn hơn số nhị phân mà nó tạo ra.
Colin Valliant

3
@Alcari: Nếu bạn đưa tất cả mã vào các thư viện mà các ngôn ngữ cấp cao hơn sử dụng, số ký tự của chúng sẽ cao hơn đáng kể. Trong trình hợp ngữ, việc làm printf("%f",a/b)không hề nhỏ, không có chỉ dẫn nào để làm điều đó và việc thực hiện của tôi ở trên giả định rằng 0 <= a / b <10 và phép toán là một phép chia và a và b là các số nguyên.
Skizz

19

Python: 101 104 107 110 ký tự

Dựa trên phiên bản Python khác của 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

Tín dụng cho AlcariTheMad cho một số phép toán.


À, những cái được đánh số lẻ được lập chỉ mục với số 0 ở giữa, giải thích mọi thứ.

Thưởng Python: 115 ký tự (nhanh chóng được hack cùng nhau)

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

Ồ, vâng, '+' đập -1 và bất kỳ ngày nào. Tuy nhiên, kỹ thuật khác tôi đặt ra khỏi tâm trí của tôi, vì nó hầu như không bao giờ là điều đúng đắn nên làm :-)
Nicholas Riley

Tôi đã sử dụng C trong quá khứ và thậm chí chưa bao giờ nhìn vào Python. 104 ký tự này dễ đọc hơn C ++ ở trên. Kinh ngạc. Có lẽ tôi nên học Python ...
Dean Thay

@Dean: Một trong những mục tiêu chính của Python là dễ đọc và dễ viết.
Colin Valliant

bạn đã từng sử dụng hành động với câu trả lời ký tự 104 của bạn quá? :)
John La Rooy

Tôi sẽ cần cuộn nén của riêng mình - zlib, marshalling, v.v. tất cả đều lớn hơn mã thực.
lunixbochs 19/03

12

Powershell, 119 113 109 ký tự

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

và đây là một phiên bản đẹp hơn:

( $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: Tôi hy vọng là không, nhưng đây phải là điều xấu xí nhất mà tôi từng viết :)
Danko Durbić Ngày

3
Nhờ cho rằng phiên bản đẹp =)
Thor Hovden

10

HyperTalk: 237 ký tự

Thụt lề không bắt buộc cũng như không được tính. Nó được thêm vào để rõ ràng. Cũng lưu ý rằng HyperCard 2.2 không chấp nhận các toán tử quan hệ không phải ASCII mà tôi đã sử dụng.

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

Vì HyperCard 2.2 không hỗ trợ stdin / stdout, một chức năng được cung cấp thay thế.


1
Hypercard, ông Adams? Nghiêm túc? Đây là điều rất bất ngờ.
Kawa

1
@Kawa: Đó là lý do tại sao tôi đăng nó :) Ngoài ra, chơi gôn mã là một cách tốt để xây dựng bộ thử nghiệm trong trường hợp tôi quyết định viết một trình thông dịch HyperTalk trong tương lai.
Joey Adams

Hả! Tôi muốn thấy điều đó, XD
Kawa

Nếu bạn quyết định viết thông dịch viên đó hoặc muốn tham gia công việc trên một phiên dịch hiện có, hãy cho tôi biết và tôi có thể thêm đề cập về nó trên hypercard.org và tôi rất tò mò về cách nó diễn ra :-)
uliwitness

10

C #: 209 202 201 ký tự:

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

Chưa xác minh:

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

Tôi không biết C # nhiều lắm nhưng liệu bạn có thể sử dụng string[]a1-r(thay vì -1+r)?
kennytm

@Kenny: Bạn nói đúng. :) Điều đó tiết kiệm được ba ký tự, và sau đó tôi đã cố gắng loại bỏ năm ký tự nữa.
Guffa

Phát hiện ra điều đầu tiên, hoàn toàn bỏ lỡ điều đó -r+1.
Dykam

4
Ngoài ra, cũng phát hiện ra x*xx+++y*y, nhưng nó là một điều điên rồ khi mổ xẻ ngay từ cái nhìn đầu tiên.
Dykam

Tôi đã tự do loại bỏ một byte khác ;-)
Joey

10

Haskell 139 145 147 150 230 ký tự:

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

Xử lý các số lẻ: 148 ký tự:

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 ký tự: (Dựa trên phiên bả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 ký tự:

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

Chưa xác minh:

main = do r <- đọc `fmap` getLine
          let p = putStr
              d = 2 / fromIntegral r ^ 2
              lyn = để cmx = nếu x> r
                                  sau đó p "\ n" >> trả về m
                                  khác nếu x * x + y * y <r * r
                                       thì p "*" >> c (m + d) (x + 1)
                                       khác p "" >> cm (x + 1)
                      trong nếu y> r
                         sau đó in n
                         khác cn (-r) >> = l (y + 2)
          l (1-r`mod`2-r) 0

Tôi đã hy vọng nó sẽ đánh bại một số phiên bản bắt buộc, nhưng tôi dường như không thể nén nó thêm nữa vào thời điểm này.


Cắt bớt 2 nữa bằng cách loại bỏ "d" và thêm 1 thay vào đó và sau đó in "2 * n / fromIntegral r ^ 2"
Steve

Loại bỏ 3 ký tự thông qua một vài thủ thuật Haskell. Tôi thích rằng trong Haskell thường không có chi phí cho nhiều dòng (dòng mới so với dấu chấm phẩy) và do đó mã-gôn của chúng tôi thường có thể đọc được!
MtnViewMark

Nói một cách chính xác, phiên bản 145-char chỉ hoạt động nếu đầu vào là số chẵn. Nhưng rất tốt một trong hai cách.
Steve

Đã rút ngắn dòng I / O. Tôi nghĩ vẫn có thể lưu thêm một vài ký tự bằng cách đẩy hàm defs vào một khối main = do {... let {...} ...}.
bão tới,

@comingstorm: Hay quá! Tôi không biết về readLn. Điều này sẽ giúp nhiều người chơi mã Haskell. @Steve: Đúng vậy, tôi vẫn đang cố gắng tìm ra cách hiệu quả nhất để khắc phục điều đó.
MtnViewMark

10

Ruby, 96 ký tự

(dựa trên giải pháp C # của 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 ký tự (tiền thưởng):

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

Cảm ơn! Tôi xấu hổ khi thấy Ruby không thể đọc được ... :)
Mladen Jablanović Ngày

bạn cũng có thể sử dụng p sthay vì puts s:)
John La Rooy

1
Ý tưởng tươi đẹp trong đó - Tôi giống như là bạn đang sử dụng g với 2 kích thước bước khác nhau và <=> để tránh việc mã để chuyển đổi từ logic
John La Rooy

9

PHP: 117

Dựa trên 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

Các bạn đang nghĩ cách quá khó.

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

8
Bạn có nghĩ vậy không? :)
John La Rooy

7
Không mở rộng. Không thể giải thích được!
spoulson

Tôi đã cố gắng nén cheat trường hợp thử nghiệm càng nhiều càng tốt và nó vẫn kết thúc hơi lớn hơn giải pháp thực tế của tôi: P
lunixbochs

5
+1, luôn luôn làm những điều rõ ràng nhất đầu tiên ... nếu ai đó doesnt như nó, lớn tiếng phàn nàn rằng wasnt đặc tả đủ rõ ràng
Mizipzor

Brian đã có một nỗ lực bán nghiêm trọng tại đặc biệt vỏ các trường hợp kiểm tra, bạn nên upvote mình quá nếu bạn thích câu trả lời này;) stackoverflow.com/questions/2457995
John La Rooy

7

J: 47 , 46 , 45

Ý tưởng cơ bản giống như các giải pháp khác, tức là r ^ 2 <= x ^ 2 + y ^ 2 , nhưng ký hiệu hướng mảng của J đơn giản hóa biểu thức:

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

Bạn sẽ gọi nó như c 2hoặc c 8hoặc c 10v.v.

Tiền thưởng: 49

Ví dụ: để xử lý đầu vào lẻ 13, chúng ta phải lọc các tọa độ x có giá trị lẻ, thay vì chỉ đơn giản lấy mọi hàng đầu ra khác (vì bây giờ các chỉ số có thể bắt đầu bằng số chẵn hoặc số lẻ). Tổng quát hóa này tốn 4 ký tự:

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

Phiên bản giảm thiểu:

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
)

Cải tiến và khái quát do Marshall Lochbam trên Diễn đàn J .


5

Python: 118 ký tự

Khá nhiều cổng đơn giản của phiên bả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

Đối với python2 bạn chỉ có thể sử dụngr=input()
John La Rooy

Bạn không cần không gian giữa print' '
John La Rooy

OK, thật đáng sợ, nó ngắn hơn phiên bản Perl bây giờ. (Tôi hoàn toàn đặt "đầu vào" ra khỏi tâm trí của tôi, vì nó rất an toàn thông thường ...)
Nicholas Riley

4

C ++: 169 ký tự

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

Chưa xác minh:

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

(Có, sử dụng std :: thay vì using namespace stdsử dụng ít ký tự hơn)

Kết quả đầu ra ở đây không khớp với các trường hợp thử nghiệm trong bài đăng gốc, vì vậy đây là một trường hợp thử nghiệm (được viết để dễ đọc). Hãy coi đó là một triển khai tham chiếu (nếu Poita_ không phiền):

#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 ký tự (với đầu ra tôi tin là chính xác)

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

Mã lặp lại từ -n đến n, vì vậy đối với đầu vào của ví dụ 4, nó hiển thị đường kính là 9, không phải 7 như trong các trường hợp thử nghiệm.
Guffa

Có yêu cầu rằng vòng tròn của bạn khớp chính xác với OP không?
Peter Alexander

3
Bạn có thể muốn thay đổi nó #include <iostream.h>về cơ bản là #include <iostream> -- using namespace std;để tương thích với các trình biên dịch C ++ cũ.
Earlz

1
@Carlos, tôi không viết bit cụ thể đó, nhưng đó là toán tử AND nhị phân. Nó kiểm tra xem bit cuối cùng có được đặt hay không, tương đương với việc thực hiện i%2, nhưng "nhanh hơn". Nó không thực sự nhanh hơn vì dù sao thì trình biên dịch cũng sẽ làm được.
Peter Alexander

1
@Poita_: Trên thực tế, i% 2 và i & 1 cư xử khác nhau với các số âm. (-1) & 1 là 1, đó là những gì chúng tôi muốn ở đây. (-1)% 2 là -1 trên hệ thống của tôi và điều này tuân theo C99. Do đó, mặc dù if (i & 1) và if (i% 2) sẽ làm điều tương tự, nhưng người ta phải cẩn thận với if (i% 2 == 1), sẽ không hoạt động khi i là số âm.
Joey Adams

3

PHP: 126 132 138

(dựa trên giải pháp 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;

Hiện tại đầy đủ:

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;

Có thể không có @trước đầu tiên $snhưng chỉ với error_reporting được đặt thành 0 (Kết quả thông báo đang làm rối vòng tròn)


/ $ r làm gì trong echo $ s * 2 / $ r / $ r;
davidosomething

Bộ phận OHH ... khoảng cách đã khiến tôi thất vọng, nghĩ rằng đó là một số viết tắt của toán tử mà tôi chưa từng thấy
davidosomething

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

Chạy với $ ruby -p piday


Nice one, nhưng nó không in ra xấp xỉ pi
John La Rooy

Nó không hoạt động trong 1.9.1 và in dấu ngoặc kép xung quanh vòng tròn.
Mladen Jablanović

Các chương trình chơi gôn không hoạt động ở các cấp độ ngôn ngữ khác nhau là điều bình thường. Có bao nhiêu Perl hoặc Python cg hoạt động trên mọi phiên bản của ngôn ngữ? Tuy nhiên, thật thú vị, lý do là vì Integer|Floatkhông còn cưỡng chế phao trên 1.9.
DigitalRoss

3

APL: 59

Hàm này chấp nhận một số và trả về hai mục được mong đợi. Hoạt động chính xác trong các trường hợp tiền thưởng.

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

Phương ngữ là Dyalog APL, với nguồn gốc chỉ mục mặc định. Cấp độ kỹ năng là một người mới không biết gì về kỹ năng , vì vậy nếu bất kỳ chuyên gia APL nào muốn hạ nó xuống 10 ký tự, hãy là khách của tôi!


Bạn có thể dùng thử trực tuyến trên Thử APL , chỉ cần dán nó vào và đặt một số sau nó:

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

Mặc dù tôi không biết APL, nó trông đẹp hơn phiên bản J.
ahala

@ahala Thật vậy. APL đẹp, cả về mặt khái niệm và thẩm mỹ. Tôi bắt đầu học J, nhưng đã bị tắt bởi sự điên cuồng ASCII ngẫu nhiên. Một linh hồn tốt đã viết một trình thông dịch APL mã nguồn mở cho Node.js (npm install apl) khá tốt. Nó tính toán mã trên chỉ với một thay đổi nhỏ (không có đơn nguyên , ký tự thứ 2.) Bạn có thể tìm thấy tài liệu APL tốt trên tất cả các trang web của nhà cung cấp, chẳng hạn như Dyalog.
Tobia

2

Và một mục nhập bash: 181 186 190 ký tự

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

Chạy với vd bash py.sh 13


2

Python: 148 ký tự.

Không thành công (nghĩa là không đủ ngắn) cố gắng lạm dụng các quy tắc và mã hóa cứng các trường hợp thử nghiệm, như tôi đã đề cập trong phần trả lời bài đăng gốc. Lạm dụng nó với một ngôn ngữ dài dòng hơn có thể dễ dàng hơn:

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 ký tự

Dựa trên phiên bản 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

(Không thể bỏ qua dòng mới sau dòng cuối cùng ở đây.)


1
127 ký tự: r = read (); for (i = 1; i <r * 2; scale = 6) {n = sqrt (2 * i r-i i); scale = 0; n = 1 + n / 1 * 2 ; i + = 2; j = rn / 2; t + = 2 * n; while (j--) ""; while (n -) "*"; ""}; t / r / r
Carlos Gutiérrez

Vấn đề duy nhất ở đây là bây giờ nó không thành công với 0, nhưng theo các quy tắc hiện tại, nó ổn.
przemoc

2

JavaScript (SpiderMonkey) - 118 ký tự

Phiên bản này chấp nhận đầu vào từ stdin và vượt qua các trường hợp kiểm tra thưởng

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)

Cách sử dụng: cat 10 | js thisfile.js - Xem trước jsbin thêm bí danh cho dòng in / dòng đọc để bạn có thể xem trong trình duyệt

Javascript: 213 163


Đã cập nhật

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

Không ai nói rằng nó phải hiển thị chính xác trong trình duyệt - chỉ là đầu ra. Vì vậy, tôi đã loại bỏ các thẻ trước và tối ưu hóa nó hơn nữa. Để xem đầu ra, bạn cần xem nguồn đã tạo hoặc đặt biểu định kiểu của mình cho phù hợp. Theo cách này, số Pi kém chính xác hơn, nhưng bây giờ nó là thông số kỹ thuật.


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

Chưa xác minh:

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

Chưa xác minh:

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

Có thể có thể tiết kiệm ~ 50 ký tự viết lại này trong scala
rwyland

1

GAWK: 136 , 132 , 126 , 125 ký tự

Dựa trên phiên bản 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}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.