高尔夫代码-π天


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个测试用例的任何解决方案

π的近似值是通过将*字符数除以2 得到的
近似值至少应为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

您可能希望弄清楚“输入”是在命令行上还是在stdin上。
格雷格·休吉尔

1
@Greg Hewgill,请随意选择最适合您使用的语言:)
John La Rooy

@Greg Hewgill,某些(即,很少)编程语言实现没有“命令行”的概念。
乔伊·亚当斯

1
我注意到很少有答案遵循仅放出y为奇数的行的规则。给定r的奇数(测试用例中未显示),大多数将输出y为偶数的行!
MtnViewMark'3

6
规则滥用挑战:通过支持4个必需的测试用例,使代码比别人的代码短。
Brian

Answers:


15

直流电:88和93 93 94 96 102 105 129 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 2010年

@gnibbler-“使用bn(3)大数例程对dc命令的完全重写首次出现在OpenBSD 3.5中。” 我不知道 包括一些不错的新运算符,但它们被标记为“非便携式扩展名”。
卡洛斯·古铁雷斯(CarlosGutiérrez)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

恭喜,j * j ++是未定义的行为
sellibitze 2010年

1
那不是一个字符吗?
Ponkadoodle

1
如何main()接受四个int论点?
David R Tribble

2
@Load:5.1.2.2.1 / 1:在程序启动时调用的函数名为main。它应该被定义… 或以其他实现定义的方式定义。这是因为实现可以接受这种形式。
肯尼

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
我的<eyes> </ eyes>!护目镜,他们什么都不做!
吉米

1
ang!恐怕您可能会因为独特性而击败我的HyperCard解决方案:D
Joey Adams 2010年

7
简直

嘿,是的,在过去,我们只有IE和XML以及XSLT是解决所有问题的解决方案。美好旧时光!:)
DankoDurbić10年

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

5
@Chris Marisic:您是否检查了标记的其他问题/主题code-golf?:)我看过更多不可读的例子。
BalusC 2010年

3
@Peter:与大多数人不同,我已经看过并写过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 2010年

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栏中有字母!
乔尔2010年

从我所见,大多数人仍然对Fortan77感兴趣。
乔尔2010年

8
我喜欢圆圈版本看起来像死星。
mskfisher 2010年

22

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

12
我喜欢StackOverflow!
zengr

2
有趣的是,某些高级语言的字符数比生成的二进制数少。
Colin Valliant

3
@Alcari:如果将所有代码包含在高级语言使用的库中,则它们的字符数会大大增加。在汇编器中,这样做printf("%f",a/b)并非无关紧要,没有一条指令可以做到这一点,而我上面的实现假设0 <= a / b <10,并且该运算是除法运算,并且a和b是整数。
Skizz 2010年

19

的Python: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和。我又想出了另一种技巧,因为它几乎从来都不是正确的事:-)
Nicholas Riley 2010年

我过去使用过C,甚至从未看过Python。这104个字符比上面的C ++更易读。惊人。也许我应该学习Python ...
Dean Rather

@Dean:Python的主要目标之一是易于阅读和编写。
科林·瓦利安

您是否也打算将exec与104个char答案一起使用?:)
约翰·拉鲁伊

我需要进行自己的压缩-zlib,marshalling等都比实际代码大。
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

@Thor:我希望不会,但这肯定是我写过的最丑陋的东西:)
DankoDurbić10年

3
感谢您提供的漂亮版本=)
Thor Hovden 2010年

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:这就是为什么我发布它的原因:)另外,如果我以后决定编写HyperTalk解释器,那么代码高尔夫是建立测试套件的好方法。
乔伊·亚当斯

哈哈!我想看到的是,XD
Kawa 2010年

如果您决定编写该解释器,或者想加入一个现有的解释器,请告诉我,我可以在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);}}

未缩小:

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)吗?
kennytm 2010年

@Kenny:你是对的。:)这样可以节省三个字符,然后我设法摆脱了另外五个字符。
Guffa

