Eş ilklülük ve pi sayısı


23

Giriş

Sayı teorisi beklenmedik bağlantılar şeklinde mucizelerle doludur. İşte onlardan biri.

İki tam sayılardır eş asal bir sayı Verilen 1 dışında ortak hiçbir faktörleri varsa N , 1'den tüm tamsayılar dikkate N . Bu gibi iki tamsayı rastgele çizin (tüm tamsayılar her bir çekilişte seçilme olasılığına sahiptir; çizimler bağımsız ve değişimlidir). Let s iki seçilmiş tamsayılar eş asal olduğu olasılığını belirtir. Sonra p 6 / eğilimi π 2 ≈ 0.6079 ... olarak , N sonsuza eğilimindedir.

Meydan okuma

Bu zorluğun amacı, p'yi N'nin bir fonksiyonu olarak hesaplamaktır .

Örnek olarak, N = 4 düşünün . 1,2,3,4 tam sayılarından elde edilen 16 olası çift vardır. Bu çiftlerin 11'i eş-asil, yani (1,1), (1,2), (1,3), (1,4), (2,1), (3,1), (4,1) ), (2,3), (3,2), (3,4), (4,3). Böylece , N = 4 için p 11/16 = 0.6875'tir .

Tam değeri p en az hesaplanabilmektedir gereken dört ondalık. Bu, hesaplamanın deterministik olması gerektiği anlamına gelir (Monte Carlo'nın aksine). Ancak, yukarıdaki gibi tüm çiftlerin doğrudan numaralandırılması gerekmez; herhangi bir yöntem kullanılabilir.

İşlev argümanları veya stdin / stdout kullanılabilir. Çıktı gösteriliyorsa, izleyen sıfırlar ihmal edilebilir. Yani örneğin 0.6300olarak görüntülenebilir 0.63. Ondalık bir sayı olarak gösterilmelidir, kesir olarak değil (dizenin görüntülenmesine 63/100izin verilmez).

Kazanan kriter en az bayttır. Yerleşik işlevlerin kullanımıyla ilgili herhangi bir kısıtlama yoktur.

Test durumları

Giriş / çıkış (yukarıda belirtildiği gibi yalnızca dört ondalık basamak zorunludur):

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

Giriş aralığında herhangi bir sınır var mı?
Eric Towers

@EricTowers Program, bellek ve veri türünün sınırlamalarına kadar makul boyutlarda çalışmalıdır. En az 1000
Luis Mendo

Dönen değerler (dizge değil) rasyonel sayılara izin verilir mi? 63/100Dilim, hesaplamada kullanılabilen geçerli bir değişmez olan yerel bir rasyonel tipe sahip . (Langs Bahsettiğim: Faktör , Raket )
kedi

@cat Tabii, devam et! Gerektiğinde, gerekli hassasiyeti göz önünde bulundurun
Luis Mendo,

Yanıtlar:


14

Jöle , 12 8 bayt

RÆṪSḤ’÷²

Çevrimiçi deneyin!

Aşağıdaki ikili kod Jelly yorumlayıcısının bu versiyonuyla çalışır .

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

Fikir

Açıktır ki, çiftlerinin sayısı (j, k) , öyle ki j ≤ k ve j ve k olan eş asal çiftlerinin sayısına eşit olduğu (k, j) aynı şartlar yerine getirilmiş olur. Ayrıca, eğer j = k ise , j = 1 = k .

Bu nedenle, 1 ile n arasındaki koordinatlara sahip eş çift sayısının sayılması için , çiftlerin m (j, k) miktarını hesaplamak yeterlidir , öyle ki j ≤ k , sonra 2m - 1 hesaplar .

Totient beri Nihayet, φ (k) arasındaki sayı tam sayıları verir , 1 ve k ko-asal şunlardır k , biz hesaplayabilirsiniz m olarak cp (1) + ... + φ (n) .

kod

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
Ah, Jelly iksir işlevi içerir! İyi fikir!
Luis Mendo

2
MATL, T-1 gününde bir titiz komut verene kadar geri sayım ...
quintopia

@quintopia (sonunda iltifat işlevini dahil ettim) :-D
Luis Mendo

14

Mathematica 43 42 bayt

Buldum Kafes kökenli görülebilen işaret aşağıdaki resim birim kafes belirli bir kare bölge ile ilgili aşağıdaki sorular ile sorunu reframing yardımcı olmak için, alındığı,:

  • Birim-kafes noktalarının hangi kısmı eş-eş koordinatlara sahiptir?
  • Ünite-kafes noktalarının hangi kısmı orijinden görülebilir?

Kafes


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

Örnekler

Sondaki sıfırlar atlandı.

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}


