Code Golf - πวัน


95

ความท้าทาย

แนวทางสำหรับโค้ดกอล์ฟบน SO

รหัสที่สั้นที่สุดตามจำนวนอักขระเพื่อแสดงการแสดงวงกลมรัศมีRโดยใช้*อักขระตามด้วยการประมาณπ

อินพุตเป็นตัวเลขเดียว, R.

เนื่องจากคอมพิวเตอร์ส่วนใหญ่ดูเหมือนจะมีอัตราส่วนเกือบ 2: 1 คุณจึงควรแสดงเฉพาะบรรทัดที่yเป็นเลขคี่ ซึ่งหมายความว่าเมื่อไหร่ที่Rคุณควรพิมพ์R-1บรรทัดแปลก มีพยานหลักฐานใหม่สำหรับR=13การชี้แจง

เช่น.

Input
    5
Output      Correct                          Incorrect

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

แก้ไข:เนื่องจากความสับสนอย่างกว้างขวางที่เกิดจากค่าคี่ของRโซลูชันใด ๆ ที่ผ่านกรณีทดสอบ 4 กรณีที่ระบุด้านล่างจะได้รับการยอมรับ

ประมาณของπจะได้รับโดยการหารสองเท่าของจำนวนของตัวละครโดย* ค่าประมาณควรถูกต้องอย่างน้อย 6 หลัก ด้านหน้าหรือด้านหลังศูนย์จะได้รับอนุญาตดังนั้นสำหรับตัวอย่างใด ๆ, , เป็นที่ยอมรับสำหรับปัจจัยการผลิตของและ

33.00000000324

จำนวนรหัสประกอบด้วยอินพุต / เอาต์พุต (เช่นโปรแกรมเต็ม)

กรณีทดสอบ

Input
    2
Output
     *** 
     *** 
    3.0

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

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

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

กรณีทดสอบโบนัส

Input
    13
Output

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

คุณอาจต้องการชี้แจงว่า "อินพุต" อยู่ในบรรทัดคำสั่งหรือใน stdin
Greg Hewgill

1
@Greg Hewgill อย่าลังเลที่จะเลือกภาษาที่คุณใช้สะดวกที่สุด :)
John La Rooy

@Greg Hewgill การใช้งานภาษาโปรแกรมบางอย่าง (ซึ่งมีน้อยมาก) ไม่มีแนวคิดเรื่อง "บรรทัดคำสั่ง"
Joey Adams

1
ฉันสังเกตว่าคำตอบไม่กี่คำตอบเป็นไปตามกฎของการใส่เฉพาะบรรทัดที่ y เป็นเลขคี่ กำหนดค่า r เป็นคี่ (ไม่แสดงในกรณีทดสอบ) ส่วนใหญ่จะแสดงผลบรรทัดที่ y เป็นคู่!
MtnViewMark

6
ความท้าทายในการละเมิดกฎ: สร้างโค้ดที่สั้นกว่าโค้ดของใคร ๆ โดยรองรับเฉพาะ 4 กรณีทดสอบที่จำเป็นเท่านั้น
Brian

คำตอบ:


15

ในกระแสตรง: 88 และ 93 93 94 96102105129 138141 ตัวอักษร

ในกรณีนี้ฉันใช้ OpenBSD และส่วนขยายที่ไม่สามารถพกพาได้ในตอนนี้

93 ตัวอักษร นี่เป็นไปตามสูตรเดียวกับโซลูชัน FORTRAN (ผลลัพธ์ต่างจากกรณีทดสอบเล็กน้อย) คำนวณ X ^ 2 = R ^ 2-Y ^ 2 สำหรับทุก Y

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

88 ตัวอักษร วิธีแก้ซ้ำ ตรงกับกรณีทดสอบ สำหรับทุก X และ Y จะตรวจสอบถ้า 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

dc pi.dcเมื่อต้องการเรียกใช้

นี่คือคำอธิบายประกอบเวอร์ชันเก่า:

