ตัวเลขที่สอดคล้องกัน


21

คำนิยาม:

  • สามเหลี่ยมนั้นถือเป็นสามเหลี่ยมมุมฉากหากมุมภายในมุมใดมุมหนึ่ง 90 องศา
  • จำนวนนั้นถือว่ามีเหตุผลถ้ามันสามารถแสดงโดยอัตราส่วนของจำนวนเต็มเช่นp/qที่ทั้งสองpและqเป็นจำนวนเต็ม
  • ตัวเลขnเป็นตัวเลขที่สอดคล้องกันหากมีพื้นที่สามเหลี่ยมมุมฉากอยู่nซึ่งทั้งสามด้านมีเหตุผล
  • นี่คือ OEIS A003273

ท้าทาย

นี่คือความท้าทายให้หมายเลขอินxพุทเอาท์พุทค่าที่ชัดเจนและสอดคล้องกันหากxเป็นจำนวนที่สมภาคกันและค่าที่แตกต่างและที่สอดคล้องกันแยกกันหากxไม่ใช่จำนวนที่สอดคล้องกัน ค่าเอาต์พุตไม่จำเป็นต้องเป็นความจริง / เท็จในภาษาของคุณ

กฎพิเศษ

สำหรับความท้าทายนี้คุณสามารถสันนิษฐานได้ว่าการคาดคะเนของเบิร์ชและสวินเนอร์ตัน - ไดเออร์เป็นเรื่องจริง หรือถ้าคุณสามารถพิสูจน์การคาดคะเนของเบิร์ชและสวินเนอร์ตัน - ไดเออร์ไปรับรางวัล 1,000,000 เหรียญสหรัฐ ;-)

ตัวอย่าง

(ใช้Trueสำหรับตัวเลขที่สอดคล้องกันและFalseอื่น ๆ )

5 True
6 True
108 False

กฎและคำชี้แจง

  • เข้าและส่งออกจะได้รับโดยวิธีการที่สะดวกใด
  • คุณสามารถพิมพ์ผลลัพธ์ไปที่ STDOUT หรือส่งคืนเป็นผลลัพธ์ของฟังก์ชัน โปรดระบุในการส่งของคุณว่าค่าที่ใช้สามารถส่งออก
  • ยอมรับได้ทั้งโปรแกรมหรือฟังก์ชั่น
  • ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม
  • นี่คือเพื่อให้ใช้กฎการเล่นกอล์ฟตามปกติทั้งหมดและรหัสที่สั้นที่สุด (เป็นไบต์) ชนะ

3
อินพุตเป็นจำนวนเต็มบวกหรือไม่
ลินน์

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

@ ซีอานโอเค แต่ความท้าทายควรอยู่ในตัวเอง
ลินน์

@Lynn ใช่อินพุตจะเป็นจำนวนเต็มบวก
AdmBorkBork

คำตอบ:


8

R, 179 173 142 141 137 135 134 ไบต์

การใช้อาร์กิวเมนต์เดียวกันตามทฤษฎีบทของ Tunnellจะส่งกลับค่า a 0ถ้าnไม่สอดคล้องกันและเป็น1อย่างอื่น (ใช้เวลานานพอสมควรที่จะมองเห็นข้อ จำกัด เกี่ยวกับเงื่อนไขที่ใช้กับจำนวนเต็มที่ไม่ต้องยกกำลังสอง )

function(n){b=(-n:n)^2
for(i in b^!!b)n=n/i^(!n%%i)
P=1+n%%2
o=outer
!sum(!o(y<-o(8/P*b,2*b,"+")/P-n,z<-16/P*b,"+"),-2*!o(y,4*z,"+"))}

ลองออนไลน์

การปรับปรุงที่นำโดยArnaudและGiuseppe (รหัสสุดท้ายคือ Guiseppe ส่วนใหญ่!) ด้วย -3 ขอบคุณRobin

การวิเคราะห์ไวยากรณ์:

for(i in b[b>0])n=n/i^(!n%%i) #eliminates all square divisors of n
P=2^(n%%2)                    #n odd (2) or even (1)
o=outer                       #saves 3 bytes 
o(8/P*b,2*b,"+")/P-n          #all sums of (8/P)x^2+(2/P)*y^2-n
o(...,16/P*b,"+")             #all sums of above and (16/P)*z^2
o(...,4*z,"+"))               #all sums of above and (64/P)*z^2
!o(...,4*z,"+"))              #all sums of above equal to zero
!sum(!...,2*!...)             #are zeroes twice one another (Tunnell)

