Co-primality และหมายเลข pi


23

บทนำ

ทฤษฎีจำนวนเต็มไปด้วยสิ่งมหัศจรรย์ในรูปแบบของการเชื่อมต่อที่ไม่คาดคิด นี่คือหนึ่งในนั้น

สองจำนวนเต็มมีร่วมที่สำคัญถ้าพวกเขามีปัจจัยในการทั่วไปอื่น ๆ กว่า 1 รับจำนวนNพิจารณาจำนวนเต็มทั้งหมดตั้งแต่ 1 ถึงN วาดจำนวนเต็มสองจำนวนดังกล่าวโดยการสุ่ม (จำนวนเต็มทั้งหมดมีความน่าจะเป็นเหมือนกันในการเลือกที่การจับแต่ละครั้งการจับนั้นเป็นอิสระและมีการแทนที่) ให้pแทนความน่าจะเป็นที่จำนวนเต็มสองตัวเลือกนั้นเป็นค่าร่วม จากนั้นpจึงมีค่าเท่ากับ6 / π 2 ≈ 0.6079 ... เนื่องจากNมักจะไม่มีที่สิ้นสุด

ความท้าทาย

วัตถุประสงค์ของการท้าทายนี้คือการคำนวณPเป็นหน้าที่ของN

ยกตัวอย่างเช่นพิจารณาN = 4 มี 16 คู่ที่เป็นไปได้ที่ได้รับจากจำนวนเต็ม 1,2,3,4 11 คู่เหล่านี้เป็นคู่ที่สำคัญคือ (1,1), (1,2), (1,3), (1,4), (2,1), (3,1), (3,1) ), (2,3), (3,2), (3,4), (4,3) ดังนั้นpคือ 11/16 = 0.6875 สำหรับN = 4

แน่นอนค่าของหน้าจะต้องมีการคำนวณที่มีอย่างน้อยสี่ทศนิยม นี่ก็หมายความว่าการคำนวณจะต้องกำหนดไว้ (เมื่อเทียบกับ Monte Carlo) แต่มันไม่จำเป็นต้องเป็นการแจงนับโดยตรงของทุกคู่ดังกล่าวข้างต้น สามารถใช้วิธีการใดก็ได้

อาจใช้อาร์กิวเมนต์ของฟังก์ชันหรือ stdin / stdout หากแสดงผลลัพธ์ศูนย์อาจถูกละเว้น ดังนั้นสำหรับตัวอย่างเช่นสามารถแสดงผลเป็น0.6300 0.63มันควรจะแสดงเป็นตัวเลขทศนิยมไม่เป็นเศษส่วน ( 63/100ไม่อนุญาตให้แสดงสตริง)

เกณฑ์ที่ชนะคือไบต์ที่น้อยที่สุด ไม่มีข้อ จำกัด ในการใช้งานฟังก์ชั่นในตัว

กรณีทดสอบ

อินพุต / เอาต์พุต (บังคับให้มีเพียงสี่ทศนิยมเท่านั้นตามที่ระบุข้างต้น):

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

ขอบเขตของอินพุตมีขอบเขตหรือไม่?
Eric Towers

@EricTowers โปรแกรมควรทำงานในทุกขนาดที่เหมาะสมจนถึงข้อ จำกัด ของหน่วยความจำและชนิดข้อมูล อย่างน้อย 1,000
Luis Mendo ใน

ตัวเลขที่มีเหตุผลเป็นค่าส่งคืน (ไม่ใช่สตริง) ได้รับอนุญาตหรือไม่ ภาษาของฉันมีชนิดมีเหตุผลแบบเนทีฟซึ่ง63/100เป็นตัวอักษรที่ถูกต้องสามารถใช้ในการคำนวณได้ (Langs ฉันพูดคุยเกี่ยวกับ: ปัจจัย , แร็กเก็ต )
แมว

@cat แน่นอนไปเลย! คำนึงถึงความแม่นยำที่จำเป็นแม้ว่า
Luis Mendo

คำตอบ:


14

เจลลี่ , 12 8 ไบต์

RÆṪSḤ’÷²

ลองออนไลน์!

รหัสเลขฐานสองต่อไปนี้ทำงานร่วมกับล่าม Jelly รุ่นนี้ได้

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

ความคิด

เห็นได้ชัดว่าจำนวนคู่(j, k)เช่นที่j ≤ kและjและkเป็น co-prime เท่ากับจำนวนคู่(k, j)ที่ตรงตามเงื่อนไขเดียวกัน นอกจากนี้ถ้าJ = k , J = 1 = k