# 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
ไม่ได้ทำงานกับ dc ลินุกซ์ แต่ผมสามารถยืนยันได้ว่าการทำงานบน OpenBSD สุดยอด!
John La Rooy

@ คาร์ลอสใช่ตัว(ดำเนินการแน่นอนว่ามีประโยชน์ แย่เกินไปที่ยังไม่ได้ติดตั้งใน dc ที่มาพร้อมกับ linux
John La Rooy

@gnibbler - "การเขียนคำสั่ง dc ใหม่ทั้งหมดโดยใช้รูทีนเบอร์ใหญ่ bn (3) ปรากฏครั้งแรกใน OpenBSD 3.5" ฉันไม่รู้เรื่องนั้น มีตัวดำเนินการใหม่ ๆ ที่ดี แต่มีการระบุว่าเป็น "ส่วนขยายแบบพกพา"
Carlos Gutiérrez

ใช่ (ผู้ปฏิบัติงานคนเดียวอนุญาตให้หลั่ง 6 จังหวะ!
Dan Andreatta

119

C: 131 ตัวอักษร

(อ้างอิงจากโซลูชัน C ++ โดย 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);}

(เปลี่ยนเป็นi|=-nเพื่อi-=nลบการรองรับกรณีจำนวนคี่ซึ่งเป็นเพียงการลดจำนวนถ่านลงเหลือ 130)

เป็นวงกลม:

      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
ฉันชอบวิธีที่คุณเพิ่มแวดวงลงในโค้ดเพื่อเปลี่ยนเป็นวงกลม +000 จะดีกว่าไหม
Potatoswatter

ขอแสดงความยินดี j * j ++ เป็นพฤติกรรมที่ไม่ได้กำหนด
sellibitze

1
นั่นจะไม่ใช่แค่ตัวละครเดียว ... ?
Ponkadoodle

1
วิธีการที่ไม่main()ใช้เวลาสี่intข้อโต้แย้ง?
David R Tribble

2
@Load: 5.1.2.2.1 / 1: mainฟังก์ชั่นที่เรียกว่าเมื่อเริ่มต้นโปรแกรมการตั้งชื่อ ก็จะต้องถูกกำหนดไว้ ... หรือในลักษณะการดำเนินงานบางส่วนที่กำหนดอื่นนั่นเป็นเพราะการใช้งานสามารถยอมรับแบบฟอร์มนี้ได้
kennytm

46

XSLT 1.0

เพื่อความสนุกสนานนี่คือเวอร์ชัน XSLT ไม่ใช่วัสดุโค้ดกอล์ฟจริงๆ แต่มันช่วยแก้ปัญหาได้ด้วยวิธีที่แปลก ๆ - 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>

หากคุณต้องการทดสอบให้บันทึกเป็นpi.xsltและเปิดไฟล์ XML ต่อไปนี้ใน IE:

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

42
<eyes> </eyes> ของฉัน! แว่นมัน <do> ไม่มีอะไรเลย </do>!
Jimmy

1
แดง! ฉันเกรงว่าคุณอาจเอาชนะโซลูชัน HyperCard ของฉันเพื่อความเป็นเอกลักษณ์: D
Joey Adams

7
ไม่น่าเชื่อว่าคุณพูดว่า "เปิด ... IE"
harpo

ใช่แล้วย้อนกลับไปในวันนี้เรามีเพียง IE และ XML กับ XSLT เท่านั้นที่เป็นทางออกสำหรับปัญหาทั้งหมดของเรา ช่วงเวลาเก่า ๆ ที่ดี! :)
Danko Durbić

XSL เวอร์ชัน 1.0 ว้าวฉันจำได้ว่าตั้งตารอเวอร์ชัน 2 แต่เมื่อถึงเวลาที่ออกมาฉันก็ย้ายไปแล้ว
gradbot

35

Perl, 95 96 99 106 109 110 119 อักขระ:

$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

(สามารถลบขึ้นบรรทัดใหม่และอยู่ที่นั่นเพื่อหลีกเลี่ยงแถบเลื่อนเท่านั้น)

