공동 우선 순위 및 수 pi


23

소개

수 이론은 예기치 않은 연결의 형태로 놀라운 것으로 가득합니다. 여기에 그들 중 하나가 있습니다.

두 개의 정수에 1 이외의 공통 인자가없는 경우 두 개의 정수는 공-프라임입니다 . 숫자 N이 주어지면 1에서 N 까지의 모든 정수를 고려하십시오 . 두 정수 를 무작위로 그립니다 (모든 정수는 각 추첨에서 선택 될 확률이 동일합니다. 추첨은 독립적이며 교체됩니다). 하자 p가 선택한 두 정수가 공동 수상이라는 확률을 나타낸다. 그러면 N 은 무한대가 되므로 p 는 6 / π 2 ≈ 0.6079 ...가됩니다 .

도전

이 과제의 목적은 pN 의 함수 로 계산 하는 것입니다 .

예를 들어, N = 4를 고려 하십시오. 정수 1,2,3,4에서 얻을 수있는 16 개의 가능한 쌍이 있습니다. 이 쌍 중 11 개는 공동 프라임, 즉 (1,1), (1,2), (1,3), (1,4), (2,1), (3,1), (4,1 ), (2,3), (3,2), (3,4), (4,3). 따라서 pN = 4 인 경우 11/16 = 0.6875입니다 .

p정확한 값은 소수점 이하 4 자리 로 계산해야합니다 . 이것은 계산이 결정 론적이어야한다는 것을 암시합니다 (Monte Carlo와는 대조적으로). 그러나 위와 같이 모든 쌍을 직접 열거 할 필요는 없습니다. 모든 방법을 사용할 수 있습니다.

함수 인수 또는 stdin / stdout이 사용될 수 있습니다. 출력을 표시하는 경우 후행 0은 생략 될 수 있습니다. 예를 들어 0.6300로 표시 할 수 있습니다 0.63. 분수가 아닌 10 진수로 표시해야합니다 (문자열 표시는 63/100허용되지 않음).

우승 기준은 가장 적은 바이트입니다. 내장 함수 사용에는 제한이 없습니다.

테스트 사례

입력 / 출력 (위에 표시된대로 네 개의 소수만 필수) :

1    / 1.000000000000000
2    / 0.750000000000000
4    / 0.687500000000000
10   / 0.630000000000000
100  / 0.608700000000000
1000 / 0.608383000000000

입력 범위에 한계가 있습니까?
Eric Towers

@EricTowers 프로그램은 메모리 및 데이터 유형의 제한에 이르기까지 합리적인 크기로 작동해야합니다. 최소 1000
Luis Mendo

합리적 숫자는 반환 값 (문자열 아님)으로 허용됩니까? 내 언어는 기본 합리적 유형을 가지고 63/100있으며 유효한 리터럴이며 계산에 사용할 수 있습니다. (내가 말하는 언어 : Factor , Racket )
cat

@cat 물론입니다! 그래도 필요한 정밀도를 고려하십시오
Luis Mendo

답변:


14

젤리 , 12 8 바이트

RÆṪSḤ’÷²

온라인으로 사용해보십시오!

다음 이진 코드는 이 버전의 Jelly 인터프리터에서 작동 합니다.

0000000: 52 91 b0 53 aa b7 9a 8a  R..S....

생각

분명히 쌍의 수 (j, K) 되도록 J ≤ KJK는 공동 계류 프라임 쌍의 수와 동일 (K, J) 와 동일한 조건을 만족시킨다. 또한 j = k 인 경우 j = 1 = k 입니다.

따라서, 좌표 간의 공동 프라임 쌍의 수 세어 1N ,이 양은 계산하면 충분 m(j를 K) 되도록 J ≤ K 후 계산 1 - 2M까지 .

오일러 피 함수에서 보낸 마지막 φ (k)는 사이 숫자 정수를 산출 1K CO 프라임한다 k는 우리 계산할 수 m 으로서 φ (1) + ... + φ (N)를 .

암호

RÆṪSḤ’÷²    Input: n

R           Yield [1, ..., n].
 ÆṪ         Apply Euler's totient function to each k in [1, ..., n].
   S        Compute the sum of all results.
    Ḥ       Multiply the result by 2.
     ’      Subtract 1.
      ÷²    Divide the result by n².

2
아, 젤리에는 참을성있는 기능이 포함되어 있습니다!? 좋은 생각!
Luis Mendo

2
MATL이 T-1 일에
강제

@quintopia (마침내 끈질긴 기능을 포함했습니다) :-D
Luis Mendo

14

Mathematica 43 42 바이트

