Code Golf - πday

Joh*_*ooy 95 language-agnostic code-golf rosetta-stone

挑战

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
Run Code Online (Sandbox Code Playgroud)

编辑:由于奇数值引起的广泛混淆R,任何通过下面给出的4个测试用例的解决方案都将被接受

π的近似值是将*字符数除以两倍得到的.
近似值应至少为6位有效数字.
前导或尾随零是允许的,因此,例如任何的3,3.000000,003被接受为输入24.

代码计数包括输入/​​输出(即完整程序).

测试用例

Input
    2
Output
     *** 
     *** 
    3.0

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

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

Input
    10
Output
          *********      
       ***************   
      *****************  
     ******************* 
     ******************* 
     ******************* 
     ******************* 
      *****************  
       ***************   
          *********      
    3.16
Run Code Online (Sandbox Code Playgroud)

奖金测试案例

Input
    13
Output

           *************       
        *******************    
       *********************   
      ***********************  
     ************************* 
     ************************* 
     ************************* 
     ************************* 
      ***********************  
       *********************   
        *******************    
           *************                                          
    2.98224852071
Run Code Online (Sandbox Code Playgroud)

ken*_*ytm 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);}
Run Code Online (Sandbox Code Playgroud)

(改变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;}
Run Code Online (Sandbox Code Playgroud)

  • @Load:5.1.2.2.1/1:程序启动时调用的函数名为`main`.应定义......*或以其他一些实现定义的方式*.那是因为实现可以接受这种形式. (2认同)

Dan*_*bić 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>
Run Code Online (Sandbox Code Playgroud)

如果要测试它,请将其保存为pi.xslt并在IE中打开以下XML文件:

<?xml version="1.0"?> 
<?xml-stylesheet href="pi.xslt" type="text/xsl" ?> 
<R> 
  10 
</R> 
Run Code Online (Sandbox Code Playgroud)

  • 我的<眼睛> </眼睛>!护目镜,他们<不做什么</ do>! (42认同)
  • 我不敢相信你说"开...... IE" (7认同)

mer*_*tor 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
Run Code Online (Sandbox Code Playgroud)

(可以删除换行符,仅用于避免滚动条)

好极了!圈版!

    $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
Run Code Online (Sandbox Code Playgroud)

对于不熟悉的长版本:

#!/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;
Run Code Online (Sandbox Code Playgroud)

  • 我想你以前从未见过APL. (13认同)
  • 这是迄今为止我一生中见过的最难以理解的代码 (6认同)
  • @Chris Marisic:你有没有检查过其他问题/标题`code-golf`?:)我看到了更多难以理解的例子. (5认同)
  • @Peter:与大多数人不同,我都看过和写过APL.习惯它的特殊字符需要几周的时间,但之后它可以很容易理解.即使经过几十年的习惯,Perl仍然要糟糕得多. (3认同)

Joh*_*ooy 25

FORTRAN - 101 Chars

$ f95 piday.f95 -o piday && echo 8 | ./piday
Run Code Online (Sandbox Code Playgroud)


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
Run Code Online (Sandbox Code Playgroud)


    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
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢圈子版本看起来像死星. (8认同)

Ski*_*izz 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
Run Code Online (Sandbox Code Playgroud)

此版本也处理奖金测试用例,为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
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢StackOverflow! (12认同)
  • @Alcari:如果你在高级语言使用的库中包含了所有代码,那么它们的字符数将会大大增加.在汇编程序中,执行`printf("%f",a/b)`并不简单,没有单一指令可以做到这一点,我上面的实现假设0 <= a/b <10并且操作是一个除法并且a和b是整数. (3认同)
  • 有趣的是,一些高级语言的字符数比它产生的二进制字数短. (2认同)

lun*_*chs 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
Run Code Online (Sandbox Code Playgroud)

对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
Run Code Online (Sandbox Code Playgroud)


Dan*_*tta 15

在dc:88和93 93 94 96 102 105 129 138 141 chars

为了以防万一,我现在正在使用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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

要运行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
Run Code Online (Sandbox Code Playgroud)


Dan*_*bić 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
Run Code Online (Sandbox Code Playgroud)

这是一个更漂亮的版本:

( $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
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你更漂亮的版本=) (3认同)

Guf*_*ffa 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);}}
Run Code Online (Sandbox Code Playgroud)

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 另外,也发现了`x*xx +++ y*y`,但乍一看是一件疯狂的事情. (4认同)

Joe*_*ams 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
Run Code Online (Sandbox Code Playgroud)

由于HyperCard 2.2不支持stdin/stdout,因此提供了一个函数.


Ste*_*eve 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
Run Code Online (Sandbox Code Playgroud)

处理奇数: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)}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

230个字符:

main=do{r<-read`fmap`getLine;let{p=putStr;d=2/fromIntegral r^2;l y n=let c m x=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" ">>c m(x+1)in if y>r then print n else c n(-r)>>=l(y+2)};l(1-r`mod`2-r)0}

Unminified:

main = do r <- read `fmap` getLine
          let p = putStr
              d = 2/fromIntegral r^2
              l y n = let c m x = 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 " " >> c m (x+1)
                      in if y > r
                         then print n
                         else c n (-r) >>= l (y+2)
          l (1-r`mod`2-r) 0

我有点希望它会击败一些必要的版本,但我现在似乎无法进一步压缩它.


Mla*_*vić 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
Run Code Online (Sandbox Code Playgroud)

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('*')
Run Code Online (Sandbox Code Playgroud)


Jas*_*ers 9

PHP:117

基于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;
Run Code Online (Sandbox Code Playgroud)


Mat*_*ins 8

你们的想法太难了.

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

  • 人物数量有点失控,你不觉得吗?:) (8认同)
  • 不规模.不可维护的! (7认同)
  • +1,总是首先做最明显的事情......如果有人不喜欢它,大声抱怨说规格不够清楚 (5认同)

Dan*_*ron 7

Y:47,46,45

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

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

你会把它c 2称为c 8c 10等等.

奖金:49

为了处理奇数输入,例如13,我们必须对奇数值x坐标进行滤波,而不是简单地取每隔一行输出(因为现在索引可以从偶数或奇数开始).这种推广花费了我们4个字符:

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

最终版本:

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
)
Run Code Online (Sandbox Code Playgroud)

由于Marshall Lochbam在J论坛上的改进和概括.


Nic*_*ley 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
Run Code Online (Sandbox Code Playgroud)