เย้! รุ่นวงกลม!

    $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

สำหรับรุ่นที่ไม่ได้ฝึกหัดรุ่นยาว:

#!/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
นั่นเป็นรหัสที่อ่านไม่ได้มากที่สุดเท่าที่ฉันเคยเห็นมาตลอดชีวิต
Chris Marisic

13
ฉันเดาว่าคุณไม่เคยเห็น APL มาก่อน
Peter Wone

5
@Chris Marisic: คุณตรวจสอบคำถาม / หัวข้ออื่น ๆ ที่แท็กcode-golfหรือไม่? :) ฉันเคยเห็นตัวอย่างที่อ่านไม่ได้มากขึ้น
BalusC

3
@ ปีเตอร์: ไม่เหมือนส่วนใหญ่ฉันเคยเห็นและเขียน APL ใช้เวลาสองสามสัปดาห์ในการทำความคุ้นเคยกับอักขระพิเศษ แต่หลังจากนั้นก็สามารถอ่านได้ แม้ผ่านไปสองสามทศวรรษกว่าจะชิน แต่ Perl ก็ยังแย่กว่ามาก
Jerry Coffin

1
111 ตัวอักษร$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 ตัวอักษร

$ 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

เดี๋ยวก่อนฉันว่าการจัดรูปแบบมีความสำคัญใน Fortran หรือไม่? คุณมีตัวอักษรในคอลัมน์ 1!
Joel

คนส่วนใหญ่ยังคงติดอยู่กับ Fortan77 จากที่ฉันเคยเห็น
Joel

8
ฉันชอบเวอร์ชันวงกลมที่ดูเหมือนเด ธ สตาร์
mskfisher

22

x86 รหัสเครื่อง: 127 ไบต์

Intel Assembler: 490 ตัวอักษร

    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

รุ่นนี้รองรับกรณีทดสอบโบนัสด้วยและมีขนาด 133 ไบต์:

    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!
zengr

2
เป็นเรื่องน่าสนใจที่ภาษาระดับสูงบางภาษามีจำนวนอักขระสั้นกว่าไบนารีที่สร้างขึ้น
Colin Valliant

3
@Alcari: หากคุณรวมรหัสทั้งหมดในไลบรารีที่ภาษาระดับสูงกว่าใช้จำนวนอักขระจะสูงขึ้นอย่างมาก ในแอสเซมเบลอร์การทำprintf("%f",a/b)ไม่ใช่เรื่องเล็กน้อยไม่มีคำสั่งเดียวในการทำเช่นนั้นและการใช้งานของฉันข้างต้นถือว่า 0 <= a / b <10 และการดำเนินการเป็นส่วนหนึ่งและ a และ b เป็นจำนวนเต็ม
Skizz

19

งูหลาม: 101 104 107 110ตัวอักษร

อ้างอิงจาก Python เวอร์ชันอื่นโดย 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

ให้เครดิตกับ AlcariTheMad สำหรับคณิตศาสตร์บางส่วน


อ่าเลขคี่ถูกจัดทำดัชนีโดยมีศูนย์ตรงกลางอธิบายทุกอย่าง

โบนัส Python: 115 ตัวอักษร (แฮ็กเข้าด้วยกันอย่างรวดเร็ว)

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

ว้าวใช่ '+' เต้น -1 และทุกวัน อีกเทคนิคหนึ่งที่ฉันไม่คิดเพราะแทบจะไม่เคยเป็นสิ่งที่ถูกต้องที่จะทำ :-)
Nicholas Riley

ฉันเคยใช้ C มาก่อนและไม่เคยดู Python เลย 104 ตัวอักษรนี้สามารถอ่านได้มากกว่า C ++ ด้านบน น่าอัศจรรย์. บางทีฉันควรเรียน Python ...
Dean Rather

@Dean: หนึ่งในเป้าหมายหลักของ Python คืออ่านและเขียนได้ง่าย
Colin Valliant

คุณเคยใช้ exec กับ 104 char answer ด้วยหรือเปล่า? :)
John La Rooy

