Đồng nguyên thủy và số pi


23

Giới thiệu

Lý thuyết số đầy những điều kỳ diệu, dưới dạng kết nối bất ngờ. Đây là một trong số họ.

Hai số nguyên là đồng thủ nếu họ không có những yếu tố chung khác hơn 1. Cho một số N , xem xét tất cả các số nguyên từ 1 đến N . Vẽ hai số nguyên như vậy một cách ngẫu nhiên (tất cả các số nguyên có cùng xác suất được chọn trong mỗi lần rút; các lần rút là độc lập và có sự thay thế). Gọi p là xác suất để hai số nguyên được chọn là đồng nguyên tố. Khi đó p có xu hướng 6 / π 2 ≈ 0,6079 ... vì N có xu hướng vô cùng.

Các thách thức

Mục đích của thử thách này là để tính p là một hàm của N .

Ví dụ, xem xét N = 4. Có 16 cặp có thể thu được từ các số nguyên 1,2,3,4. 11 trong số các cặp đó là đồng nguyên tố, cụ thể là (1,1), (1,2), (1,3), (1,4), (2,1), (3,1), (4,1 ), (2,3), (3,2), (3,4), (4,3). Do đó p là 11/16 = 0,6875 cho N = 4.

Các chính xác giá trị của p cần phải được tính toán với ít nhất bốn thập phân. Điều này ngụ ý rằng việc tính toán phải mang tính quyết định (trái ngược với Monte Carlo). Nhưng nó không cần phải là một bảng liệt kê trực tiếp của tất cả các cặp như trên; bất kỳ phương pháp có thể được sử dụng.

Các đối số chức năng hoặc stdin / stdout có thể được sử dụng. Nếu hiển thị đầu ra, các số 0 ở cuối có thể được bỏ qua. Vì vậy, ví dụ 0.6300có thể được hiển thị như 0.63. Nó nên được hiển thị dưới dạng số thập phân, không phải là phân số (hiển thị chuỗi 63/100không được phép).

Tiêu chí chiến thắng là ít byte nhất. Không có hạn chế về việc sử dụng các chức năng tích hợp.

Các trường hợp thử nghiệm

Đầu vào / đầu ra (chỉ có bốn số thập phân là bắt buộc, như đã nêu ở trên):

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

Có bất kỳ giới hạn về phạm vi đầu vào?
Tháp Eric

@EricTowers Chương trình nên hoạt động với mọi kích thước hợp lý cho đến giới hạn của bộ nhớ và loại dữ liệu. Ít nhất 1000
Luis Mendo

Các số hữu tỷ là giá trị trả về (không phải chuỗi) được phép? Ngôn ngữ của tôi có một loại hợp lý bản địa, trong đó 63/100là một nghĩa đen hợp lệ, có thể sử dụng trong tính toán. (Langs tôi đang nói về: Yếu tố , vợt )
mèo

@cat Chắc chắn, đi tiếp! Tuy nhiên, hãy tính đến độ chính xác cần thiết
Luis Mendo

Câu trả lời:


14

Thạch , 12 8 byte

RÆṪSḤ’÷²

Hãy thử trực tuyến!

Mã nhị phân sau hoạt động với phiên bản trình thông dịch Jelly này .

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

Ý kiến

Rõ ràng, số cặp (j, k) sao cho j ≤ kjk là đồng nguyên tố bằng số cặp (k, j) thỏa mãn cùng điều kiện. Ngoài ra, nếu j = k , j = 1 = k .

Do đó, để đếm số cặp đồng nguyên tố có tọa độ từ 1 đến n , nó đủ để tính lượng m của các cặp (j, k) sao cho j ≤ k , sau đó tính 2m - 1 .

Cuối cùng, do hàm tổng của Euler φ (k) mang lại số nguyên nằm trong khoảng từ 1 đến k là đồng nguyên tố với k , nên chúng ta có thể tính mφ (1) + Lỗi + φ (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
Ồ, Jelly bao gồm chức năng toàn diện!? Ý kiến ​​hay!
Luis Mendo

2
Đếm ngược cho đến khi MATL bao gồm một lệnh toàn bộ tại T-1 ngày ...
quintopia

@quintopia (Cuối cùng tôi đã bao gồm hàm toàn phần) :-D
Luis Mendo

14

Toán học 43 42 byte

Tôi thấy các điểm Lattice có thể nhìn thấy từ điểm gốc , từ đó hình ảnh bên dưới được chụp, rất hữu ích trong việc xử lý vấn đề thông qua các câu hỏi sau đây liên quan đến một khu vực vuông của mạng đơn vị:

  • Phần nào của các điểm mạng đơn vị có tọa độ đồng nguyên tố?
  • Phần nào của các điểm mạng đơn vị có thể được nhìn thấy từ điểm gốc?

lưới điện


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

Ví dụ

Số không lưu trữ được bỏ qua.

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}


