Конгрунтні числа


21

Визначення:

  • Трикутником вважається правильний трикутник якщо один із внутрішніх кутів рівно 90 градусів.
  • Число вважається раціональним, якщо його можна представити співвідношенням цілих чисел, тобто p/q, де і pіq є цілими числами.
  • Число n- це конгруентне число, якщо існує правильний трикутник площіn де всі три сторони раціональні.
  • Це OEIS A003273 .

Виклик

Це виклик вирішення. Враховуючи вхідне число, xвиведіть чітке і послідовне значення, якщо xце відповідне число, і окреме чітке і послідовне значення, якщоx не є збіжним числом. Вихідні значення не обов'язково повинні бути truthy / falsey у вашій мові.

Спеціальне правило

Для цілей цього виклику можна припустити, що гіпота Берези та Свіннертона-Дайера є правдою. Крім того, якщо ви зможете довести гіпотезу Берези та Свіннертона-Дайєра, вимагайте отримати премію в тисячі тисяч доларів США. ;-)

Приклади

(Використовується Trueдля конгруентних чисел та Falseінше).

5 True
6 True
108 False

Правила та уточнення

  • Введення та вихід можуть бути надані будь-яким зручним методом .
  • Ви можете роздрукувати результат в STDOUT або повернути його як результат функції. Будь ласка, вкажіть у своєму поданні, які значення може приймати результат.
  • Прийнятна або повна програма, або функція.
  • Стандартні лазівки заборонені.
  • Це тому застосовуються всі звичайні правила гольфу, і найкоротший код (у байтах) виграє.

3
Чи є вхідне ціле число?
Лінн

Мій початковий підхід полягав у тому, щоб помножити вхід на довільне квадратне число, поки воно не стане половиною добутку ніжки в піфагорійській трійці, але потім я зрозумів, що може бути трохи важко насправді закінчити для неконгруентного введення.
Непов’язана струна

@ Xi'an Добре, але виклики повинні бути самостійними.
Лінн

@Lynn Так, вхід буде цілим числом.
AdmBorkBork

Відповіді:


8

R, 179 173 142 141 137 135 134 134 байт

Використовуючи ті ж аргументи, що базуються на теоремі Туннела , повертає 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,"+"))}

Спробуйте в Інтернеті

Покращення, які принесли Арно та Джузеппе (остаточний код - це в основному Гізєппе!), З -3 завдяки Робіну

Аналіз синтаксису:

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)

з теоремою Туннелла, що стверджує, що n є конгруентним тоді і лише тоді, коли число цілих розв’язків до 2x² + y² + 8z² = n вдвічі більше, ніж кількість цілих розв’язків до 2x² + y² + 32z² = n, якщо n непарне і число цілих розв’язків до 8x² + y² + 16z² = n вдвічі більше, ніж кількість цілих розв’язків до 8x² + y² + 64z² = n, якщо n парне.


1
Ласкаво просимо до PPCG! Мета - зробити код якомога коротшим. Можливо, ви можете ознайомитись із цими порадами щодо гольфу або цими R-підказками .
Джузеппе

1
Пробілів багато, а також рекомендую включити посилання, щоб спробувати його в Інтернеті! щоб підтвердити свій код :-)
Джузеппе

1
Не соромтесь зайти і в чат гольфіста R, якщо хочете; Ви можете попередити, використовуючи @[username]... Я здогадуюсь, що Ви потрапили в гольф коду від Робіна Райдера ??
Джузеппе

1
142 байти - анонімні функції ідеально добре, і я зробив кілька інших гольфів, які я із задоволенням пояснюю
Джузеппе

1
Приємно! Чи є причина, яку ви використовуєте -n:n? Я не читав теорему Тунеля, але мені здається, що n:0це спрацювало б так само на -1 байт ... Крім того, підказка, якщо натиснути кнопку "посилання" у верхній частині TIO, ви отримаєте приємне формати для копіювання та вставлення в PPCG :-) EDIT: Я бачу, є випадки, коли n:0це не працює.
Джузеппе

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]}
  • Використовуйте теорему Джерольда Б. Туннелла , яку я насправді не розумію, але, здається, все одно працює.
  • розділимо n на всі його квадратні коефіцієнти, щоб зробити його «квадратом вільним», оскільки в статтях нижче теорема Туннела описана лише для квадратних вільних.
    • Я вважаю, що це може спрацювати, тому що кожне збіжне число, помножене на квадрат, створює більшу відповідне число, і навпаки. тому, випробувавши меншу кількість, ми можемо перевірити більшу, яка в нашому випадку дорівнює n. (всі вилучені квадрати можна помножити разом, щоб вийшов один великий квадрат).
  • проведіть через усі можливі комбінації цілих чисел x, y, z, випробуйте рівняння Tunnell:
    if n is odd, test if n = 2x2+y2+32z2 and/or 2x2+y2+8z2
    if n is even, test if n = 8х2+2у2+64z2 та / або 8х2+2у2+16z2
    • у самому коді чотири рівняння згладжені в одне, всередині циклу, використовуючи модуль для парного / непарного
  • дотримуйтесь підрахунку рівнянь, рівних n
  • після циклу тестуйте співвідношення талі (за Tunnell)

Дивись також:

виправлено парне / дивне, спасибі @Level River St


1
Ну добре, на той момент, коли я працював, я бачив лише відповідь c ++, яка була неправильною ...
Дон яскраво

дякую Рівне Річка Св
нехай яскравий

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 - інакше.

qs2q також є конгруентним (алгоритм, здається, розбивається на деякі квадратно-містять числа.


1
@Arnauld: ах, це був друкарський помилок з мого боку. фіксований.
Ніл А.

1

JavaScript (ES7), 165 байт

Дуже схожа на відповідь @ NeilA , Це засновано на теоремі Туннелла, і тому припускає, що гіпотеза Берези та Свіннертона-Дайера є правдивою.

Повертає булеве значення.

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

Спробуйте в Інтернеті!

Як?

nnr=ns2

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

gCk2r<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

g(x,y,z)[r+1,r]3s2An=Bnn2Cn=Dnn

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

Рубін , 126 байт

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

Спробуйте в Інтернеті!

знайшов місце для ініціалізації t=1та розширив список квадратів у триплеті замість того, qщоб використовувати додаткові копії.

Рубін , 129 байт

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

Спробуйте в Інтернеті!

Використовує теорему Туннеля, як і інші відповіді. Я використовую єдине рівняння наступним чином.

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

Ми перевіряємо справи k=8і k=32перевіряємо, чи є вдвічі більше рішень для, k=8ніж k=32. Це робиться шляхом додавання k-16в tкожен раз , коли ми знаходимо рішення. Це або +16 у випадку, k=32або -8 у випадку k=8. Загалом, число є збіжним, якщо tвоно є таким, як його початкове значення в кінці функції.

Необхідно знайти всі рішення тестового рівняння. Я бачу багато тестування відповідей між +/- sqrt n. Цілком нормально тестувати і за межами цих меж, якщо це робить код коротшим, але рішення не знайдеться, оскільки ліва частина рівняння перевищить n. Що я пропустив на початку, це те, що негативне та позитивне x,y,zрозглядаються окремо. Таким чином, -3,0,3виходить три квадрати, 9,0,9і всі розв’язки потрібно рахувати окремо (0 потрібно рахувати один раз і 9рахувати двічі).

Невикористаний код

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

про позитивні та негативні рішення, те саме тут, я даремно пропустив цей момент!
Сіань
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.