내추럴 파이 # 0-락


39

입력을받는 프로그램 / 함수를 만들고 임의의 정수 쌍이 소수 N인지 확인 N하고를 반환합니다 sqrt(6 * N / #coprime).

TL; DR

이러한 과제는 Pi를 근사화하기 위해 자연과 두뇌 (및 일부 재사용 가능한 리소스) 만 필요한 알고리즘 시뮬레이션입니다. 좀비 종말 중에 Pi가 정말로 필요하다면,이 방법들은 탄약을 낭비 하지 않습니다 ! 앞으로 8 가지 과제가 더 있습니다. 체크 아웃 샌드 박스 포스트 추천을 할 수 있습니다.

시뮬레이션

우리는 무엇을 시뮬레이션하고 있습니까? 음, 두 개의 임의의 정수가 상대적으로 소수 일 가능성이 높습니다 (즉, 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) == 1:result = 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

언어의 제한이 있다면 @Fatalize. 그렇지 않으면을 처리해야합니다 N=10^6.
NonlinearFruit


2
목표는 오해의 소지가 있으며 한 쌍의 정수만 검사한다고 나타냅니다.
user253751

1
생성 된 난수에 대한 상한이 정확히 1000000이어야합니까? 더 큰 상한이 허용됩니까?
Sok

답변:


12

APL, 23 바이트

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

설명:

  • ?⍵2⍴1e6: [1..10 6 ] 범위의 난수로 구성된 2x1 행렬을 생성합니다 .
  • 1+.=∨/: 각 쌍의 GCD를 구하고 1이 몇 개인 지 확인합니다. S를 계산합니다.
  • .5*⍨6×⍵÷: (6 × ⍵ ÷ S) 0.5

11

젤리 , 20 18 16 바이트

@ Pietu1998 덕분에 -2 바이트 (체인 및 사용 횟수 1, ċ1합계 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 바이트를 절약합니다. ( ȷ6단일 nilad에서 10 ^ 6, 하나 ċ1계산)
PurkkaKoodari

덕분에 (내가 생각 - 아 나는 그런 체인을 최대로 (나는 몇 가지 시도), 카운트 1 트릭 잊었 방법을 작동하지 않을 수있는 ȷ²작은 작은 조금 더 빨리보다 ȷ6)
조나단 앨런

아마도. 지금은 그것을 생각하는 것이 ȷ²두 개의 링크가되는 것은 여기 다치게하지 않지만, 추가 링크 또는 필요 ¤일부 사용 사례
PurkkaKoodari

1
Ḥȷ6xX€무작위 샘플링에서 작동합니다.
Dennis

9

파이썬 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

여기서 시험 해봐 !

2 바이트 저장에 대한 Jonathan Allan에게 감사드립니다 :)


OP에 따르면을 1 <= i , j <= 10^6사용해야 randrange(1,1e6+1)합니다.
mbomb007

1
또한 언어 이름 내에 repl.it 링크를 갖는 것은 정말 이상합니다. 언어 이름의 링크는 해당 언어의 홈페이지로 연결되어야합니다. repl.it 링크를 코드 아래에 별도의 링크로 넣으십시오.
mbomb007

@ mbomb007 좋은 지적, 나는 그것을 고쳤다 :) 오랜만에!
Kade

1
k=lambda:r.randrange(1e6)+12 바이트 절약
Jonathan Allan

1
@JonathanAllan 좋은 캐치, 감사합니다!
Kade


8

R, 103 99 95 99 98 94 바이트

약간 다운 될 수 있습니다. 별칭을 정의하여 인해 @ 앙투안 SAC-4 바이트, 또 다른 4 바이트를 삭감 sample하여, ^.5대신 sqrt하고 1e6대신 10^6. 추가 된 4 바이트의 샘플링이 있는지 확인 i하고 j진정으로 균일하다. 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). 더 짧을뿐만 아니라 훨씬 더 효율적입니다.
antoine-sac

잘못되었을 수도 있지만 샘플을 replace = T와 함께 사용하여 올바르게 임의의 정수를 사용해서는 안됩니다. 예를 들어 sample(10,10)1:10의 모든 숫자를 반환하는 반면 sample(10,10,T)숫자를 반복 할 수있는 임의의 항목을 생성합니다.
MickyT

@MickyT 당신은 절대적으로 정확합니다. 몇 분 전에 나 자신을 깨달았습니다. 이 인스턴스에서 이것이 수학적으로 어떻게 나타나는지 완전히 확신하지 못합니다. 알 수있는 한 두 방법 모두 대략적으로 정확합니다. 이 정보를 추가하기 위해 게시물을 편집하겠습니다.
rturnbull

N << 10 ^ 6 일 때 두 방법 모두 동일합니다. 임의로 큰 N을 처리하려면 교체, 좋은 캐치로 샘플링해야합니다.
antoine-sac

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)에서 선택된 다음 증분됩니다.
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

스칼라, 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 스칼라! 특히 때로는 설명이 필요하기 때문에.
Roman Gräf

RomanGräf는 솔직히 @, 내가 생각하는 유일한 일이 될 불분명 수 6f, Seq.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

자바 스크립트 (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 Version에서이 gcd함수를 호출합니다g
Roman Gräf

r=_=>그 코드입니까 아니면 그림입니까?
aross

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))**.51B 짧음
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

펄, 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

상대적으로 느리지 만 여전히 작동합니다. N은 2 개의 난수 (1에서 1e6까지)를 취하고 gcd가 2보다 작은 지 확인합니다 ( 이전의 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)

input을 취하고 같을 때까지 루프를 $n시작합니다 ( 처음 루프에 들어갈 for때 암시 적 ). 각각의 반복은, 새로운 얻을 번호 및 합니다 ( nimum 플래그는 우리가있어 확인 하고 더 최대 플래그까지 허용하지 않습니다 그것보다 더 큰 이후 영업에 의해 허용되는, ).$k$n$k=0Random$i$j-mi1>=1[int]::MaxValue10e6

그런 다음 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

자바 8, 164151 바이트

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
첫 번째 괄호가 필요하지 않습니다 n, t+=1될 수있는 t++당신은 당신의 응축 수, int즉, 한 줄에 선언을 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 ()는 내가 뺄 수 (1,0) 대 (0,1)를 제공합니다. 그리고 불운 : 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 자 ...?
CalculatorFeline

찾아 주셔서 감사합니다. 줄 바꿈을 세지 않았고 ², ³는 1 바이트에 불과합니다. 최종 줄 바꿈없이 89 바이트로 수정했습니다.
아마 소

자세한 코드를 수정하지 않았습니다.
CalculatorFeline

간격, 따옴표 및 숫자 등이 일대일로 일치하지 않습니다.
아마도


1

Pyt , 37 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.