ฉันจะต้องรีดการบีบอัดของตัวเอง - zlib, marshalling และอื่น ๆ ทั้งหมดออกมาใหญ่กว่ารหัสจริง
lunixbochs

12

Powershell, 119 113 109 อักขระ

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

@ ธ อร์: ฉันหวังว่าจะไม่ แต่นี่จะต้องเป็นสิ่งที่น่าเกลียดที่สุดที่ฉันเคยเขียนมา :)
Danko Durbić

3
ขอบคุณสำหรับเวอร์ชั่นที่สวยกว่า =)
Thor Hovden

10

HyperTalk: 237 อักขระ

ไม่จำเป็นต้องมีการเยื้องหรือนับ เป็นการเพิ่มเพื่อความชัดเจน โปรดทราบว่า HyperCard 2.2 ยอมรับตัวดำเนินการเชิงสัมพันธ์ที่ไม่ใช่ ASCII ที่ฉันใช้

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 จึงมีการจัดเตรียมฟังก์ชันให้แทน


1
ไฮเปอร์การ์ดนายอดัมส์? อย่างจริงจัง? นี่เป็นเรื่องที่ไม่คาดคิดอย่างมาก
Kawa

1
@Kawa: นั่นเป็นเหตุผลว่าทำไมฉันจึงโพสต์ :) นอกจากนี้ Code Golf ยังเป็นวิธีที่ดีในการสร้างชุดทดสอบในกรณีที่ฉันตัดสินใจเขียนล่าม HyperTalk ในอนาคต
Joey Adams

ห๊ะ! ฉันอยากเห็น XD
Kawa

หากคุณเคยตัดสินใจที่จะเขียนล่ามคนนั้นหรือต้องการเข้าร่วมทำงานกับล่ามที่มีอยู่แจ้งให้เราทราบและฉันสามารถเพิ่มการกล่าวถึงใน hypercard.org และฉันอยากรู้ว่ามันเป็นอย่างไร :-)
uliwitness

10

C #: 209202201อักขระ:

using C=System.Console;class P{static void Main(string[]a){int r=int.Parse(a[0]),s=0,i,x,y;for(y=1-r;y<r;y+=2){for(x=1-r;x<r;s+=i)C.Write(" *"[i=x*x+++y*y<=r*r?1:0]);C.WriteLine();}C.Write(s*2d/r/r);}}

Unminified:

using C = System.Console;
class P {
  static void Main(string[] arg) {
    int r = int.Parse(arg[0]), sum = 0, inside, x, y;
    for (y = 1 - r; y < r; y += 2) {
      for (x = 1 - r; x < r; sum += inside)
        C.Write(" *"[inside = x * x++ + y * y <= r * r ? 1 : 0]);
      C.WriteLine();
    }
    C.Write(sum * 2d / r / r);
  }
}

ฉันไม่รู้จัก C # มากนัก แต่คุณไม่ควรใช้string[]aและ1-r(แทน-1+r) ได้หรือไม่?
kennytm

@ เคนนี่: คุณพูดถูก :) นั่นช่วยประหยัดอักขระสามตัวจากนั้นฉันก็กำจัดอีกห้าตัว
Guffa

เห็นว่าสิ่งแรกที่พลาดทั้งหมดใน-r+1thingy
Dykam

4
นอกจากนี้ยังพบx*xx+++y*yอีกด้วย แต่มันเป็นเรื่องบ้าที่จะผ่าในตอนแรก
Dykam

ฉันใช้เสรีภาพในการกำจัดไบต์อื่น ;-)
โจอี้

10

Haskell 139 145 147 150 230ตัวอักษร:

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