ดังนั้นการนับจำนวนของคู่ร่วมสำคัญกับพิกัดระหว่าง1และnก็พอเพียงที่จะคำนวณจำนวนเงินที่คู่(ญ, k)ดังกล่าวว่าเจ≤ kแล้วคำนวณ2m - 1

สุดท้ายตั้งแต่ออยเลอร์ totient ฟังก์ชันφ (k)อัตราผลตอบแทนจำนวนเต็มจำนวนระหว่างระหว่าง1และkที่มีร่วมที่สำคัญในการkเราสามารถคำนวณเมตรเป็นφ (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
โอ้ Jelly ได้รวมฟังก์ชั่น totient!? ความคิดดี!
Luis Mendo

2
นับถอยหลังจนกระทั่ง MATL รวมคำสั่ง totient ที่ T-1 วัน ...
quintopia

@quintopia (ในที่สุดฉันก็รวมฟังก์ชั่นโทเทิล) :-D
Luis Mendo

14

Mathematica 43 42 ไบต์

ฉันพบจุดขัดแตะที่มองเห็นได้จากจุดกำเนิดซึ่งใช้รูปภาพด้านล่างนี้เพื่อช่วยในการ reframing ปัญหาผ่านคำถามต่อไปนี้เกี่ยวกับพื้นที่สี่เหลี่ยมจัตุรัสที่กำหนดของโครงตาข่ายหน่วย:

  • เศษเล็กเศษน้อยของคะแนนหน่วยขัดแตะมีจุดร่วมที่สำคัญอย่างไร
  • เศษส่วนของหน่วยจุดขัดแตะสามารถมองเห็นได้จากจุดกำเนิด?

ตะแกรง


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

ตัวอย่าง

ละเว้นศูนย์ต่อท้าย

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

ฟังก์ชั่นนิรนามใช้กำลังดุร้ายอย่างง่าย เคสสุดท้ายใช้เวลาประมาณ 0.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=⍳∘.∨⍳

ตรงไปตรงมาสวย มันเป็นรถไฟฟังก์ชั่น monadic Iota คือตัวเลขตั้งแต่ 1 ถึงอินพุตดังนั้นเราจึงนำผลิตภัณฑ์ด้านนอกมาจาก gcd แล้วนับสัดส่วนของมัน


3

อ็อกเทฟ49 49ไบต์

เพียงแค่การคำนวณgcdของทุกคู่และการนับ

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

ผลิตภัณฑ์ kronecker นั้นยอดเยี่ยมมาก


kron! ความคิดที่ดี!
Luis Mendo

ครั้งแรกที่ฉันใช้meshgridแต่แล้วฉันสังเกตเห็นว่าฉันสามารถทำเช่นเดียวกันกับkroninline! (-> ฟังก์ชั่นที่ไม่ระบุตัวตน)
ข้อบกพร่อง

2

JavaScript (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

ลองใช้ออนไลน์

ฉันไม่อยากอธิบายเพราะมันใช้อัลกอริทึมแบบเดียวกับโซลูชัน 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

โซลูชันของเดนนิสให้คำอธิบายที่ดีว่าเราจะใช้ฟังก์ชั่น Totient ได้อย่างไร

ลองออนไลน์ได้ที่นี่


2

Mathematica, 35 ไบต์

ใช้อัลกอริทึมของ @ Dennis

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

คำนวณผลรวมของผลรวม (ฟังก์ชัน phi ของออยเลอร์) ในช่วงตั้งแต่ 1 ถึงค่าอินพุต ทวีคูณด้วยจำนวนจุดลอยตัวที่สอง (ด้วยความแม่นยำสี่หลัก) และลบออก (สามารถรักษาความแม่นยำได้มากขึ้นโดยใช้แทน " 2" และ " 1`4") นี่คือจำนวนคู่ coprime ทั้งหมดดังนั้นหารด้วยกำลังสองของอินพุตเพื่อให้ได้เศษส่วนที่ต้องการ เพราะทั้งสองเป็นจำนวนโดยประมาณผลลัพธ์ก็คือ

การทดสอบ (ด้วยข้อมูลเวลาในคอลัมน์ด้านซ้ายเนื่องจากเราอย่างน้อยหนึ่งคนคิดว่ามันน่าสนใจ) ด้วยฟังก์ชั่นที่กำหนดให้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[]ทำการคำนวณหลายครั้งและใช้เวลาเฉลี่ยพยายามที่จะไม่สนใจแคชเย็นและผลกระทบอื่น ๆ ที่ก่อให้เกิดค่าผิดปกติเวลา ขีด จำกัด asymptotic คือ

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

ดังนั้นสำหรับอาร์กิวเมนต์> 10 ^ 4 เราสามารถส่งคืน "0.6079" และตรงตามข้อกำหนดความแม่นยำและความแม่นยำที่ระบุ


2

Julia, 95 ไบต์

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

เพียงวิธีการตรงไปตรงมาสำหรับตอนนี้ ฉันจะดูโซลูชันที่สั้นลง / สวยงามมากขึ้นในไม่ช้า นี่คือฟังก์ชั่นที่ไม่ระบุชื่อที่รับจำนวนเต็มและส่งคืนค่าทศนิยม หากต้องการเรียกใช้กำหนดค่าให้กับตัวแปร

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

เท่าที่ผมสามารถบอกคุณไม่จำเป็นต้องเป็นวัตถุขี้เกียจที่จะใช้มันcollect length
แมว

@cat คุณlengthใช้วิธีที่ไม่มีวิธีกำหนดซึ่งเป็นกรณีสำหรับตัววนซ้ำตัวกรองที่กรองแล้ว ในทำนองเดียวกันendofจะไม่ทำงานเพราะไม่มีวิธีสำหรับประเภทgetindexนั้น
Alex A.


@cat ไม่กลับชนิดเดียวกันของวัตถุrange combinationsหลังส่งคืนตัววนซ้ำมากกว่าชุดค่าผสมซึ่งเป็นชนิดแยกต่างหากโดยไม่มีlengthวิธีที่กำหนดไว้ ดูที่นี่ (นอกจากนี้ยังมี:ไวยากรณ์ที่เป็นที่ต้องการมากกว่าrangeสำหรับการสร้างช่วง;))
อเล็กซ์ A.

2

Sage, 55 ไบต์

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

ด้วยการใช้คอมพิวเตอร์ Sage ที่เป็นสัญลักษณ์สัญลักษณ์ของ epsilon และประเด็นทศนิยมไม่ทำให้เกิดปัญหา tradeoff คือเพื่อให้เป็นไปตามกฎรูปแบบเอาต์พุตn()จำเป็นต้องมีการเรียกเพิ่มเติม(ฟังก์ชันการประมาณทศนิยม)

ลองออนไลน์


ดีมาก! ดูเหมือนว่าคุณจะใช้ Sage บ่อยครั้งเมื่อเร็ว ๆ นี้ :-)
Luis Mendo