Thời gian

Thời gian, tính bằng giây, đi trước câu trả lời.

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

{0,605571, 0,608383}



6

Toán học, 42 32 byte

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

Chức năng ẩn danh, sử dụng lực lượng vũ phu đơn giản. Trường hợp cuối cùng chạy trong khoảng 0,37 giây trên máy của tôi. Giải trình:

                               &   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.

Bạn có thể đăng một ví dụ chạy và giải thích, cho những người trong chúng ta không có Mathicala không?
Luis Mendo

2
Điều này đoàn kết đệ trình của chúng tôi: Count[Array[GCD,{#, #}],1,2]/#^2.& Hãy là khách của tôi.
DavidC

4

APL Dyalog, 15 byte

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

Khá đơn giản. Đó là một tàu chức năng đơn nguyên. Iota là các số từ 1 đến đầu vào, vì vậy chúng tôi lấy sản phẩm bên ngoài bằng gcd, sau đó đếm tỷ lệ của các số đó.


3

Octave, 49 47 byte

Chỉ cần tính toán gcdcủa tất cả các cặp và đếm.

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

Các sản phẩm kronecker là tuyệt vời.


kron! Ý tưởng tốt!
Luis Mendo

Lần đầu tiên tôi sử dụng meshgrid, nhưng sau đó tôi nhận thấy tôi có thể làm tương tự với kronnội tuyến! (-> chức năng ẩn danh)
flawr

2

JavaScript (ES6), 88 byte

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

Giải trình

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

Kiểm tra

Mất một lúc cho các >100giá trị lớn ( ) của n.


2

Nghiêm túc, 15 byte

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

Bãi rác Hex:

2c3ba62975317860b1604de4e7442f

Dùng thử trực tuyến

Tôi sẽ không bận tâm giải thích về nó vì nó thực sự sử dụng thuật toán chính xác giống như giải pháp Jelly của Dennis (mặc dù tôi đã rút ra nó một cách độc lập).


2

J, 19 17 byte

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

Sử dụng:

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

Giải trình:

*:%~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

Giải pháp của Dennis đưa ra một lời giải thích hay về cách chúng ta có thể sử dụng hàm tổng.

Hãy thử trực tuyến tại đây.


2

Toán học, 35 byte

Triển khai thuật toán @ Dennis.

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

Tính tổng của tổng (hàm phi Euler) trong phạm vi từ 1 đến giá trị đầu vào. Nhân với dấu phẩy động hai (có bốn chữ số chính xác) và trừ đi một. (Có thể giữ lại độ chính xác cao hơn bằng cách sử dụng thay vì " 2" và " 1`4".) Đây là tổng số cặp đối ứng, do đó chia cho bình phương của đầu vào để có được phân số mong muốn. Bởi vì hai là một số gần đúng, kết quả cũng vậy.

Kiểm tra (với dữ liệu thời gian ở cột bên trái vì ít nhất một người trong chúng tôi nghĩ rằng điều đó thú vị), với chức năng được gán để fdòng kiểm tra dễ đọc hơn:

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

Chỉnh sửa: Hiển thị phạm vi phạm vi của các yếu tố đầu vào (hoán đổi độ chính xác thành một thay vì hai vì các kết quả trở nên khá đơn điệu) và thách thức những người khác làm điều tương tự ...

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[]thực hiện tính toán nhiều lần và mất trung bình số lần, cố gắng bỏ qua bộ đệm lạnh và các hiệu ứng khác gây ra các ngoại lệ về thời gian. Giới hạn tiệm cận là

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

vì vậy, đối với các đối số> 10 ^ 4, chúng ta có thể trả về "0,6079" và đáp ứng các yêu cầu về độ chính xác và độ chính xác đã chỉ định.


2

Julia, 95 byte

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

Chỉ là cách tiếp cận đơn giản cho bây giờ; Tôi sẽ xem xét các giải pháp ngắn hơn / thanh lịch hơn sớm. Đây là một hàm ẩn danh chấp nhận một số nguyên và trả về một số float. Để gọi nó, gán nó cho một biến.

Ung dung:

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

Theo như tôi có thể nói, bạn không cần phải có collectmột đối tượng lười biếng để lấy nó length.
mèo

@cat Bạn làm cho một số nơi lengthkhông có phương thức được xác định, đó là trường hợp ở đây cho các trình lặp kết hợp được lọc. Tương tự như vậy endofsẽ không hoạt động vì không có phương pháp cho loại đó getindex.
Alex A.


@cat rangekhông trả lại cùng loại đối tượng như combinations. Cái sau trả về một iterator qua các kết hợp là một kiểu riêng biệt không có lengthphương thức xác định . Xem tại đây . (Ngoài ra :cú pháp được ưu tiên hơn rangecho việc xây dựng phạm vi;))
Alex A.

2

Sage, 55 byte

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

Nhờ tính toán Sage mọi thứ một cách tượng trưng, ​​các vấn đề về epsilon và dấu phẩy động không tăng lên. Sự cân bằng là, để tuân theo quy tắc định dạng đầu ra, cần có một lệnh gọi bổ sung n()(hàm xấp xỉ thập phân).

Dùng thử trực tuyến


Rất đẹp! Dường như bạn đang sử dụng Sage khá thường xuyên gần đây :-)
Luis Mendo

@LuisMendo Sage là tuyệt vời và làm tất cả mọi thứ. Thật tuyệt khi sử dụng cho các thử thách dựa trên toán học vì nó có một thư viện dựng sẵn khổng lồ như Mathematica, nhưng cú pháp tốt hơn (nhờ a) không phải là Mathicala và b) được xây dựng trên Python).
Mego

