Помощник по факторизации Ферма


19

Мы хотели бы факторизовать полупервичное . Цель этой задачи состоит в нахождении два небольших целых чисел и такие , что может быть разложено тривиальным методом Ферма, что позволяет легко вычесть факторы .у v U v N NNuvuvNN

Задание

Для заданного полупростого числа и положительного целого числа мы определяем и как:к х уNkxy

y=x2-kN

x=kN
y=x2kN

Шаг № 1 - Найтиk

Сначала вам нужно найти наименьшее возможное значение такое что - это квадратное число ( или идеальный квадрат).уky

Это позволяет факторизовать за одну итерацию метода факторизации Ферма . Конкретнее, это сразу приводит к:kN

kN=(x+y)×(xy)

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

Шаг № 2 - Факторизоватьk

Затем вы должны найти два положительных целых числа и такие что:vuv

c u = x +

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

где и являются главными факторами .d NcdN

Резюме

Ваша задача - написать программу или функцию, которая принимает качестве входных данных и печатает или выводит и в любом порядке и в любом разумном формате.u vNuv

пример

Давайте рассмотримN=199163

Шаг 1

Наименьшее возможное значение составляет , что дает:40k40

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

x=(40×199163)=2823
y=2823240×199163=79693297966520=2809=532
kN=(2823+53)×(282353)
kN=2876×2770

Шаг 2

Правильная факторизация равна , потому что:k = 4 × 10kk=4×10

k N = ( 719 × 4 ) × ( 277 × 10 ) N = 719 × 277

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

Таким образом, правильный ответ будет либо либо .[ 10 , 4 ][4,10][10,4]

правила

  • Не обязательно строго применять два шага, описанных выше. Вы можете использовать любой другой метод, если он находит правильные значения и .vuv
  • uvN
  • Вход гарантированно будет полупростым.
  • Это код-гольф, поэтому выигрывает самый короткий ответ в байтах.
  • Стандартные лазейки запрещены.

Контрольные примеры

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 ]

Пример реализации

fNuv

gNuvNO(1)


Гарантируем ли мы, что на Nсамом деле вход будет полупростым?
Грег Мартин

@GregMartin Да, ты.
Арно

Ответы:


8

Mathematica, 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

Python 2, 127 121 117 111 107 104 101 99 байт

-1 байт благодаря Нейлу и -3 байта благодаря ovs

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) выше. разгрызть и проверить

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.