กับทฤษฎีบทของ Tunnell ที่ระบุว่า n นั้นสอดคล้องกันถ้าจำนวนของการแก้ปัญหาจำนวนเต็มเป็น2x² + y² + 8z² = n เป็นสองเท่าของจำนวนวิธีการแก้ปัญหาจำนวนเต็มเป็น2x² + y² + 32z² = n ถ้า n เป็นเลขคี่และจำนวน การแก้ปัญหาจำนวนเต็มถึง8x² + y² + 16z² = n เท่ากับสองเท่าของจำนวนเต็ม Solutions ถึง8x² + y² + 64z² = n ถ้า n เป็นเลขคู่


1
ยินดีต้อนรับสู่ PPCG! เป้าหมายคือการสร้างรหัสให้สั้นที่สุด บางทีคุณอาจมองเหล่านี้เคล็ดลับสำหรับการเล่นกอล์ฟหรือเหล่านี้เคล็ดลับ R-ที่เฉพาะเจาะจง
จูเซปเป้

1
มีช่องว่างมากมายและฉันขอแนะนำให้รวมลิงก์ไปยังTry It Online! เพื่อช่วยยืนยันรหัสของคุณ :-)
จูเซปเป้

1
อย่าลังเลที่จะติดต่อในการแชทนักกอล์ฟ Rหากคุณต้องการ; คุณสามารถแจ้งได้โดยใช้@[username]... ฉันเดาว่าคุณถูกดึงเข้าสู่โค้ดกอล์ฟโดย Robin Ryder หรือไม่?
จูเซปเป้

1
142 ไบต์ - ฟังก์ชั่นนิรนามนั้นใช้ได้อย่างสมบูรณ์แบบและฉันสร้างสนามกอล์ฟอื่น ๆ ที่ฉันยินดีอธิบาย
Giuseppe

1
ดี! มีเหตุผลที่คุณใช้-n:nหรือไม่? ฉันไม่ได้อ่านทฤษฏีของ Tunnel แต่ดูเหมือนว่าสำหรับฉันn:0จะใช้งานได้ดีเช่นกันสำหรับ -1 ไบต์ ... นอกจากนี้เคล็ดลับโปรถ้าคุณกดปุ่ม "ลิงก์" ที่ด้านบนของ TIO คุณจะดีขึ้น รูปแบบสำหรับการคัดลอกและวางลงใน PPCG :-) แก้ไข: ฉันเห็นมีบางกรณีที่ใช้n:0ไม่ได้
Giuseppe

3

สนิม - 282 ไบต์

fn is(mut n:i64)->bool{let(mut v,p)=(vec![0;4],n as usize%2);while let Some(l)=(2..n).filter(|i|n%(i*i)==0).nth(0){n/=l*l;}for x in -n..=n{for y in -n..=n{for z in -n..=n{for i in 0..2{if n-6*x*x*(n+1)%2==2*x*x+(2-n%2)*(y*y+(24*i as i64+8)*z*z){v[2*p+i]+=1};}}}}v[2*p]==2*v[2*p+1]}
  • ใช้ทฤษฎีบทของJerrold B. Tunnellซึ่งฉันไม่เข้าใจจริง ๆ แต่ดูเหมือนว่าจะได้ผล
  • หาร n ด้วยปัจจัยสแควร์ทั้งหมด, เพื่อให้มัน 'ฟรีสแควร์', เนื่องจากในเอกสารด้านล่างทฤษฏีของ Tunnell อธิบายไว้สำหรับสแควร์อิสระเท่านั้น
    • ฉันเชื่อว่าสิ่งนี้อาจใช้งานได้เพราะทุกหมายเลขที่สอดคล้องกันเมื่อคูณด้วยสี่เหลี่ยมจะสร้างจำนวนที่สอดคล้องกันมากขึ้นและในทางกลับกัน ดังนั้นโดยการทดสอบจำนวนที่น้อยลงเราสามารถตรวจสอบขนาดที่ใหญ่กว่าซึ่งในกรณีของเราคือ n (สี่เหลี่ยมที่ถูกลบออกทั้งหมดสามารถคูณเข้าด้วยกันเพื่อสร้างหนึ่งสี่เหลี่ยมจัตุรัสใหญ่)
  • if n is odd, test if n = 2x2+y2+32z2 and/or 2x2+y2+8z2
    if n is even, test if n = 8x2+2y2+64z2 and/or 8x2+2y2+16z2
    • ในโค้ดตัวเองสมการทั้งสี่ได้ถูก smooshed เป็นหนึ่งในลูปโดยใช้โมดูโล่สำหรับคู่ / คี่
  • นับจำนวนของสมการที่ตรงกับ n
  • หลังจากวนลูปทดสอบอัตราส่วนของสิ่งที่นับ (ต่อ Tunnell)

