自然派#0-摇滚


39

目标

创建一个接受输入的程序/函数N,检查N随机整数对是否相对质数,然后返回sqrt(6 * N / #coprime)

TL; DR

这些挑战是仅需要自然和大脑(也许还有一些可重复使用的资源)才能逼近Pi的算法模拟。如果您在僵尸启示录期间确实需要Pi,那么这些方法不会浪费弹药!还有另外八个挑战。检出沙盒帖子以提出建议。

模拟

我们在模拟什么?好吧,两个随机整数是相对质数(即coprime或gcd == 1)的概率是6/Pi/Pi,因此计算Pi的自然方法是挖出两个桶(或少数几个)的岩石。数他们;看看他们的gcd是否为1;重复。这样做后,一对夫妇很多次,sqrt(6.0 * total / num_coprimes)会趋向Pi。如果计算世界末日后的平方根使您感到紧张,请不要担心!有牛顿法

我们如何模拟这一点?

  • 接受输入 N
  • 请执行以下N次数:
    • 均匀生成随机正整数,i并且j
    • 1 <= i , j <= 10^6
    • 如果gcd(i , j) == 1result = 1
    • 其他: result = 0
  • N结果的总和,S
  • 返回 sqrt(6 * N / S)

在此处输入图片说明

规格

  • 输入值
    • 灵活,可以采用任何标准方式(例如,函数参数,STDIN)和任何标准格式(例如,字符串,二进制)进行输入
  • 输出量
    • 灵活,以任何标准方式(例如退货,打印)提供输出
    • 可以使用空格,尾随和前导空格
    • 精度,请提供至少4位小数位数(即3.1416
  • 计分
    • 最短的代码胜出!

测试用例

由于随机的机会,您的输出可能与这些不一致。但平均而言,对于的给定值,您应该能获得如此高的准确性N

Input     ->  Output 
-----         ------
100       ->  3.????
10000     ->  3.1???
1000000   ->  3.14??
code-golf  math  random  pi  approximation  popularity-contest  code-golf  sequence  number-theory  binary  coding-theory  code-golf  math  3d  code-golf  code-golf  math  number  code-golf  kolmogorov-complexity  code-golf  ascii-art  graphical-output  binary-tree  code-golf  ascii-art  code-golf  ascii-art  kolmogorov-complexity  code-golf  array-manipulation  hexadecimal  code-golf  math  number  set-theory  code-golf  math  arithmetic  number-theory  integer  code-golf  string  kolmogorov-complexity  code-golf  math  sequence  arithmetic  decision-problem  code-golf  code-golf  ascii-art  code-golf  array-manipulation  parsing  code-golf  string  ascii-art  kolmogorov-complexity  code-challenge  code-golf  sequence  code-golf  number  array-manipulation  sorting  code-golf  string  function  code-golf  arithmetic  code-golf  math  sequence  number-theory  primes  restricted-source  javascript  code-challenge  polyglot  rosetta-stone  code-golf  code-golf  regular-expression  code-golf  math  code-golf  math  primes  code-golf  ascii-art  kolmogorov-complexity  binary  code-golf  math  sequence  code-golf  sequence  subsequence  code-golf  string  code-golf  parsing  music  code-golf  grid  game  path-finding  board-game  code-golf  string  binary  code-golf  array-manipulation  balanced-string  code-golf  code-golf  algorithm  code-golf  string  number  arithmetic  array-manipulation  code-golf  array-manipulation  binary-tree  tree-traversal  code-golf  code-golf  tips  code-golf  string  base-conversion  code-golf  tips  s.i.l.o.s  code-golf  string  ascii-art  code-golf  code-challenge  code-golf  game 

1
我们的答案是否需要解决?N = 1000000如果N程序太大,例如返回堆栈溢出,可以吗?
致命

@fatalize,如果这是语言的限制,那么可以。否则,您需要处理N=10^6
NonlinearFruit


2
目标是令人误解的,它指出仅检查一对整数。
user253751 '16

1
生成的随机数的上限是否需要恰好为1000000?可以接受更大的上限吗?
2016年

Answers:


12

APL,23个字节

{.5*⍨6×⍵÷1+.=∨/?⍵2⍴1e6}

说明:

  • ?⍵2⍴1e6:生成范围为[1..10 6 ] 的2×⍵随机数矩阵
  • 1+.=∨/:获取每对的GCD并查看多少等于1。这将计算S。
  • .5*⍨6×⍵÷:(6×⍵÷S)0.5

11

果冻20 18 16 字节

@ Pietu1998产生-2个字节(链和使用计数1s,ċ1而不是少于两个的总和<2S

@Dennis产生-2个字节(在采样之前多次重复1e6以避免链接)

Ḥȷ6xX€g2/ċ1÷³6÷½

(由于随机函数,速度极慢)

怎么样?

Ḥȷ6xX€g2/ċ1÷³6÷½ - Main link: n
 ȷ6              - 1e6
   x             - repeat
Ḥ                -     double, 2n
    X€           - random integer in [1,1e6] for each
       2/        - pairwise reduce with
      g          -     gcd
         ċ1      - count 1s
           ÷     - divide
            ³    - first input, n
             6   - literal 6
              ÷  - divide
               ½ - square root

在线试用


ḤRµȷ6Xµ€g2/ċ1÷³6÷½保存2个字节。(ȷ6在一个尼拉德中是10 ^ 6,ċ1算一个)
PurkkaKoodari '16

啊,我不知道该如何将其链接起来(我尝试了几件事),却忘记了count 1的把戏-谢谢(我想ȷ²比这快一点点ȷ6
Jonathan Allan

可能。现在,我想到了,ȷ²在这里成为两个链接并没有什么坏处,但是需要一个额外的链接或¤用于某些用例
PurkkaKoodari

1
Ḥȷ6xX€应该为随机抽样工作。
丹尼斯

9

Python 2中,143个 140 132 124 122 124 122字节

自打高尔夫球以来已经有一段时间了,所以我可能在这里错过了一些东西!随着我的缩短,它将不断更新。

import random as r,fractions as f
n,s=input(),0
k=lambda:r.randrange(1e6)+1
exec's+=f.gcd(k(),k())<2;'*n
print(6.*n/s)**.5

在这里测试我

感谢Jonathan Allan的两字节保存:)


根据OP,1 <= i , j <= 10^6因此您需要使用randrange(1,1e6+1)
mbomb007 '16

1
同样,在语言名称中包含repl.it链接真的很奇怪。lang名称中的链接应指向该语言的主页(如果有)。将您的repl.it链接作为单独的链接放在代码下方。
mbomb007 '16

@ mbomb007好点了,我已经解决了:)已经有一段时间了!
卡德

1
k=lambda:r.randrange(1e6)+1保存两个字节
Jonathan Allan

1
@JonathanAllan很好,谢谢!
卡德,2013年


8

R,103 99 95 99 98 94字节

可能会打低一点。通过定义一个别名削减4个字节由于@安托囊,和另一个4个字节sample,使用^.5的而不是sqrt和,1e6而不是10^6。新增的4个字节,以保证采样ij是真正的统一。我意识到6*N/sum(x)与相同后,删除了一个字节6/mean(x)。用于pryr::f代替function(x,y)保存4个字节。

N=scan()
s=sample
g=pryr::f(ifelse(o<-x%%y,g(y,o),y))
(6/mean(g(s(1e6,N,1),s(1e6,N,1))==1))^.5

样本输出:

N=100     -> 3.333333
N=10000   -> 3.137794
N=1000000 -> 3.141709

1
您可以简单地使用sample(10^6,N)。它不仅更短,而且效率更高。
asac-恢复莫妮卡

我可能是错的,但不应将样本与replace = T一起使用以适当地均匀地分配随机整数。例如sample(10,10),保证返回所有以1:10的数字,而sample(10,10,T)将产生一个随机选择,可以重复数字。
MickyT

@MickyT你是完全正确的,我几分钟前才意识到这一点。我不完全确定这种情况在数学上如何发挥作用-据我所知,这两种方法大致相同。我将编辑我的帖子以添加此信息。
rturnbull

当N << 10 ^ 6时,这两种方法都同样准确。要处理任意大的N,您必须取样进行更换,并保持良好。
asac-恢复莫妮卡

7

其实是19个位元组

`6╤;Ju@Ju┤`nkΣß6*/√

在线尝试!

说明:

`6╤;Ju@Ju┤`nkΣß6*/√
`6╤;Ju@Ju┤`n         do this N times:
 6╤;                   two copies of 10**6
    Ju                 random integer in [0, 10**6), increment
      @Ju              another random integer in [0, 10**6), increment
         ┤             1 if coprime else 0
            kΣ       sum the results
              ß      first input again
               6*    multiply by 6
                 /   divide by sum
                  √  square root

i,j不允许为0
isaacg '16

1
@isaacg不是。如果您读懂了说明,则说明从[0,10 ** 6)中选择了随机值,然后递增。
Mego

7

MATL,22字节

1e6Hi3$YrZ}Zd1=Ym6w/X^

在线尝试!

1e6      % Push 1e6
H        % Push 2
i        % Push input, N
3$Yr     % 2×N matrix of uniformly random integer values between 1 and 1e6
Z}       % Split into its two rows. Gives two 1×N arrays
Zd       % GCD, element-wise. Gives a 1×N array
1=       % Compare each entry with 1. Sets 1 to 0, and other values to 0
Ym       % Mean of the array
6w/      % 6 divided by that
X^       % Square root. Implicitly display