@ LuisMendo Sage ยอดเยี่ยมและทำทุกสิ่ง มันดีมากที่จะใช้กับความท้าทายทางคณิตศาสตร์เพราะมีห้องสมุดขนาดใหญ่ในตัวเช่น Mathematica แต่ไวยากรณ์นั้นดีกว่า (โดยอาศัยก) ไม่ได้เป็น Mathematica และ b) ถูกสร้างขึ้นบน Python)
Mego

2

MATL , 20 17 ไบต์

สิ่งนี้ใช้เวอร์ชันปัจจุบัน (5.0.0)ของภาษา

วิธีการขึ้นอยู่กับคำตอบ @ flawr ของ

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

แก้ไข (28 เมษายน 2558) : ลองออนไลน์! หลังจากโพสต์คำตอบนี้แล้วฟังก์ชัน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

คุณสั้นลงหรือไม่ด้วยวิธีการเช่นเดียวกับที่ฉันเคยใช้ในระดับแปดเสียง?
ข้อบกพร่อง

แน่นอน! ขอขอบคุณ! น้อยกว่า 3 ไบต์ คุณควรทำด้วยตัวเองใน MATL :-)
Luis Mendo

ฉันจะลองถ้ามันไม่ได้ผ่านเวลานอนของฉัน =)
ข้อบกพร่อง

1

PARI / GPขนาด 25 ไบต์

การทำให้ฟังก์ชั่นไม่ระบุชื่อจะช่วยประหยัดไบต์ แต่ถ้าอย่างนั้นฉันต้องใช้selfมันทำให้ราคาโดยรวมแพงขึ้น

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

1

ตัวคูณ120 113 ไบต์

ฉันใช้เวลาเล่นกอล์ฟในชั้นนี้และฉันไม่สามารถทำให้สั้นลงได้

แปลของ: จูเลีย

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

ตัวอย่างทำงานกับ 5 กรณีทดสอบแรก (ค่า 1,000 ทำให้ตัวแก้ไขตรึงและฉันไม่สามารถใส่ใจในการคอมไพล์ปฏิบัติการได้ตอนนี้):

! 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 เสร็จแล้ว!
แมว

1

ซาเมา 12 ไบต์

ข้อจำกัดความรับผิดชอบ: ไม่แข่งขันเนื่องจากฉันอัปเดตภาษาหลังจากคำถามถูกโพสต์

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

Hex dump (Samau ใช้การเข้ารหัส CP737):

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

ใช้อัลกอริทึมเดียวกันกับคำตอบของเดนนิสในเยลลี่


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.