コードゴルフ-π日


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.000000003の入力のために受理される24

コードカウントには入力/出力(つまり、完全なプログラム)が含まれます。

テストケース

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

「入力」がコマンドラインにあるのか、標準入力にあるのかを明確にしたい場合があります。
グレッグヒューギル

1
@Greg Hewgill、使用している言語に最も適したものを自由に選択してください:)
John La Rooy

@Greg Hewgill、一部の(つまり、ごく少数の)プログラミング言語の実装には、「コマンドライン」の概念がありません。
ジョーイアダムス

1
yが奇数である行のみを出力するという規則に従っていない回答がいくつかあります。rの奇数の値(テストケースには示されていません)を指定すると、ほとんどの場合、yが偶数の行が出力されます。
MtnViewMark 2010年

6
ルール乱用の課題:必要な4つのテストケースのみをサポートすることにより、他の誰よりも短いコードを作成します。
ブライアン

回答:


15

DC:88および93 93 94 96 102105129 138 141文字

念のため、この時点では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

1
Linux dcでは動作しませんが、openbsdで動作することを確認できます。驚くばかり!
John La Rooy、

@Carlos、はい、(オペレーターは確かに便利です。残念ながら、Linuxに付属するDCには実装されていません
John La Rooy

@gnibbler-"OpenBSD 3.5で初めて登場したbn(3)の大きな数のルーチンを使用したdcコマンドの完全な書き換え。" 知らなかった。いくつかの素晴らしい新しい演算子が含まれていますが、それらは「移植不可能な拡張」としてマークされています。
カルロスグティエレス

ええ、(オペレーターだけで6ストロークを流すことができました!
Dan Andreatta 2010年

119

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|=-ni-=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 2010年

おめでとう
ござい

1
たった一人のキャラクターじゃないですか…?
Ponkadoodle、2010年

1
main()4つの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、IEで次のXMLファイルを開きます。

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

42
私の<目> </目>!ゴーグル、彼らは<do>何もしない</ do>!
ジミー

1
ダン!私はHyperCardソリューションの独自性を打ち負かしたのではないかと思います:D
Joey Adams

7
「open ... IE」と言ったなんて信じられません
harpo

ええ、はい、当時、IEとXSLTを備えたXMLしかありませんでしたが、すべての問題の解決策でした。古き良き時代!:)
DankoDurbić2010年

XSLバージョン1.0はすごい、バージョン2を楽しみにしていたのを覚えていますが、それが出てくるまでに、私はすでに先に進んでいました。
gradbot 2010年

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
それははるかに私は私の生涯で見た中で最も読めないコードである
クリスMarisic

13
APLを見たことがないと思います。
Peter Wone 2010年

5
@Chris Marisic:タグ付けされた他の質問/トピックを確認しましたcode-golfか?:)私ははるかに読みにくい例を見てきました。
BalusC 2010年

3
@ピーター:ほとんどとは異なり、私はAPLを見たり書いたりしました。特殊文字に慣れるまでに数週間かかりますが、その後はかなり読みやすくなります。慣れるまでに数十年経った後でも、Perlはさらに悪い状態です。
ジェリーコフィン

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 2010年

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文字

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へのクレジット。


ああ、奇数番号のものはゼロを中央にして索引付けされており、すべてを説明しています。

ボーナス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を打ち、いつでも もう1つのテクニックは心に留めておく必要があります。それは、ほとんど正しいことではないからです:-)
Nicholas Riley

私は過去にCを使用したことがあり、Pythonを見たことさえありません。この104文字は、上記のC ++よりも読みやすくなっています。すごい。多分私はPythonを学ぶべきでしょう...
Dean Rather

@Dean:Pythonの主な目標の1つは、読み書きしやすいことです。
Colin Valliant 2010年

104文字の回答でexecを使用することについてはどうですか?:)
John La Rooy

私は自分の圧縮をロールする必要があります-zlib、マーシャリングなどはすべて実際のコードよりも大きくなりました。
lunixbochs 2010年

