Natural Pi#0-ロック


39

ゴール

入力を受け取るプログラム/関数を作成し、整数のランダムなペアが比較的素数であるNかどうかを確認しN、を返しますsqrt(6 * N / #coprime)

TL; DR

これらの課題は、Piを概算するために自然と脳(およびおそらく再利用可能なリソース)のみを必要とするアルゴリズムのシミュレーションです。ゾンビの黙示録中に本当にPiが必要な場合、これらの方法は弾薬を無駄にしません!さらに8つの課題があります。推奨事項を作成するには、サンドボックスの投稿をチェックしてください。

シミュレーション

何をシミュレートしていますか?さて、2つのランダムな整数が比較的素数(すなわち、コプライムまたはgcd == 1)である確率は6/Pi/Piです。それらを数える; gcdが1 かどうかを確認します。繰り返す。これを回繰り返した後、sqrt(6.0 * total / num_coprimes)に向かう傾向がありPiます。黙示録的な世界で平方根を計算するのが不安になっても心配しないでください!そのためのニュートン法があります。

これをどのようにシミュレートしますか?

  • 入力してください N
  • 次のN時間を実行します。
    • ランダムな正の整数を均一に生成しij
    • 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が大きすぎる場合にスタックオーバーフローなどを返す場合は大丈夫ですか?
16年

@Fatalizeが言語の制限であれば、確かに。それ以外の場合は、を処理する必要がありN=10^6ます。
NonlinearFruit


2
目標は誤解を招くものであり、1組の整数のみがチェックされると述べています。
user253751

1
生成される乱数の上限は1000000である必要がありますか?より大きな上限は許容されますか?
ソク

回答:


12

APL、23バイト

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

説明:

  • ?⍵2⍴1e6:範囲[1..10 6 ] の乱数の2行by列の行列を生成します
  • 1+.=∨/:各ペアのGCDを取得し、1に等しい数を確認します。これにより、Sが計算されます。
  • .5*⍨6×⍵÷:(6×÷÷S)0.5

11

ゼリー20 18 16 バイト

@ Pietu1998のおかげで-2バイト(チェーンと使用カウントċ11、2未満の合計の代わりに<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

TryItOnline


ḤRµȷ6Xµ€g2/ċ1÷³6÷½2バイト節約します。(ȷ61ニラドで10 ^ 6、ċ1カウント1)
PurkkaKoodari

おかげで(私は思う-ああ、私は(私はいくつかのことを試してみました)、カウント1トリックを忘れてしまったようなチェーン、それまでにどのようにうまくできなかったȷ²小さな小さなビットより速いですȷ6
ジョナサン・アラン

かもしれない。考えてȷ²¤
みる

1
Ḥȷ6xX€ランダムサンプリングで動作するはずです。
デニス

9

Python 2、143 140 132 124 122 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

ここでテストしてください!

ジョナサン・アランの2バイトの保存に感謝します:)


OPによれば1 <= i , j <= 10^6、を使用する必要がありますrandrange(1,1e6+1)
mbomb007

1
また、言語名の中にrepl.itリンクがあるのは本当に奇妙です。言語名のリンクは、もしあれば、言語のホームページにあるべきです。repl.itリンクをコードの下に別のリンクとして配置します。
mbomb007

@ mbomb007良い点、私はそれを修正しました:)しばらくしています!
カーデ

1
k=lambda:r.randrange(1e6)+12バイト節約
ジョナサンアラン

1
@JonathanAllan良いキャッチ、ありがとう!
カーデ


8

R、103 99 95 99 98 94バイト

少し下がっている可能性があります。@ antoine-sacのために4バイトを削減しsample、の^.5代わりにsqrt、およびの1e6代わりにを使用してのエイリアスを定義して、さらに4バイトを削減します10^6。追加しました4バイトのサンプリングがいることを確実にするためij、本当に均一です。6*N/sum(x)と同じであることに気付いた後、1バイト削除しました6/mean(x)。4バイトを節約するpryr::f代わりに使用されfunction(x,y)ます。

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-モニカの復元16年

私は間違っているかもしれませんが、適切に均一なランダム整数のために、replace = Tでサンプルを使用すべきではありません。たとえばsample(10,10)、1:10ですべての数値を返すことが保証されていますが、数値をsample(10,10,T)繰り返すことができるランダムな選択が生成されます。
MickyT

@MickyTあなたは絶対に正しいです、私はこれを数分前に自分で実現しました。この場合、これが数学的にどのように機能するのか完全にはわかりません-私が知る限り、両方の方法はほぼ正確です。投稿を編集してこの情報を追加します。
rturnbull

N << 10 ^ 6の場合、どちらの方法も同じ精度です。任意の大きなNを処理するには、交換用のサンプルを使用する必要があります。
asac-モニカの復元16年

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

1
@isaacgそうではありません。説明を読むと、ランダムな値は[0、10 ** 6)から選択されてから増分されると書かれています。
メゴ

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

I <3 Scala!特に、説明が必要な場合があるためです。
ローマングラフ

@RomanGräf正直に言うと、不明瞭だと思うのは6fSeq.fillとだけmath.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=_=>そのコードまたは図面ですか?
アロス

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=gcd13としてカウントされるコマンドラインオプションが必要です。入力は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

比較的遅いが、それでも動作します。2つの乱数(1から1e6まで)を取り、それらのgcdが2より小さいかどうかをチェックする関数をN回複製します(私の古いgcd関数を使用)。


1
警告が気にならない場合1:xは動作します。
MickyT

4

PowerShell v2 +、118 114バイト

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です)。各反復で、新しい数値を取得します(nimum フラグは、最大フラグがを超えないことを保証します。これは、OPがより大きいため、OPで許可されます)。$n$k=0Random$i$j-mi1>=1[int]::MaxValue10e6

次に、GCD whileループに入ります。次に、GCDが1である限り、$o増分されます。forループの終わりに、単純な[math]::Sqrt()呼び出します。この呼び出しはパイプラインに残り、出力は暗黙的です。

入力で実行するには約15分かかります 10000〜1年前のCore i5ラップトップます。

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すなわち、1行に宣言しint c=n,t=0,x,y;、そして!=0(私が思う)になることができます>0。これにより、全体で12バイト節約できます。ただし、これはxとyのGCDを見つけるのに最適な方法です。
TNT


1

フリンク、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)を与えるので、減算できます。不運なことに、ループ変数とその境界はローカルでループ外では未定義なのでnは事前に割り当てられ、aが使用されます。

冗長

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文字です...?
電卓

キャッチしてくれてありがとう。私は改行を数えませんでしたが、²、³は1バイトだけですが、⁶はそれ以上です。最終改行なしで89バイトに修正しました。
多分

詳細コードを修正していません。
CalculatorFeline

これは、間隔でとにかく引用符と数字などの1対1のマッチではありません
maybeso


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数秒かかりました。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.