Zamanlama

Zamanlama, saniye cinsinden cevaptan önce gelir.

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

{0.605571, 0.608383)



6

Mathematica, 42 32 bayt

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

Anonim işlev, basit kaba kuvvet kullanır. Son dava makinemde yaklaşık 37 saniye sürüyor. Açıklama:

                               &   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 sahibi olmayanlarımız için bir örnek koşu ve açıklama gönderebilir misiniz?
Luis Mendo

2
Bu, önerilerimizi birleştiriyor: Count[Array[GCD,{#, #}],1,2]/#^2.& Benim konuğum ol.
DavidC

4

Dyalog APL, 15 bayt

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

Oldukça basit. Bu bir monadik fonksiyon treni. Iota, 1'den girişe kadar olan sayılardır, bu yüzden dış ürünü gcd ile alırız, sonra bunların oranını sayarız.


3

Octave, 49 47 bayt

Sadece gcdtüm çiftlerin hesaplanması ve sayılması.

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

Kronecker ürünü harika.


kron! İyi bir fikir!
Luis Mendo

İlk önce kullandım meshgridama sonra kronsatır içi ile aynı şeyi yapabileceğimi fark ettim ! (-> anonim işlev)
kusur,

2

JavaScript (ES6), 88 bayt

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

açıklama

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

Ölçek

İçin büyük ( >100) değerler biraz zaman alır n.


2

Cidden, 15 bayt

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

Hex Dump:

2c3ba62975317860b1604de4e7442f

Çevrimiçi Deneyin

Kelimenin tam anlamıyla Dennis'in Jelly çözümü ile tam olarak aynı algoritmayı kullandığı için açıklamaktan rahatsız olmayacağım (bağımsız olarak türetmiş olmama rağmen).


2

J, 19 17 bayt

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

Kullanımı:

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

Açıklama:

*:%~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'in çözümü , totient işlevini nasıl kullanabileceğimize dair güzel bir açıklama sunar.

Burada çevrimiçi deneyin.


2

Mathematica, 35 bayt

@ Dennis'in algoritmasını uygular.

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

Ttientin (Euler phi fonksiyonu) toplamını 1'den giriş değerine kadar hesaplayın. Kayan nokta iki ile çarpın (dört basamaklı hassasiyetle) ve birini çıkarın. (Bunun yerine " 2" ve " 1`4" kullanılarak daha fazla hassasiyet korunur .) Bu, toplam koprime çifti sayısıdır, bu nedenle istenen kesri elde etmek için girişin karesine bölün. İkisi yaklaşık bir sayı olduğundan, sonuç da böyledir.

Test (en azından birimiz bunun ilginç olduğunu düşündüğü için sol sütundaki zamanlama verileriyle), atanan fonksiyonla ftest çizgisi daha kolay okunur:

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

Düzenleme: Girdi aralığının kapsamını gösterme (kesinliği ikisi yerine bire çevirme çünkü sonuçta monoton olur) ve diğerlerini de aynı şekilde yapmalarını ...

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[]hesaplamayı birkaç kez gerçekleştirir ve soğuk önbellekleri ve zamanlama aykırı değerlerine neden olan diğer efektleri göz ardı etmeye çalışarak, ortalama süreleri alır. Asimptotik sınır

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

bu yüzden> 10 ^ 4 argümanları için, sadece "0.6079" u geri getirebilir ve belirtilen hassasiyet ve doğruluk gereksinimlerini karşılayabiliriz.


2

Julia, 95 bayt

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

Şimdilik sadece basit yaklaşım; Yakında daha kısa / daha zarif çözümlere bakacağım. Bu bir tamsayı kabul eden ve bir şamandıra döndüren adsız bir işlevdir. Aramak için değişkene atayın.

Ungolfed:

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

Söyleyebileceğim kadarıyla, onu almak collectiçin tembel bir nesneye ihtiyacınız yok length.
kedi

@ cat Bazıları için burada lengthtanımlanmış bir yöntemin olmadığı, burada filtre uygulanmış kombinasyonlar yineleyici için geçerli olduğu durum var. Benzer şekilde endofişe yaramaz çünkü bu tip için hiçbir yöntem yoktur getindex.
Alex A.


@ cat rangeaynı nesneyi döndürmez combinations. Sonuncusu, tanımlanmış bir lengthyöntemi olmayan ayrı bir tür olan kombinasyonlar üzerinden bir yineleyici döndürür . Buraya bakınız . (Ayrıca, :sözdizimi, rangearalıkları oluşturmak için tercih edilir ;))
Alex A.

2

Adaçayı, 55 bayt

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

Her şeyi sembolik olarak hesaplayan Sage sayesinde, makine epsilon ve kayan nokta sorunları ortaya çıkmıyor. Tradeoff, çıktı format kuralını takip etmek için ek bir çağrıya n()(ondalık yaklaşma fonksiyonu) ihtiyaç duyulur.

Çevrimiçi deneyin


Çok hoş! Son zamanlarda Sage'i oldukça sık kullanıyor gibisin :-)
Luis Mendo

@LuisMendo Sage harika ve her şeyi yapıyor. Matematik temelli zorluklarda kullanmak çok güzel çünkü Mathematica gibi büyük bir yerleşik kütüphaneye sahip, ancak sözdizimi (a) nedeniyle Mathematica olmamak ve b) Python üzerine inşa edilmek daha iyidir.
Mego,

2

MATL , 20 17 bayt

Bu dilin geçerli sürümünü (5.0.0) kullanır .

@ Kusurunun cevabına dayanan yaklaşım .

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

Düzenleme (28.04.2015) : Çevrimiçi deneyin! Bu cevap gönderildikten sonra, fonksiyonun Y)ismi değiştirildi X:; bağlantı bu değişikliği içerir.