12

パワーシェル、 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

@トール:そうではないと思いますが、これは私がこれまで書いた中で最も醜いものであるに違いありません:)
DankoDurbić

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
ハイパーカード、アダムスさん?マジ?これは予想外です。
カワマール

1
@Kawa:それが私が投稿した理由の1つです:)また、コードゴルフは、将来HyperTalkインタープリターを作成することにした場合に備えて、テストスイートを構築するための良い方法です。
ジョーイアダムス

はぁ!XD
Kawa

あなたがそのインタープリターを書くことに決めた場合、または既存のインタープリターの作業に参加したい場合は、私に知らせてください
。hypercard.org

10

C#:209 202 201文字:

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

ミニ化されていない:

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[]a1-r(の代わりに-1+r)and を使用できませんか?
kennytm

@ケニー:あなたは正しいです。:)これは3つの文字を節約し、さらに5つを取り除くことができました。
Guffa

最初のものを発見し、完全に見落としました-r+1
Dykam

4
また、斑点x*xx+++y*yもありましたが、一見解剖するとはマジなことです。
Dykam

私は別のバイトを排除する自由を取りました;-)
Joey

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; let {p = putStr; d = 2 / fromIntegral r ^ 2; lyn = let cmx = if x> r then p "\ n" >> return m else if x * x + y * y <r * r then p "*" >> c(m + d)(x + 1)else p "" >> cm(x + 1)in if y> r then print n else cn (-r)>> = l(y + 2)}; l(1-r`mod`2-r)0}

ミニ化されていない:

main = do r <-`fmap` getLineを読み取ります
          p = putStrとします
              d = 2 / fromIntegral r ^ 2
              lyn = let let cmx = if x> r
                                  次にp "\ n" >> return m
                                  それ以外の場合、x * x + y * y <r * r
                                       次にp "*" >> c(m + d)(x + 1)
                                       それ以外の場合、p "" >> cm(x + 1)
                      y> rの場合
                         次にnを出力します
                         それ以外の場合はcn(-r)>> = l(y + 2)
          l(1-r`mod`2-r)0

私はそれがいくつかの命令型バージョンを打つことを望んでいましたが、現時点ではそれをさらに圧縮することはできません。


「d」を取り除き、代わりに「1」を追加して「2 * n / fromIntegral r ^ 2」を出力することにより、さらに2つ切り捨て
Steve

いくつかのHaskellトリックを使って3文字を削った。Haskellでは、複数行(改行とセミコロン)に費用がかからないことが多いので、コードゴルフは一般的に読みやすいです。
MtnViewMark 2010年

厳密に言えば、145文字バージョンは、入力が偶数の場合にのみ機能します。しかし、どちらにしてもとてもいいです。
Steve

I / Oラインを短くしました。関数defsをmain = do {... let {...} ...}ブロックにプッシュすることで、さらにいくつかの文字を保存できるはずです。
来年の嵐2016年

@comingstorm:かっこいい!readLnについて知りませんでした。これは多くのHaskellコードゴルフを助けます。@スティーブ:うん、私はまだそれを修正するための最も効率的な方法を理解しようとしています。
MtnViewMark 2010年

10

ルビー、96文字

(GuffaのC#ソリューションに基づく):

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がどのように読み
にくく

:)のp s代わりに使用することもできますputs s
John La Rooy

1
素晴らしい新鮮なアイデア-2つの異なるステップサイズと<=>でgを使用して、コードを論理型から変換するのを避けるのが好きです
John La Rooy


8

君たちは考えすぎだ。

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

8
文字数が少々手に負えなくなりますね。:)
John La Rooy

7
スケーリングしません。メンテナンス不可能!
スポールソン2010年

テストケースのチートを可能な限り圧縮してみましたが、実際のソリューションよりも少し大きくなっていました:P
lunixbochs

