[language-agnostic] 코드 골프-파이 데이

도전

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 개 이상의 유효 숫자로 정확해야합니다.
선행 또는 후행 0은 그래서 예를 들어 어떤의 허용됩니다 3, 3.000000, 003의 입력에 대해 수락 2하고 4.

코드 수에는 입력 / 출력 (즉, 전체 프로그램)이 포함됩니다.

테스트 케이스

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



답변

dc에서 : 88 및 93 93 94 96102105129138141 자

혹시라도 저는 OpenBSD와이 시점에서 이식 할 수없는 확장을 사용하고 있습니다.

93 자 이는 FORTRAN 솔루션과 동일한 공식을 기반으로합니다 (테스트 케이스와 약간 다른 결과). 모든 Y에 대해 X ^ 2 = R ^ 2-Y ^ 2 계산

[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


답변

C : 131 자

(Joey의 C ++ 솔루션 기반)

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


답변

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.xsltIE에서 다음 XML 파일을 엽니 다.

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


답변

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;


답변

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


답변

x86 머신 코드 : 127 바이트

인텔 어셈블러 : 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


답변

파이썬 : 101 개 104 107 110 문자

Nicholas Riley의 다른 Python 버전을 기반으로합니다.

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에 대한 크레딧.


아, 홀수 번호는 중간이 0으로 색인되어 모든 것을 설명합니다.

보너스 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