6

Pyth,21个字节

@*6cQ/iMcmhO^T6yQ2lN2

在线尝试。

说明

                Q          input number
               y           twice that
         m                 map numbers 0 to n-1:
             T                 10
            ^ 6                to the 6th power
           O                   random number from 0 to n-1
          h                    add one
        c        2         split into pairs
      iM                   gcd of each pair
     /            lN       count ones
   cQ                      divide input number by the result
 *6                        multiply by 6
@                   2      square root

6

Scala,149126字节

val& =BigInt
def f(n: Int)={math.sqrt(6f*n/Seq.fill(n){val i,j=(math.random*99999+1).toInt
if(&(i).gcd(&(j))>1)0 else 1}.sum)}

说明:

val& =BigInt                //define & as an alias to the object BigInt, because it has a gcd method
def f(n:Int)={              //define a method
  math.sqrt(                //take the sqrt of...
    6f * n /                //6 * n (6f is a floating-point literal to prevent integer division)
    Seq.fill(n){            //Build a sequence with n elements, where each element is..
      val i,j=(math.random*99999+1).toInt //take 2 random integers
      if(&(i).gcd(&(j))>1)0 else 1        //put 0 or 1 in the list by calling
                                          //the apply method of & to convert the numbers to
                                          //BigInt and calling its bcd method
    }.sum                   //calculate the sum
  )
}