การจัดการตัวเลขคี่: 148 ตัวอักษร:

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 ตัวอักษร: (อ้างอิงจากเวอร์ชัน 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 ตัวอักษร:

main = do {r <-read`fmap`getLine; ให้ {p = putStr; d = 2 / fromIntegral r ^ 2; lyn = let cmx = if x> r แล้ว p "\ n" >> ส่งคืน m else ถ้า x * x + y * y <r * r แล้ว p "*" >> c (m + d) (x + 1) else p "" >> cm (x + 1) ในถ้า y> r แล้วพิมพ์ n else cn (-r) >> = l (y + 2)}; l (1-r`mod`2-r) 0}

Unminified:

main = do r <- อ่าน `fmap` getLine
          ให้ p = putStr
              d = 2 / fromIntegral r ^ 2
              lyn = ให้ cmx = ถ้า x> r
                                  จากนั้น p "\ n" >> กลับ m
                                  อื่นถ้า x * x + y * y <r * r
                                       แล้ว p "*" >> c (m + d) (x + 1)
                                       อื่น p "" >> ซม. (x + 1)
                      ในถ้า y> r
                         จากนั้นพิมพ์ n
                         อื่น cn (-r) >> = l (y + 2)
          ล. (1-r`mod`2-r) 0

ฉันหวังว่ามันจะเอาชนะเวอร์ชันที่จำเป็นบางอย่างได้ แต่ดูเหมือนว่าฉันจะไม่สามารถบีบอัดได้อีกในตอนนี้


ตัดออกอีก 2 ตัวโดยกำจัด "d" แล้วเพิ่ม 1 แทนจากนั้นพิมพ์ "2 * n / fromIntegral r ^ 2"
Steve

โกนตัวละคร 3 ตัวออกโดยใช้เทคนิค Haskell เล็กน้อย ฉันชอบที่ Haskell มักจะไม่มีค่าใช้จ่ายสำหรับหลายบรรทัด (newline เทียบกับ semicolon) และด้วยเหตุนี้ code-golf ของเราจึงสามารถอ่านได้โดยทั่วไป!
MtnViewMark

พูดอย่างเคร่งครัดรุ่น 145-char จะใช้งานได้ก็ต่อเมื่ออินพุตเป็นเลขคู่เท่านั้น แต่ก็ดีมากทั้งสองวิธี
Steve

ทำให้สาย I / O สั้นลง ยังคงเป็นไปได้ที่จะบันทึกอักขระอีกสองสามตัวโดยการกดฟังก์ชัน def ลงในบล็อก main = do {... let {... } ... }
comingstorm

@comingstorm: เจ๋ง! ฉันไม่รู้เกี่ยวกับ readLn สิ่งนี้จะช่วยให้ Haskell code-golf จำนวนมาก @ สตีฟ: ใช่ฉันยังคงพยายามหาวิธีที่มีประสิทธิภาพที่สุดในการแก้ไขปัญหานั้น
MtnViewMark

10

ทับทิม 96 ตัว

(อิงตามโซลูชัน C # ของ 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 ตัวอักษร (โบนัส):

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

ขอบคุณ! ฉันอายที่เห็นว่า Ruby ที่อ่านไม่ออกจะเป็นยังไง ... :)
Mladen Jablanović

คุณยังสามารถใช้p sแทนputs s:)
John La Rooy

1
มีแนวคิดใหม่ ๆ ที่ดี - ฉันชอบที่คุณใช้ g กับ 2 ขนาดขั้นตอนที่แตกต่างกันและ <=> เพื่อหลีกเลี่ยงไม่ให้โค้ดแปลงจากตรรกะ
John La Rooy


8

พวกคุณกำลังคิดหนักเกินไป

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

8
จำนวนตัวละครคล่องมือคุณไม่คิดเหรอ? :)
John La Rooy

7
ไม่ปรับขนาด ไม่สามารถเข้าถึงได้!
spoulson

ฉันพยายามบีบอัดการโกงกรณีทดสอบให้มากที่สุดและมันก็ยังใหญ่กว่าโซลูชันจริงของฉันเล็กน้อย: P
lunixbochs

5
+1 ทำสิ่งที่ชัดเจนที่สุดก่อนเสมอ ... ถ้ามีใครไม่ชอบก็บ่นเสียงดังว่าสเป็คไม่ชัดเจนพอ
Mizipzor

