Помічник факторизації Ферма


19

Ми хотіли б факторізовать полупервічное . Мета цього завдання полягає в знаходженні два невеликих цілих чисел і такі , що UVN може бути розкладено тривіальним методом Ферма, що дозволяє легко відняти чинники N .NuvuvNN

Завдання

З огляду на полупервічное N і натуральне число k , ми визначимо x і y , як:

x=kN
y=x2kN

Крок №1 - Знайдіть k

Спочатку потрібно знайти найменше можливе значення k таке, щоб y - це квадратне число (він же ідеальний квадрат).

Це дозволяє розподілити kN за допомогою однієї ітерації методу факторизації Ферма . Більш конкретно, це негайно призводить до:

kN=(x+y)×(xy)

(Оновлення: ця послідовність тепер опублікована як A316780 )

Крок №2 - Розділити фактор k

Тоді вам доведеться знайти два цілих натуральних числа u і v такі, що:

c u = x +

uv=k
dv=x-
cu=x+y
dv=xy

де c і г є головними факторами N .

Підсумок

Ваше завдання - написати програму або функцію, яка приймає N як вхід, і друкує або виводить у і v у будь-якому порядку та будь-якому розумному форматі.

Приклад

Розглянемо N=199163

Крок 1

Найменше можливе значення к дорівнює 40 , що дає:

y=28232-40×199163=7969329-7966520=2809=532kN=(2823+53)×(2823-53)kN=2876×2770

х=(40×199163)=2823 рік
y=2823240×199163=79693297966520=2809=532
kN=(2823+53)×(282353)
kN=2876×2770

Крок №2

Правильна факторизація k дорівнює k=4×10 , оскільки:

kN=2876×2770
kN=(719×4)×(277×10)
N=719×277

Отже, правильною відповіддю буде або або .[4,10][10,4]

Правила

  • Не потрібно чітко застосовувати два описані вище кроки. Ви можете використовувати будь-який інший метод, якщо він знайде правильні значення і .уv
  • Ви повинні підтримувати всі значення до нативного максимального розміру непідписаного цілого числа на вашій мові.уvN
  • Гарантований вхід є напівпринтер.
  • Це код-гольф, тому найкоротша відповідь у байтах виграє.
  • Стандартні лазівки заборонені.

Тестові справи

N          | k    | Output
-----------+------+------------
143        | 1    | [   1,  1 ]
2519       | 19   | [   1, 19 ]
199163     | 40   | [   4, 10 ]
660713     | 1    | [   1,  1 ]
4690243    | 45   | [   9,  5 ]
11755703   | 80   | [  40,  2 ]
35021027   | 287  | [   7, 41 ]
75450611   | 429  | [ 143,  3 ]
806373439  | 176  | [   8, 22 ]
1355814601 | 561  | [  17, 33 ]
3626291857 | 77   | [   7, 11 ]
6149223463 | 255  | [  17, 15 ]
6330897721 | 3256 | [  74, 44 ]

Приклад реалізації

У фрагменті нижче функція - це нереалізована реалізація, яка приймає як вихідний і повертає і .fNуv

Для ілюстративних цілей фрагмент також включає функцію яка приймає , та як вхідні дані та обчислює коефіцієнти в .гNуvNО(1)


Ми гарантуємо, що вхід Nбуде насправді напівприміром?
Грег Мартін

@GregMartin Так.
Арнольд

Відповіді:


8

Математика, 81 79 байт

Дякуємо Мартіну Ендеру за збереження 2 байтів!

(c=Ceiling;For[j=0;z=E,c@z>z,p=(x=c@Sqrt[j+=#])+{z=Sqrt[x^2-j],-z}];p/#~GCD~p)&

Чиста функція, що приймає напівпримір як вхідний і повертає впорядковану пару натуральних чисел. В Forреалізує цикл точну процедуру , описану в питанні (використовуючи #для введення в місці n), з xтакими , як визначено тут, хоча ми зберігати , j = k*nа не kсам по собі , і z=Sqrt[y]замість того , yсаме по собі. Ми також обчислюємо p={x+z,x-z}всередині Forциклу, який закінчується збереженням одного байта (як, наприклад, сьома спроба). Тоді два бажаних чинника є (x+z)/GCD[#,x+z]і (x-z)/GCD[#,x-z], які стислий вираз p/#~GCD~pобчислює безпосередньо як упорядковану пару.

Цікавості: ми хочемо циклічити, поки zне буде ціле число; але оскільки ми будемо використовувати Ceilingвже в коді, він економить два байти, !IntegerQ@zщоб визначити c=Ceiling(що коштує чотири байти, як знають гольфісти Mathematica), а потім перевірити, чи c@z>z. Ми повинні ініціалізувати zщось, і щоб щось краще не було цілим числом, щоб цикл міг запускатися; на щастя, Eце стислий вибір.


4

JavaScript (ES7), 86 81 байт

n=>(g=k=>(y=(n*k)**.5+1|0,y+=(y*y-n*k)**.5)%1?g(k+1):n*u++%y?g(k):[--u,k/u])(u=1)

Редагувати: Збережено 4 байти завдяки @Arnauld.


4

Пітон 2, 127 121 117 111 107 104 101 99 байт

-1 байт завдяки Нілу та -3 байти завдяки ов

N=input()
k=u=1;p=m=.5
while p%1:p=1+(k*N)**m//1;p+=(p*p-k*N)**m;k+=1
while N*u%p:u+=1
print~-k/u,u

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

Цікавості:

pініціалізується .5так, щоб умова циклу була вірною на першій ітерації. Зверніть увагу , що вона коротше зберігати p(як x+ sqrt(y)) , ніж для зберігання кожного з xі по yокремо.


x*xзамість x**2?
Ніл

@Neil Так, звичайно. Спасибі
наркоман з математики

1

Аксіома, 131 115 байт

v(x)==floor(x^.5)::INT;r(n)==(k:=0;repeat(k:=k+1;x:=1+v(k*n);y:=v(x*x-k*n);x^2-y^2=k*n=>break);[w:=gcd(k,x+y),k/w])

Функція, яка б вирішила питання, є r (n) вище. ungolf і тест

vv(x)==floor(x^.5)::INT    

--(x-y)*(x+y)=k*n
rr(n)==
  k:=0
  repeat
     k:=k+1
     x:=1+vv(k*n)
     y:=vv(x*x-k*n)
     x^2-y^2=k*n=>break
  [w:=gcd(k,x+y),k/w]


(4) -> [[i,r(i)] for i in [143,2519,199163,660713,4690243,11755703]]
   (4)
   [[143,[1,1]], [2519,[1,19]], [199163,[4,10]], [660713,[1,1]],
    [4690243,[9,5]], [11755703,[40,2]]]
                                                      Type: List List Any
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.