我<3 Scala!特别是因为有时确实需要解释。
罗曼·格拉夫(RomanGräf)

@RomanGräf说实话,我认为唯一的东西可能是不明确的6fSeq.fillmath.random
corvus_192

5

球拍92字节

(λ(N)(sqrt(/(* 6 N)(for/sum((c N))(if(= 1(gcd(random 1 1000000)(random 1 1000000)))1 0)))))

取消高尔夫:

(define f
  (λ (N)
    (sqrt(/ (* 6 N) 
            (for/sum ((c N))
              (if (= 1
                     (gcd (random 1 1000000)
                          (random 1 1000000)))
                  1 0)
              )))))

测试:

(f 100)
(f 1000)
(f 100000)

输出:

2.970442628930023
3.188964020716403
3.144483068444827

5

JavaScript(ES7),107 95 94字节

n=>(n*6/(r=_=>Math.random()*1e6+1|0,g=(a,b)=>b?g(b,a%b):a<2,q=n=>n&&g(r(),r())+q(n-1))(n))**.5

ES6版本恰好为99个字节,但ES7指数运算符在上**保存了5个字节Math.sqrt

不打高尔夫球

function pi(n) {
  function random() {
    return Math.floor(Math.random() * 1e6) + 1;
  }
  function gcd(a, b) {
    if (b == 0)
      return a;
    return gcd(b, a % b);
  }
  function q(n) {
    if (n == 0)
      return 0;
    return (gcd(random(), random()) == 1 ? 1 : 0) + q(n - 1));
  }
  return Math.sqrt(n * 6 / q(n));
}