ไบรอันมีความพยายามกึ่งจริงจังในกรณีทดสอบพิเศษคุณควรโหวตให้เขาด้วยถ้าคุณชอบคำตอบนี้) stackoverflow.com/questions/2457995
John La Rooy

7

ญ: 47 , 46 , 45

แนวคิดพื้นฐานเหมือนกับวิธีแก้ปัญหาอื่น ๆ เช่นr ^ 2 <= x ^ 2 + y ^ 2แต่สัญกรณ์เชิงอาร์เรย์ของ J ทำให้นิพจน์ง่ายขึ้น:

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

คุณจะเรียกว่าชอบc 2หรือc 8หรือc 10อื่น ๆ

โบนัส: 49

ในการจัดการอินพุตคี่เช่น13เราต้องกรองพิกัด x ที่มีค่าคี่แทนที่จะใช้เพียงแค่เอาแถวอื่น ๆ ของเอาต์พุต (เพราะตอนนี้ดัชนีสามารถเริ่มต้นด้วยเลขคู่หรือเลขคี่ก็ได้) ลักษณะทั่วไปนี้ทำให้เราเสียค่าใช้จ่าย 4 อักขระ:

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

เวอร์ชันลดขั้นตอน:

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
)

การปรับปรุงและการสรุปทั่วไปเนื่องจากMarshall Lochbam บนฟอรัม Jในเจฟอรั่ม


5

Python: 118 อักขระ

พอร์ตที่ค่อนข้างตรงไปตรงมาของเวอร์ชัน 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

สำหรับ python2 คุณสามารถใช้ได้r=input()
John La Rooy

คุณไม่ต้องการช่องว่างระหว่างprintและ' '
John La Rooy

ตกลงมันน่ากลัวมันสั้นกว่าเวอร์ชั่น Perl ตอนนี้ (ฉันใส่ "อินพุต" โดยสิ้นเชิงเพราะมันไม่ปลอดภัยโดยปกติ ... )
Nicholas Riley

4

C ++: 169 อักขระ

#include <iostream>
int main(){int i,j,c=0,n;std::cin>>n;for(i=-n;i<=n;i+=2,std::cout<<'\n')for(j=-n;j<=n;j++)std::cout<<(i*i+j*j<=n*n?c++,'*':' ');std::cout<<2.*c/n/n;}

Unminified:

#include <iostream>
int main()
{
    int i,j,c=0,n;
    std::cin>>n;
    for(i=-n;i<=n;i+=2,std::cout<<'\n')
        for(j=-n;j<=n;j++)
            std::cout<<(i*i+j*j<=n*n?c++,'*':' ');
    std::cout<<2.*c/n/n;
}

(ใช่โดยใช้ std :: แทนที่จะusing namespace stdใช้อักขระน้อยกว่า)

ผลลัพธ์ที่นี่ไม่ตรงกับกรณีทดสอบในโพสต์ต้นฉบับดังนั้นนี่คือสิ่งที่ทำ (เขียนเพื่อให้อ่านง่าย) พิจารณาว่าเป็นการใช้งานอ้างอิง (หาก Poita_ ไม่ทราบ):

#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 อักขระ (พร้อมเอาต์พุตฉันเชื่อว่าถูกต้อง)

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

โค้ดจะวนจาก -n ถึง n ดังนั้นสำหรับอินพุตของตัวอย่างเช่น 4 จะแสดงเส้นผ่านศูนย์กลางเป็น 9 ไม่ใช่ 7 ดังที่แสดงในกรณีทดสอบ
Guffa

ความต้องการที่วงกลมของคุณตรงกับของ OP ที่ว่า ?
Peter Alexander

3
คุณอาจต้องการเปลี่ยน#include <iostream.h>ซึ่งโดยพื้นฐานแล้ว#include <iostream> -- using namespace std;เพื่อให้เข้ากันได้กับคอมไพเลอร์ C ++ เก่า
Earlz