发现第一件事,完全错过了那件事-r+1
Dykam'3

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 <-readfmap`getLine; let {p = putStr; d = 2 / fromIntegral r ^ 2; lyn = let cmx = if x> r then p“ \ n” >>返回m else x * x + y * y <r * r然后p“ *” >> c(m + d)(x + 1)否则p“” >> cm(x + 1)in如果y> r,则打印n else cn (-r)>> = l(y + 2)}; l(1-r`mod`2-r)0}

未缩小:

main =做r <-阅读`fmap` getLine
          令p = putStr
              d = 2 /来自积分r ^ 2
              lyn =让cmx =如果x> r
                                  然后p“ \ n” >>返回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”
Steve 2010年

通过一些Haskell技巧减少了3个字符。我喜欢Haskell在多行代码(换行符与分号)之间通常没有任何花费,因此我们的代码高尔夫球通常可读性高!
MtnViewMark 2010年

严格来说,仅在输入为偶数的情况下145字符版本才有效。但无论哪种方式都很好。
史蒂夫(Steve)2010年

缩短了I / O线。我认为,通过将函数defs推入main = do {... let {...} ...}块中,仍然应该可以节省更多的字符。
即将到来的风暴,2010年

@comingstorm:太酷了!我不知道readLn。这将帮助许多Haskell代码高尔夫球。@Steve:是的,我仍在尝试找出最有效的解决方法。
MtnViewMark 2010年

10

Ruby,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可能是不可读的... :)
MladenJablanović10年

你也可以使用p s,而不是puts s:)
约翰·拉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
不缩放。难以维持!
spoulson

我尝试尽可能多地压缩测试用例作弊,但最终结果仍然比我的实际解决方案稍大:P
lunixbochs 2010年

5
+1,始终先做最明显的事情……如果有人不喜欢它,请大声抱怨规格不够清晰
Mizipzor 2010年

布赖恩(Brian)在特殊情况下对测试用例进行了半认真的尝试,如果您喜欢这个答案,也应该投票赞成他;)stackoverflow.com/questions/2457995
John La Rooy 2010年

7

J:47岁 46,45

与其他解决方案相同的基本思想,即r ^ 2 <= x ^ 2 + y ^ 2,但是J的面向数组的表示法简化了表达式:

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

你会这样称呼它c 2c 8c 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
)

马歇尔•洛赫巴姆在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,2010年

你不需要之间的空间print' '
约翰·拉ROOY

好的,这很可怕,它现在比Perl版本短。(我通常会完全忘记“输入”,因为它通常很不安全...)
Nicholas Riley 2010年

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

(是的,使用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的要求?
彼得·亚历山大

3
您可能希望将其更改为#include <iostream.h>基本上#include <iostream> -- using namespace std;与旧的C ++编译器兼容的版本。
厄尔兹(Earlz)2010年

1
@Carlos,我没有写那个特定的位,但是它是一个二进制AND运算符。它检查是否设置了最后一位,这等效于doing i%2,但是“更快”。这并不是真的更快,因为编译器还是会这么做。
彼得·亚历山大

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的:126132138

(基于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在回显$ s * 2 / $ r / $ r中做什么?
davidosomething,2010年

OHH部门...这个距离让我失望,以为那是我从未见过的操作员速记
davidosometh 2010年

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


尼斯之一,但它不会打印出圆周率近似值
约翰·拉ROOY

在1.9.1中不起作用,并在圆周围打印双引号。
MladenJablanović10年

高尔夫程序不能使用完全不同的语言水平是正常的。每个语言版本有多少Perl或Python cg可以工作?有趣的是,事实证明原因是因为Integer|Float不再强制1.9上的浮点数。
DigitalRoss 2010年

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版本还漂亮。
2013年

@ahala确实。APL在概念和美学上都是美丽的。我开始学习J,但是由于随机ASCII疯狂而被关闭。一个好人为Node.js(npm install apl)编写了一个开源APL解释器,这很好。只需稍作更改即可计算以上代码(不包含monadic ,第二个字符)。您可以在所有供应商站点(例如Dyalog)上找到良好的APL文档。
Tobia

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
卡洛斯·古铁雷斯

唯一的问题是,它现在失败了,但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

爪哇: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

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}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.