在Ungolfed版本gcd调用的函数g
罗马格拉夫

r=_=>是代码还是工程图?
2016年

n=>(n*6/(r=_=>Math.random()*1e6,g=(a,b)=>b?g(b,a%b):a>-2,q=n=>n&&g(~r(),~r())+q(n-1))(n))**.5缩短1B
l4m2

n=>(n*6/(q=_=>n--&&q(r=_=>Math.random()*1e6)+g(~r(),~r()))(g=(a,b)=>b?g(b,a%b):a>-2))**.5
l4m2

5

PHP,82 77 74字节

for(;$i++<$argn;)$s+=2>gmp_gcd(rand(1,1e6),rand(1,1e6));echo(6*$i/$s)**.5;

像这样运行:

echo 10000 | php -R 'for(;$i++<$argn;)$s+=2>gmp_gcd(rand(1,1e6),rand(1,1e6));echo(6*$i/$s)**.5;' 2>/dev/null;echo

说明

它在锡上说了什么。需要PHP_GMP gcd

调整

  • 通过使用节省了3个字节 $argn

4

Perl,64个字节

sub r{1+~~rand 9x6}$_=sqrt$_*6/grep{2>gcd r,r}1..$_

需要命令行选项-pMntheory=gcd,计数为13。输入取自stdin。

样品用量

$ echo 1000 | perl -pMntheory=gcd pi-rock.pl
3.14140431218772

4

R,94个字节

N=scan();a=replicate(N,{x=sample(1e6,2);q=1:x[1];max(q[!x[1]%%q&!x[2]%%q])<2});(6*N/sum(a))^.5

相对较慢,但仍然有效。复制N次一个接受2个随机数(从1到1e6)的函数,并检查其gcd是否小于2(使用mine旧gcd函数)。


1
如果您不担心警告,那就可以了1:x
MickyT

4

PowerShell v2 +,118114字节

param($n)for(;$k-le$n;$k++){$i,$j=0,1|%{Random -mi 1};while($j){$i,$j=$j,($i%$j)}$o+=!($i-1)}[math]::Sqrt(6*$n/$o)

接受输入$n,开始for循环,直到$k等于$n$k=0在第一次进入循环时隐含)。每次迭代,获取新的Random数字$i$j-minimum 1标志确保我们这样做,>=1并且最大标志不允许达到[int]::MaxValue,这是OP所允许的,因为它大于10e6)。

然后我们进入GCD while循环。然后,只要GCD为1$o就递增。在for循环的最后,我们做一个简单的[math]::Sqrt()调用,该调用留在管道上,并且输出是隐式的。

10000在大约1岁的Core i5笔记本电脑上运行输入内容大约需要15分钟。

例子

PS C:\Tools\Scripts\golfing> .\natural-pi-0-rock.ps1 100
3.11085508419128

PS C:\Tools\Scripts\golfing> .\natural-pi-0-rock.ps1 1000
3.17820863081864

PS C:\Tools\Scripts\golfing> .\natural-pi-0-rock.ps1 10000
3.16756133579975

3

Java 8,164 151字节

n->{int c=n,t=0,x,y;while(c-->0){x=1+(int)(Math.random()*10e6);y=1+(int)(Math.random()*10e6);while(y>0)y=x%(x=y);if(x<2)t++;}return Math.sqrt(6f*n/t);}

说明

n->{
    int c=n,t=0,x,y;
    while(c-->0){                          // Repeat n times
        x=1+(int)(Math.random()*10e6);     // Random x
        y=1+(int)(Math.random()*10e6);     // Random y
        while(y>0)y=x%(x=y);               // GCD
        if(x<2)t++;                        // Coprime?
    }
    return Math.sqrt(6f*n/t);              // Pi
}