2

MATL , 20 17 byte

Điều này sử dụng phiên bản hiện tại (5.0.0) của ngôn ngữ.

Cách tiếp cận dựa trên câu trả lời của @ flawr .

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

Chỉnh sửa (ngày 28 tháng 4 năm 2015) : Dùng thử trực tuyến! Sau khi câu trả lời này được đăng, chức năng Y)được đổi tên thành X:; liên kết bao gồm sự thay đổi đó.

Thí dụ

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

Giải trình

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

Câu trả lời cũ: 20 byte

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

Giải trình

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

Bạn có thể thậm chí ngắn hơn với một cách tiếp cận như cách tôi đã sử dụng trong quãng tám không?
flawr

Thật! Cảm ơn bạn! Ít hơn 3 byte. Bạn nên tự làm điều đó trong MATL :-)
Luis Mendo

Tôi đã cố gắng nếu nó không vượt quá giờ đi ngủ của tôi =)
flawr

1

PARI / GP , 25 byte

Làm cho hàm ẩn danh sẽ tiết kiệm được một byte, nhưng sau đó tôi phải sử dụng selflàm cho nó đắt hơn về tổng thể.

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

1

Yếu tố, 120 113 byte

Tôi đã dành thời gian chơi golf này và tôi không thể rút ngắn nó.

Bản dịch của: Julia .

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

Ví dụ chạy trên 5 trường hợp thử nghiệm đầu tiên (giá trị 1000 khiến nó đóng băng trình soạn thảo và tôi không thể bận tâm biên dịch một tệp thực thi ngay bây giờ):

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

Thêm một ví dụ có thể chạy?
Luis Mendo

1
@LuisMendo đã xong!
mèo

1

Samau , 12 byte

Tuyên bố miễn trừ trách nhiệm: Không cạnh tranh vì tôi đã cập nhật ngôn ngữ sau khi câu hỏi được đăng.

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

Hex dump (Samau sử dụng mã hóa CP737):

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

Sử dụng thuật toán tương tự như câu trả lời của Dennis trong Jelly.


0

Python2 / Pypy, 178 byte

Các xtập tin:

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

Đang chạy:

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

Mã đếm các cặp đồng nguyên tố (n,m) for m<nhai lần ( c+=2). Điều này bỏ qua (i,i) for i=1..ncái nào cũng được, ngoại trừ (1,1), do đó được sửa chữa bằng cách khởi tạo bộ đếm với 1( 1.0để chuẩn bị phân chia phao sau) để bù lại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.