5
+1、常に最も明白なことを最初に行う...誰かが気に入らない場合、仕様が十分に明確ではなかったと大声で不平を言う
Mizipzor

ブライアンはテストケースを特別な方法でケーシングすることで、かなり深刻な試みをしました。この回答が気に入ったら、彼も
賛成してください

7

J:4746、45

他のソリューションと同じ基本的な考え方、すなわちr ^ 2 <= x ^ 2 + y ^ 2ですが、Jの配列指向表記は式を簡略化します。

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

あなたはそれを次のように呼ぶでしょう c 2か、c 8またはc 10など

ボーナス:49

たとえば13、奇数の入力を処理するには、出力の1行おきに取得するのではなく、奇数の値の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
)

JフォーラムでのMarshall Lochbamによる改善と一般化。


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

OK、それは恐ろしいことです、それは今のPerlバージョンより短いです。(「入力」は、通常は安全でないため、完全に頭から離れています...)
ニコラスライリー

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

ミニ化されていない:

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

(はい、using namespace std少ない文字を使用する代わりに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の入力の場合、テストケースに示されているように7ではなく、9の直径が表示されます。
Guffa

サークルがOPと正確に一致する必要がありますか?
Peter Alexander

3
#include <iostream.h>基本的には#include <iostream> -- using namespace std;古いC ++コンパイラとの互換性のために変更することもできます。
Earlz

1
@Carlos、私はその特定のビットを書きませんでしたが、それはバイナリAND演算子です。最後のビットが設定されていることを確認します。これはを実行することと同じi%2ですが、「高速」です。コンパイラはとにかくそれを行うので、それは本当に速くはありません。
Peter Alexander

1
@Poita_:実際には、i%2とi&1は負の数では異なる動作をします。(-1)&1は1です。これがここで必要なものです。(-1)%2は私のシステムでは-1であり、これはC99に準拠しています。したがって、if(i&1)とif(i%2)が同じことをする場合でも、if(i%2 == 1)に注意する必要があります。これは、iが負の場合は機能しません。
ジョーイアダムス

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(注意出力は円をいじりされる)だけを0に設定をするerror_reportingで


/ $ rはecho $ s * 2 / $ r / $ rで何をしますか。
davidosomething 2010年

OHHの除算...間隔を空けて、それは私が見たことのない演算子の省略表現だと思った
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

で実行 $ ruby -p piday


いいですね、ただしpi近似は出力されません
John La Rooy

1.9.1では機能せず、円の周りに二重引用符が印刷されます。
MladenJablanović10年

ゴルフプログラムが極端に異なる言語レベルで機能しないのは正常です。言語のすべてのバージョンでいくつのPerlまたはPython cgが機能しますか?興味深いのInteger|Floatは、フロートを1.9に強制しなくなったためです。
DigitalRoss 2010年

3

APL:59

この関数は数値を受け入れ、2つの予期される項目を返します。ボーナスケースで正しく動作します。

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

Dialectは、デフォルトのインデックス起点を持つ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 2013

@ahala確かに。APLは概念的にも審美的にも美しいです。私はJを学び始めましたが、ランダムなASCII狂気に気をとられました。優れた魂がNode.js(npm install apl)向けのオープンソースのAPLインタープリターを作成しましたが、これはかなり優れています。わずかな変更(モナディックなし、2番目の文字)だけで上記のコードを計算します。Dyalogなどのすべてのベンダーサイトで優れたAPLドキュメントを見つけることができます。
トビア2013

2

そして、bashエントリ: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:165127、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(); 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
CarlosGutié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プレビューブラウザで表示できるように、印刷/ 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))

ブラウザーで正しくレンダリングする必要があるとは誰も言っていません。出力だけです。そのため、preタグを削除してさらに最適化しました。出力を表示するには、生成されたソースを表示するか、それに応じてスタイルシートを設定する必要があります。この方法では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>')

ミニ化されていない:

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

ミニ化されていない:

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:136132126、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.