ดูสิ่งนี้ด้วย:

แก้ไขแม้ / คี่ขอบคุณ @Level River St


1
โอ้ดีในเวลาที่ฉันทำงานนี้ฉันเห็นเพียงคำตอบ c ++ ซึ่งผิด ...
ดอน

ขอบคุณ Level River St
don bright

3

C ++ (gcc) , 251 234 ไบต์

ขอบคุณ @arnauld ที่ชี้ให้เห็นถึงความผิดพลาดในส่วนของฉัน

-17 ไบต์ขอบคุณ @ceilingcat

#import<cmath>
int a(int n){int s=sqrt(n),c,x=-s,y,z,i=1,X;for(;++i<n;)for(;n%(i*i)<1;n/=i*i);for(;x++<s;)for(y=-s;y++<s;)for(z=-s;z++<s;c+=n&1?2*(n==X+24*z*z)-(n==X):2*(n==4*x*x+2*X+48*z*z)-(n/2==2*x*x+X))X=2*x*x+y*y+8*z*z;return!c;}

ลองออนไลน์!

ส่งคืน 1 ถ้าnสอดคล้องกัน 0 เป็นอย่างอื่น

เนื่องจากเราสามารถสรุปได้ว่าการคาดคะเนของ Birch และ Swinnerton-Dyer นั้นเป็นจริงฉันใช้ทฤษฎีบทของ Tunnel เป็นบททดสอบ โปรดทราบว่าในทางเทคนิคจะต้องมีการทดสอบที่ไม่ใช่ศูนย์ x, y และ z เท่านั้นเนื่องจากชุดของค่าบวก (x, y, z) หมายถึงชุดเพิ่มเติมสำหรับแต่ละค่าเหล่านั้นเป็นค่าลบเนื่องจากตัวเลขทั้งสี่กำหนดให้ใช้จตุรัสของ x y และ z ในการคำนวณ นอกจากนี้เนื่องจากต้องการอัตราส่วนของตัวเลขสองตัวคือ A และ B หรือ C และ D เราจึงไม่จำเป็นต้องกังวลเกี่ยวกับเซ็ตอื่น ๆ เหล่านี้ ดังนั้นเราเพียงแค่ต้องเพิ่ม 2 สำหรับทุกวิธีแก้ปัญหาสำหรับ A หรือ C และลบ 1 สำหรับทุกวิธีแก้ปัญหาของ B หรือ D และตรวจสอบว่าเราลงท้ายด้วย 0 นอกจากนี้ข้อมูลจะถูกลดลงเป็นจำนวนเต็ม squarefree เพราะถ้าQ เป็นจำนวนที่สอดคล้องกันแล้ว s2Q ก็สอดคล้องกัน (อัลกอริทึมดูเหมือนว่าจะทำลายตัวเลขที่มีสแควร์


1
@ Arnauld: อานั่นเป็นคำที่พิมพ์ผิดในส่วนของฉัน คงที่
Neil A.

1

JavaScript (ES7), 165 ไบต์

เช่นเดียวกับคำตอบของ @ NeilA.นี่เป็นไปตามทฤษฎีบทของ Tunnellและสันนิษฐานว่าการคาดคะเนของ Birch และ Swinnerton-Dyer นั้นเป็นจริง

ส่งคืนค่าบูลีน

n=>(r=(g=i=>i<n?g(i+!(n%i**2?0:n/=i*i)):n**.5|0)(s=2),g=(C,k=r)=>k+r&&g(C,k-1,C(k*k)))(x=>g(y=>g(z=>s+=2*(n==(X=(n&1?2:8)*x+(o=2-n%2)*y)+o*32*z)-(n==X+o*8*z))))|s==2

ลองออนไลน์!

อย่างไร?

ก่อนอื่นเราแปลงอินพุต n เป็นคู่ฟรีสแควร์ของมัน n'คำนวณ R=n' และเริ่มต้น s ไปยัง 2.

r = (                // we will eventually save isqrt(n) into r
  g = i =>           // g = recursive function taking an integer i
    i < n ?          //   if i is less than n:
      g(i + !(       //     do a recursive call with either i or i + 1
        n % i**2 ?   //     if n is not divisible by i²:
          0          //       yield 0 and therefore increment i
        :            //     else:
          n /= i * i //       divide n by i² and leave i unchanged
      ))             //     end of recursive call
    :                //   else:
      n ** .5 | 0    //     stop recursion and return isqrt(n)
  )(s = 2)           // initial call to g with i = s = 2

จากนั้นเราจะกำหนดฟังก์ชั่นตัวช่วย ก. ซึ่งเรียกใช้ฟังก์ชันเรียกกลับ C กับ k2 สำหรับ -R<kR.

  g = (C, k = r) =>  // C = callback function, k = counter initialized to r
    k + r &&         //   if k is not equal to -r:
    g(               //     do a recursive call:
      C,             //       pass the callback function unchanged
      k - 1,         //       decrement k
      C(k * k)       //       invoke the callback function with k²
    )                //     end of recursive call

ในที่สุดเราก็ใช้การโทรซ้อน 3 ครั้ง ก. ที่จะเดินผ่านสามทั้งหมด (x,y,z)[r+1,r]3 and update s to test whether 2An=Bn if n is odd or 2Cn=Dn if n is even, with:

An=#{(x,y,z)[r+1,r]3n=2x2+y2+32z2}Bn=#{(x,y,z)[r+1,r]3n=2x2+y2+8z2}Cn=#{(x,y,z)[r+1,r]3n=8x2+2y2+64z2}Dn=#{(x,y,z)[r+1,r]3n=8x2+2y2+16z2}

g(x =>                            // for each x:      \    NB:
  g(y =>                          //   for each y:     >-- all these values are
    g(z =>                        //     for each z:  /    already squared by g
      s +=                        //       add to s:
        2 * (                     //         +2 if:
          n == (                  //           n is equal to either
            X =                   //           An if n is odd (o = 1)
            (n & 1 ? 2 : 8) * x + //           or Cn if n is even (o = 2)
            (o = 2 - n % 2) * y   //
          ) + o * 32 * z          //
        ) - (                     //         -1 if:
          n == X + o * 8 * z      //           n is equal to either
        )                         //           Bn if n is odd
    )                             //           or Dn if n is even
  )                               //
)                                 // if s in unchanged, then n is (assumed to be) congruent

1

Ruby, 126 bytes

->n{[8,32].product(*[(-n..-t=1).map{|i|i*=i;n%i<1&&n/=i;i}*2+[0]]*3).map{|j|d=2-n%2
k,x,y,z=j
2*d*x+y+k*z==n/d&&t+=k-16}
t==1}

Try it online!

found a place to initialize t=1 and expanded the list of squares into a triplet instead of using q to make additional copies.

Ruby, 129 bytes

->n{t=0
[8,32].product(q=(-n..-1).map{|i|i*=i;n%i<1&&n/=i;i}*2+[0],q,q).map{|j|d=2-n%2
k,x,y,z=j
2*d*x+y+k*z==n/d&&t+=k-16}
t==0}

Try it online!

Uses Tunnell's theorem like the other answers. I use a single equation as follows.

2*d*x^2 + y^2 + k*z^2 == n/d  where d=2 for even n and d=1 for odd n

We check the cases k=8 and k=32 and check if there are twice as many solutions for k=8 than k=32. This is done by adding k-16 to t every time we find a solution. This is either +16 in the case k=32 or -8 in the case k=8. Overall the number is congruent if t is the same as its initial value at the end of the function.

It is necessary to find all solutions to the test equation. I see many answers testing between +/-sqrt n. It is perfectly OK to test also outside these limits if it makes code shorter, but no solutions will be found because the left side of the equation will exceed n. The thing I missed in the beginning is that negative and positive x,y,z are considered separately. Thus -3,0,3 yields three squares 9,0,9 and all solutions must be counted separately (0 must be counted once and 9 must be counted twice.)

Ungolfed code

->n{t=0                              #counter for solutions

  q=(-n..-1).map{|i|i*=i;n%i<1&&n/=i #make n square free by dividing by -n^2 to -1^2 as necessary 
  i}*2+[0]                           #return an array of squares, duplicate for 1^2 to n^2, and add the case 0 

  [8,32].product(q,q,q).map{|j|      #make a cartesian product of all possible values for k,x,y,z and iterate
    d=2-n%2                          #d=1 for odd n, 2 for even n
    k,x,y,z=j                        #unpack j. k=8,32. x,y,z are the squared values from q.
    2*d*x+y+k*z==n/d&&t+=k-16}       #test if the current values of k,x,y,z are a valid solution. If so, adjust t by k-16 as explained above.
t==0}                                #return true if t is the same as its initial value. otherwise false.

about positive and negative solutions, same here, I wasted quite a while missing this point!
Xi'an
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.