测试线束

class Main {
    public static interface F{ double f(int n); }
    public static void g(F s){
        System.out.println(s.f(100));
        System.out.println(s.f(1000));
        System.out.println(s.f(10000));
    }
    public static void main(String[] args) {
        g(
            n->{int c=n,t=0,y,x;while(c-->0){x=1+(int)(Math.random()*10e6);y=1+(int)(Math.random()*10e6);while(y>0)y=x%(x=y);if(x<2)t++;}return Math.sqrt(6f*n/t);}
        );
    }
}

更新资料

  • -13 [16-10-05]感谢@TNT并添加了测试工具

1
你不需要括号围绕第一nt+=1可以成为t++,您可以将您int的声明成一条线,即int c=n,t=0,x,y;,和!=0(我认为)可以成为>0。这应该总共节省12个字节。不过,这是找到x和y的GCD的巧妙方法。
TNT


1

Frink,84 89

r[]:=random[10^6]+1
g=n=eval[input[1]]
for a=1to n
g=g-1%gcd[r[],r[]]
println[(6*n/g)^.5]

我很幸运:g = n = ...g = 0 n = ...上节省了一个字节;和1%gcd()给出(0,1)与(1,0),所以我可以减去。而倒霉:ñ被预先指定和一个使用,因为循环变量和它们的边界是本地和外循环不确定的。

详细

r[] := random[10^6] + 1     // function. Frink parses Unicode superscript!
g = n = eval[input[""]]     // input number, [1] works too
for a = 1 to n              // repeat n times
   g = g - 1%gcd[r[], r[]]  // subtract 1 if gcd(i, j) > 1
println[(6*n/g)^.5]         // ^.5 is shorter than sqrt[x], but no super ".", no ½

那是90个字节和88个字符...?
CalculatorFeline

感谢您抓住这一点。我没有计算换行符,而²,³只是1个字节,而⁶甚至更多。我将其固定为89个字节,没有最后的换行符。
也许

您尚未固定详细代码。
CalculatorFeline

这不是一个一对一的比赛无论如何与间距,报价和数量等
maybeso

1

AWK,109字节

func G(p,q){return(q?G(q,p%q):p)}{for(;i++<$0;)x+=G(int(1e6*rand()+1),int(1e6*rand()+1))==1;$0=sqrt(6*$0/x)}1

在线尝试!

我很惊讶它在合理的时间内运行了1000000次。


1

Pyt37 35字节

←Đ0⇹`25*⁶⁺Đ1⇹ɾ⇹1⇹ɾǤ1=⇹3Ș+⇹⁻łŕ⇹6*⇹/√

说明:

←Đ                                              Push input onto stack twice
  0                                             Push 0
   ⇹                                            Swap top two elements of stack
    `                      ł                    Repeat until top of stack is 0
     25*⁶⁺Đ1⇹ɾ⇹1⇹ɾ                              Randomly generate two integers in the range [1,10^6]
                  Ǥ1=                           Is their GCD 1?
                     ⇹3Ș                        Reposition top three elements of stack
                        +                       Add the top 2 on the stack
                         ⇹⁻                     Swap the top two and subtract one from the new top of the stack
                            ŕ                   Remove the counter from the stack
                             ⇹                  Swap the top two on the stack
                              6*                Multiply top by 6
                                ⇹               Swap top two
                                 /              Divide the second on the stack by the first
                                  √             Get the square root

1

J,27字节

3 :'%:6*y%+/(1:=?+.?)y#1e6'

说明:

3 :'                      '  | Explicit verb definition
                     y#1e6   | List of y copies of 1e6 = 1000000
            (1:=?+.?)        | for each item, generate i and j, and test whether their gcd is 1
          +/                 | Sum the resulting list
      6*y%                   | Divide y by it and multiply by six
    %:                       | Square root

3.14157for的使用非常幸运N = 10000000,这花了2.44几秒钟。


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.