Örnek

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

açıklama

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

Eski cevap: 20 bayt

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

açıklama

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

Oktavda kullandığım gibi bir yaklaşımla daha kısa olamaz mıydınız?
kusur,

Aslında! Teşekkür ederim! 3 bayt daha az. Kendin yapmalısın MATL :-)
Luis Mendo


1

PARI / GP , 25 bayt

İşlevi anonim yapmak bir bayttan tasarruf sağlar, ancak daha sonra selfgenel olarak daha pahalı hale getirmek için kullanmak zorunda kalırdım .

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

1

Faktör, 120 113 bayt

Bunu golf oynamak için harcadım ve daha kısa süremiyorum.

Tercüme: Julia .

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

Örnek ilk 5 test senaryosunda çalışır (1000 değeri editörün donmasına neden olur ve şu anda çalıştırılabilir bir dosyayı derlemek için can atıyorum):

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

Bir örnek run belki olabilir?
Luis Mendo

1
@LuisMendo bitti!
kedi

1

Samau , 12 bayt

Sorumluluk reddi: Soru gönderildikten sonra dili güncellediğim için rekabet yok.

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

Hex dökümü (Samau, CP737 kodlamasını kullanır):

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

Jelly’in Dennis’in cevabıyla aynı algoritmayı kullanmak.


0

Python2 / Pypy, 178 bayt

xdosya:

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

Koşu:

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

Kod, eş asal çiftleri (n,m) for m<niki kez sayar ( c+=2). Bunun (i,i) for i=1..ndışında tamam olan bu görmezden gelir (1,1), bu sayede telafi etmek üzere sayacı 1( 1.0daha sonra yüzer bölmeye hazırlanmak için) ile başlatarak düzeltilir .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.