1
@ คาร์ลอสฉันไม่ได้เขียนบิตนั้น แต่เป็นไบนารี AND ตัวดำเนินการ ตรวจสอบว่าบิตสุดท้ายถูกตั้งค่าซึ่งเทียบเท่ากับการทำi%2แต่ "เร็วกว่า" มันไม่ได้เร็วขึ้นจริง ๆ เพราะคอมไพเลอร์จะทำอยู่แล้ว
Peter Alexander

1
@Poita_: ที่จริงแล้ว i% 2 และ i & 1 ทำงานต่างกันกับจำนวนลบ (-1) & 1 คือ 1 ซึ่งตรงนี้เราต้องการ (-1)% 2 คือ -1 ในระบบของฉันและเป็นไปตาม C99 ดังนั้นแม้ว่า (i & 1) และ if (i% 2) จะทำสิ่งเดียวกัน แต่ก็ต้องระวัง if (i% 2 == 1) ซึ่งจะไม่ทำงานเมื่อฉันเป็นลบ
Joey Adams

3

PHP: 126 132 138

(ขึ้นอยู่กับโซลูชัน 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;

เต็มปัจจุบัน:

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;

สามารถทำได้โดยไม่ต้อง@มาก่อน$sแต่มีเฉพาะ error_reporting ที่ตั้งค่าเป็น 0 เท่านั้น (การแจ้งเตือนผลลัพธ์จะทำให้วงกลมยุ่งเหยิง)


/ $ r ทำอะไรใน echo $ s * 2 / $ r / $ r;
davidosomething

แผนก OHH ... การเว้นวรรคทำให้ฉันผิดหวังคิดว่ามันเป็นตัวดำเนินการชวเลขที่ฉันไม่เคยเห็น
davidosomething

3

รูบี้ 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

ทำงานด้วย $ ruby -p piday


เป็นสิ่งที่ดี แต่มันไม่ได้พิมพ์ค่าประมาณของ pi
John La Rooy

ใช้ไม่ได้ใน 1.9.1 และพิมพ์เครื่องหมายคำพูดคู่รอบวงกลม
Mladen Jablanović

เป็นเรื่องปกติที่รายการกอล์ฟจะไม่ใช้ภาษาที่แตกต่างกันอย่างรุนแรง Perl หรือ Python cg ทำงานได้กี่ภาษาในทุกเวอร์ชัน เป็นที่น่าสนใจ แต่ปรากฎว่าสาเหตุเป็นเพราะInteger|Floatไม่บังคับลอยที่ 1.9
DigitalRoss

3

APL: 59

ฟังก์ชันนี้ยอมรับตัวเลขและส่งกลับรายการที่คาดหวังสองรายการ ทำงานได้อย่างถูกต้องในกรณีโบนัส

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

ภาษาถิ่นคือ Dyalog APL ซึ่งมีต้นกำเนิดดัชนีเริ่มต้น เลเวลสกิลเป็นมือใหม่ที่ไม่รู้ตัวดังนั้นหากกูรู APL คนไหนต้องการลดระดับลงถึง 10 ตัวอักษรเชิญเป็นแขกของฉัน!


คุณสามารถทดลองใช้งานออนไลน์ได้ที่Try APLเพียงแค่วางและใส่ตัวเลขตามหลัง:

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

แม้ว่าฉันจะไม่รู้จัก APL แต่ก็ดูสวยกว่ารุ่น J
ahala

@ahala แน่นอน. APL มีความสวยงามทั้งในแง่ความคิดและความสวยงาม ฉันเริ่มเรียนรู้ J แต่ถูกปิดโดยความบ้าคลั่ง ASCII แบบสุ่ม จิตวิญญาณที่ดีเขียนตัวแปล APL แบบโอเพนซอร์สสำหรับ Node.js (npm install apl) ซึ่งค่อนข้างดี มันคำนวณโค้ดด้านบนด้วยการเปลี่ยนแปลงเล็กน้อย (ไม่มี monadic , อักขระที่ 2) คุณสามารถค้นหาเอกสาร APL ที่ดีได้จากไซต์ผู้ขายทั้งหมดเช่น Dyalog
Tobia

2

และรายการทุบตี: 181 186 190ตัวอักษร

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

เรียกใช้ด้วยเช่น bash py.sh 13


2

Python: 148 อักขระ

ล้มเหลว (กล่าวคือไม่สั้นพอ) พยายามละเมิดกฎและฮาร์ดโค้ดกรณีทดสอบดังที่ฉันได้กล่าวไว้ในการตอบกลับโพสต์ต้นฉบับ การใช้ภาษาที่ละเอียดกว่าในทางที่ผิดอาจทำได้ง่ายกว่า:

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 ตัวอักษร

อิงตามเวอร์ชัน 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

(ไม่สามารถเว้นบรรทัดใหม่หลังบรรทัดสุดท้ายได้ที่นี่)


1
127 ตัวอักษร: r = read (); สำหรับ (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

ปัญหาเดียวที่นี่คือตอนนี้ล้มเหลวสำหรับ 0 แต่ตามกฎปัจจุบันก็โอเค
przemoc

2

JavaScript (SpiderMonkey) - 118 ตัวอักษร

เวอร์ชันนี้ยอมรับอินพุตจาก stdin และผ่านกรณีทดสอบโบนัส

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)

การใช้งาน: cat 10 | js thisfile.js - jsbin previewเพิ่มนามแฝงสำหรับ print / readline เพื่อให้คุณสามารถดูในเบราว์เซอร์

javascript: 213 163


อัปเดตแล้ว

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

ไม่มีใครบอกว่าต้องแสดงผลอย่างถูกต้องในเบราว์เซอร์ - เพียงแค่ผลลัพธ์ ด้วยเหตุนี้ฉันจึงได้ลบแท็กก่อนและปรับให้เหมาะสมเพิ่มเติม ในการดูผลลัพธ์คุณต้องดูแหล่งที่สร้างขึ้นหรือตั้งค่าสไตล์ชีตของคุณตามนั้น Pi มีความแม่นยำน้อยกว่าด้วยวิธีนี้ แต่ตอนนี้เป็นข้อมูลจำเพาะ


r=10;m=Math;a=Array;t=0;s='';for(i=-r;i<r;i++){w=m.floor((m.sqrt(m.pow(r,2)-m.pow(i,2)))*2);t+=w;if(i%2){z=a(m.round(r-w/2)).join(' ')+a(w).join('*');s+=z+'\n';}}document.write('<pre>'+(s+(t/m.pow(r,2)))+'</pre>')

Unminified:

r=10;
m=Math;
a=Array;
t=0;
s='';
for(i=-r;i<r;i++){
    w=m.floor((m.sqrt(m.pow(r,2)-m.pow(i,2)))*2);
    t+=w;
    if(i%2){
    z=a(m.round(r-w/2)).join(' ')+a(w).join('*');
    s+=z+'\n';
    }
}
document.write('<pre>'+(s+(t/m.pow(r,2)))+'</pre>');

1

จาวา: 234

class C{public static void main(String[] a){int x,y,s=0,r=Integer.parseInt(a[0]);for(y=1-r;y<r;y+=2){for(x=1-r;x<r;++x){boolean b=x*x+y*y<=r*r;s+=b?1:0;System.out.print(b?'*':' ');}System.out.println();}System.out.println(s*2d/r/r);}}

Unminified:

class C{
    public static void main(String[] a){
        int x,y,s=0,r=Integer.parseInt(a[0]); 
        for(y=1-r;y<r;y+=2){
            for(x=1-r;x<r;++x) {
                boolean b=x*x+y*y<=r*r;
                s+=b?1:0;
                System.out.print(b?'*':' ');
            }
            System.out.println();
        }
        System.out.println(s*2d/r/r);
    }
}

อาจบันทึก ~ 50 ตัวอักษรเขียนใหม่ใน scala
rwyland

1

GAWK: 136 , 132 , 126 , 125 ตัวอักษร

อิงตามเวอร์ชัน 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}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.