내가 발견 격자 원점에서 볼 포인트 아래 그림은 단위 격자의 주어진 사각 지역에 대한 다음과 같은 질문을 통해 문제를 프레이밍에 도움이 될 촬영되는 :

  • 단위-격자 포인트의 몇 분율에 코-프라임 좌표가 있습니까?
  • 원점에서 볼 수있는 단위 격자 점의 일부는 무엇입니까?

그리드


N@Mean[Mean/@Boole@Array[CoprimeQ,{#,#}]]&

후행 0은 생략됩니다.

N@Mean[Mean/@Boole@Array[CoprimeQ,{#,#}]]&/@Range@10

{1., 0.75, 0.777778, 0.6875, 0.76, 0.638889, 0.714286, 0.671875, 0.679012, 0.63}


타이밍

정답은 초 단위의 타이밍입니다.

N@Mean[Mean/@Boole@Array[CoprimeQ,{#,#}]]&[1000]// AbsoluteTiming

{0.605571, 0.608383}



6

Mathematica, 42 32 바이트

Count[GCD~Array~{#,#},1,2]/#^2.&

익명 함수는 단순한 무차별 대입을 사용합니다. 마지막 사례는 내 컴퓨터에서 약 .37 초 안에 실행됩니다. 설명:

                               &   A function taking N and returning
Count[               , , ]           the number of
                      1               ones
                                     in the
                        2             second
                                     level of
         ~Array~                      a matrix of
      GCD                              the greatest common denominators of
                {#,#}                 all 2-tuples in [1..N]
                          /         divided by
                           #          N
                            ^2.      squared.

Mathematica가없는 사람들을 위해 예제 실행과 설명을 게시 할 수 있습니까?
Luis Mendo

2
이것은 우리의 제출을 ​​통합합니다 : Count[Array[GCD,{#, #}],1,2]/#^2.& 내 손님이 되십시오.
DavidC

4

Dyalog APL, 15 바이트

(+/÷⍴)∘∊1=⍳∘.∨⍳

꽤 직설적 인. 그것은 모나 딕 기능 열차입니다. Iota는 1부터 입력까지의 숫자이므로 외부 제품을 gcd로 가져간 다음 비율을 계산합니다.


3

옥타브, 49 47 바이트

그냥 계산 gcd모든 쌍과 계산의를.

@(n)mean(mean(gcd(c=kron(ones(n,1),1:n),c')<2))

크로네 커 제품은 훌륭합니다.


kron! 좋은 생각!
Luis Mendo

나는 처음 사용 meshgrid했지만 kron인라인으로 똑같이 할 수 있음을 알았습니다 ! (-> 익명 함수)
flawr

2

자바 스크립트 (ES6), 88 바이트

n=>eval(`p=0;for(i=n;i;i--)for(j=n;j;j--,p+=a)for(a=1,k=j;k>1;k--)a=i%k||j%k?a:0;p/n/n`)

설명

n=>
  eval(`                     // use eval to enable for loop without {} or return
    p=0;                     // p = number of pairs
    for(i=n;i;i--)           // i = 1 to n
      for(j=n;j;j--,p+=a)    // j = i to n, a will equal 1 if i and j are coprime, else 0
        for(a=1,k=j;k>1;k--) // for each number from 0 to j
          a=i%k||j%k?a:0;    // if i%k and j%k are both 0, this pair is not coprime
    p/n/n                    // return result (equivalent to p/(n*n))
  `)

테스트

의 큰 >100값 ( ) 에는 시간이 걸립니다 n.


2

진지하게, 15 바이트

,;ª)u1x`▒`MΣτD/

육각 덤프 :

2c3ba62975317860b1604de4e7442f

온라인으로 사용해보십시오

문자 그대로 Dennis의 Jelly 솔루션과 정확히 동일한 알고리즘을 사용하기 때문에 설명하지 않아도됩니다 (독립적으로 파생 되었음에도 불구하고).


2

J, 19 17 바이트

*:%~1-~5+/@p:|@i:

용법:

   (*:%~1-~5+/@p:|@i:) 4
0.6875

설명:

*:%~1-~5+/@p:|@i:
               i: [-n..n]
             |@   absolute value of each element ([n..1,0,1,..n])
       5+/@p:     sum of the totient function for each element
    1-~           decreased by one, giving the number of co-prime pairs
*:%~              divided by N^2

Dennis의 솔루션 은 우리가 참종 기능을 어떻게 사용할 수 있는지에 대한 좋은 설명을 제공합니다.

여기에서 온라인으로 사용해보십시오.


2

Mathematica, 35 바이트

@Dennis의 알고리즘을 구현합니다.

(2`4Plus@@EulerPhi@Range[#]-1)/#^2&

1에서 입력 값까지의 범위에 대한 배 심자 (Euler의 phi 함수)의 합을 계산합니다. 부동 소수점 2 (정수 4 자리)를 곱하고 1을 뺍니다. ( " 2"및 " 1`4" 대신에 더 많은 정밀도를 유지할 수 있습니다 .) 이것은 총 코 프라임 쌍의 수이므로 입력의 제곱으로 나누어 원하는 분수를 얻습니다. 두 개는 근사치이므로 결과도 마찬가지입니다.

테스트 f라인을보다 쉽게 ​​읽을 수 있도록 할당 된 기능을 사용하여 테스트 (왼쪽 열에 타이밍 데이터가 있음) .

f=(2`4Plus@@EulerPhi@Range[#]-1)/#^2&
RepeatedTiming[f[#]] & /@ {1, 2, 4, 10, 100, 1000}
(* {{5.71*10^-6, 1.000}, 
    {5.98*10^-6, 0.750}, 
    {0.000010  , 0.6875}, 
    {0.0000235 , 0.6300}, 
    {0.00028   , 0.6087}, 
    {0.0033    , 0.6084} }  *)

편집 : 입력 범위의 범위를 표시하고 (그렇지 않으면 결과가 단조로워지기 때문에 정밀도를 두 개 대신 하나로 스와핑하고) 다른 사람들이 똑같이하도록 도전합니다 ...

f = (2 Plus @@ EulerPhi@Range[#] - 1`4)/#^2 &
{#}~Join~RepeatedTiming[f[#]] & /@ {1, 2, 4, 10, 100, 1000, 10^4, 10^5, 10^6, 10^7}
(*  Results are {input, wall time, output}
    {{       1,  5.3*10^-6, 1.000}, 
     {       2,  6.0*10^-6, 0.7500}, 
     {       4,  0.0000102, 0.68750}, 
     {      10,  0.000023 , 0.63000}, 
     {     100,  0.00028  , 0.6087000}, 
     {    1000,  0.0035   , 0.608383000}, 
     {   10000,  0.040    , 0.60794971000}, 
     {  100000,  0.438    , 0.6079301507000}, 
     { 1000000,  4.811    , 0.607927104783000}, 
     {10000000, 64.0      , 0.60792712854483000}}  *)

RepeatedTiming[]계산을 여러 번 수행하고 평균 시간을 사용하여 콜드 캐시 및 타이밍 이상 값을 유발하는 기타 영향을 무시하려고합니다. 점근 적 한계는

N[6/Pi^2,30]
(*  0.607927101854026628663276779258  *)

따라서 10 ^ 4보다 큰 인수의 경우 "0.6079"를 반환하고 지정된 정밀도 및 정확도 요구 사항을 충족 할 수 있습니다.


2

줄리아, 95 바이트

n->(c=combinations([1:n;1:n],2);((L=length)(collect(filter(x->gcd(x...)<2,c)))÷2+1)/L(∪(c)))

지금은 간단한 접근 방식입니다. 더 짧고 우아한 솔루션을 곧 살펴 보겠습니다. 이것은 정수를 받아들이고 float를 반환하는 익명 함수입니다. 호출하려면 변수에 지정하십시오.

언 골프 드 :

function f(n::Integer)
    # Get all pairs of the integers from 1 to n
    c = combinations([1:n; 1:n], 2)

    # Get the coprime pairs
    p = filter(x -> gcd(x...) == 1, c)

    # Compute the probability
    return (length(collect(p)) ÷ 2 + 1) / length(unique(c))
end

내가 알 수 collect있는 한, 게으른 물건을 취할 필요가 없습니다 length.
고양이

@cat length메소드가 정의되지 않은 곳 에서는 필터링 된 조합 반복자에 대한 경우가 있습니다. endof해당 유형에 대한 메소드가 없기 때문에 마찬가지로 작동하지 않습니다 getindex.
Alex A.


@cat은와 range같은 종류의 객체를 반환하지 않습니다 combinations. 후자는 정의 된 length메소드 가없는 별도 유형 인 조합에 대해 반복자를 리턴합니다 . 여기를 참조 하십시오 . (또한 :구문은 range범위를 구성 하는 것보다 선호됩니다 .)
Alex A.

2

세이지, 55 바이트

lambda a:n((sum(map(euler_phi,range(1,a+1)))*2-1)/a**2)

모든 것을 상징적으로 계산하는 Sage 덕분에 머신 엡실론 및 부동 소수점 문제가 발생하지 않습니다. 출력 형식 규칙을 따르려면 n()(십진수 근사 함수)에 대한 추가 호출 이 필요합니다.

온라인으로 사용해보십시오


아주 좋아요! 최근 Sage를 자주 사용하는 것 같습니다 :-)
Luis Mendo

@LuisMendo Sage는 훌륭하고 모든 일을합니다. Mathematica와 같은 거대한 내장 라이브러리가 있기 때문에 수학 기반 과제에 사용하는 것이 매우 좋지만 (a) Mathematica가 아닌 b) Python을 기반으로하는 구문이 더 좋습니다.
Mego

2

MATL , 20 17 바이트

이 사용하는 최신 버전 (5.0.0) 의 언어를.

@flawr의 답변을 기반으로 접근하십시오 .

i:tg!X*t!Zd1=Y)Ym

편집 (2015 년 4 월 28 일) : 온라인으로 사용해보십시오! 이 답변이 게시 된 후 기능 Y)이름이 X:; 링크는 그 변화를 포함합니다.

>> matl i:tg!X*t!Zd1=Y)Ym
> 100
0.6087

설명

i:         % vector 1, 2, ... up to input number
tg!        % copy, convert into ones, transpose
X*         % Kronecker product. Produces a matrix
t!         % copy, transpose
Zd         % gcd of all pairs
1=         % is it equal to 1?
Y)         % linearize into column array
Ym         % compute mean

기존 답변 : 20 바이트

Oi:t"t@Zd1=sb+w]n2^/

설명

O             % produce literal 0. Initiallizes count of co-prime pairs.
i             % input number, say N
:             % create vector 1, 2, ... N
t             % duplicate of vector
"             % for loop
    t         % duplicate of vector
    @         % loop variable: each element from vector
    Zd        % gcd of vector and loop variable. Produces a vector
    1=s       % number of "1" in result. Each "1" indicates co-primality
    b+w       % accumulate into count of co-prime pairs
]             % end
n2^/          % divide by N^2

옥타브에서 사용한 것과 같은 접근 방식으로 더 짧을 수 있습니까?
flawr

과연! 고맙습니다! 3 바이트 미만 당신은 :-) MATL에서 직접 했어야
루이스 Mendo

내 취침 과거의 방법이 아니었다면 나는) = 시도 것
flawr

1

PARI / GP , 25 바이트

함수를 익명으로 만들면 바이트가 절약되지만 self전체적으로 더 비싸게 만들어야합니다.

f(n)=n^2-sum(j=2,n,f(n\j))

1

요인, (120) 113 바이트

나는 이것을 골프 연습에 보냈고 더 짧아 질 수는 없다.

Julia의 번역 .

[ [a,b] dup append 2 <combinations> [ members ] keep [ first2 coprime? ] filter [ length ] bi@ 2 /i 1 + swap /f ]

예제는 처음 5 개의 테스트 사례에서 실행됩니다 (1000의 값으로 인해 편집기가 정지되고 지금은 실행 파일을 컴파일 할 필요가 없습니다).

! with floating point division
IN: scratchpad auto-use {
      1    
      2    
      4    
      10   
      100  
    }
    [ 
      [1,b] dup append 2 <combinations> [ members ] keep 
      [ first2 coprime? ] filter [ length ] bi@ 2 /i 1 + swap /f 
    ]
    map

--- Data stack:
{ 1.0 0.75 0.6875 0.63 0.6087 }
! with rational division
IN: scratchpad auto-use {
      1    
      2    
      4    
      10   
      100  
    }
    [ 
      [1,b] dup append 2 <combinations> [ members ] keep 
      [ first2 coprime? ] filter [ length ] bi@ 2 /i 1 + swap / 
    ]
    map

--- Data stack:
{ 1.0 0.75 0.6875 0.63 0.6087 }
{ 1 3/4 11/16 63/100 6087/10000 }

아마도 예제를 추가 하시겠습니까?
Luis Mendo

1
@LuisMendo 완료!
cat

1

Samau , 12 바이트

면책 조항 : 질문이 게시 된 후 언어를 업데이트했기 때문에 경쟁하지 않습니다.

▌;\φΣ2*($2^/

16 진 덤프 (Samau는 CP737 인코딩을 사용함) :

dd 3b 5c ad 91 32 2a 28 24 32 5e 2f

Jelly의 Dennis의 답변과 동일한 알고리즘을 사용합니다.


0

Python2 / Pypy, 178 바이트

x파일 :

N={1:set([1])}
n=0
c=1.0
e=input()
while n<e:
 n+=1
 for d in N[n]:
  m=n+d
  try:N[m].add(d)
  except:N[m]=set([d,m])
 for m in range(1,n):
  if N[m]&N[n]==N[1]:c+=2
print c/n/n

달리는:

$ pypy x <<<1
1.0
$ pypy x <<<10
0.63
$ pypy x <<<100
0.6087
$ pypy x <<<1000
0.608383

이 코드는 보조 프라임 쌍을 (n,m) for m<n두 번 계산합니다 ( c+=2). (i,i) for i=1..n이것은를 제외하고 어느 것이 괜찮은지를 무시 (1,1)하므로 보상하기 위해 1( 1.0나중에 플로트 분할을 준비하기 위해) 카운터를 초기화하여 수정됩니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.