Обчисліть модульну обернену


16

Враховуючи два додатних числа xі nс x<2^n, запишіть найкоротші можливі функції для обчислення x^-1 mod 2^n. Іншими словами, знайдіть yтаке x*y=1 mod 2^n.

Ваша функція повинна виконуватись у розумний час принаймні n=64, тому вичерпний пошук не працюватиме.

Якщо обернення не існує, ви повинні якось вказати на те, що викликає абонент (киньте виняток, поверніть дозорне значення тощо).

Якщо вам цікаво, з чого почати, спробуйте розширений евклідовий алгоритм .


це стане однією заявою в деяких програмних
засобах з

1
@ st0le: Правильно, і вам не дозволять використовувати таку функцію в таких системах. :-D
Кріс Єстер-Янг

Відповіді:


2

Пітон 95 89

cце ваша функція. Повертає 0, якщо немає зворотного (тобто коли х парне).

p=lambda x,y,m:y and p(x,y/2,m)**2*x**(y&1)%m or 1
c=lambda x,n:[0,p(x,2**n-1,2**n)][x%2]

3

Пітон, 29 байт

lambda x,n:pow(x,2**n-1,2**n)

Це повертає 0 для парного х . Він використовує теорему Ейлера із зауваженням, що 2 ^ n - 1 ділиться на 2 ^ ( n - 1) - 1, через вбудовану Пітоном швидку модульну експоненцію. Це досить швидко для n до 7000 або близько того, де воно починає більше приблизно секунди.


2

Математика - 22

f=PowerMod[#,-1,2^#2]&

f[x,n]повертається yз x*y=1 mod 2^n, інакшеx is not invertible modulo 2^n


2

GolfScript (23 символи)

{:^((1${\.**2^?%}+*}:f;

Результатом дозорного для неіснуючого зворотного є 0.

Це просте застосування теореми Ейлера . , тому x - 1x 2 n - 1 - 1xφ(2n)1(mod2н)х-1х2н-1-1(мод2н)

На жаль, це занадто великий показник прямого обчислення, тому нам доводиться використовувати цикл і робити модульне скорочення всередині циклу. Ітеративний крок і у нас є вибір базового випадку: або зх2к-1=(х2к-1-1)2×хk=1

{1\:^(@{\.**2^?%}+*}:f;

або k=2з

{:^((1${\.**2^?%}+*}:f;

Я працюю над іншим підходом, але дозорний складніше.

Ключове зауваження полягає в тому, що ми можемо побудувати обернутий біт на біт: якщо xy1(mod2k1)xy{1,1+2k1}(mod2k)xx(y+xy1)1(mod2k)y=(x+1)y1

0x1(mod20) we get, by induction

x(1(x+1)nx)1(mod2n)

де зворотною є сума геометричної послідовності. Я показав деривацію, щоб уникнути ефекту кролика з капелюхом: враховуючи цей вираз, легко зрозуміти, що (враховуючи, що скорбоване значення є цілим числом, що випливає з його виведення як суми цілого числа послідовність) продукт зліва повинен бути у правій клаві еквівалентності, якщох+1 рівномірний.

Це дає 19-знакову функцію

{1$)1$?@/~)2@?%}:f;

що дає правильні відповіді на входи, які мають зворотну. Однак коли це не так простохрівномірний. Один з потенційно цікавих варіантів, які я знайшов - це додати, x&1а не 1.

{1$.1&+1$?@/~)2@?%}:f;

Це, здається, дає дозорні значення будь-якого 0 або 2н-1, але я ще цього не довів.

Зробивши цей крок далі, ми можемо забезпечити дозорну службу 0 для парних чисел, змінюючи вираз 1-(х+1)н в 1-1н:

{1$.1&*)1$?@/~)2@?%}:f;

Це пов'язане з прямим застосуванням теореми Ейлера для довжини коду, але буде мати гірші показники для великих н. Якщо взяти аргументи навпаки n x f, ми можемо зберегти один символ і дістатися до 22 символів :

{..1&*)2$?\/~)2@?%}:f;

1

Рубі - 88 символів

Використовуйте функцію f.

def e a,b;a%b==0?[0,1]:(x,y=e(b,a%b);[y,x-(y*(a/b))])end
def f x,n;e(x,2**n)[0]*(x%2)end

Просто рекурсивна функція із пов’язаної сторінки wiki, повертає 0 за помилкою.


Ви можете зберегти деякі символи за допомогою вставки "e:" (e=->a,b{...})[x,2**n][0]. Можна також зберегти персонаж, тестуючи a%b<1замість a%b==0.
гістократ


1

Pyth , 9 байт

.^Et^2Q^2

Спробуйте тут!

Вводиться в зворотному порядку. Або, 9 байт теж: .^EtK^2QK.

Пояснення

. ^ Et ^ 2Q ^ 2 - Повна програма.

. ^ - функція Pow. Те саме в Python (pow).
  E - Другий вхід.
    ^ 2Q - І 2 ^ перший вхід.
   t - зменшено.
       ^ 2 - І 2 ^ перший вхід знову.

0

GAP, 39 байт

f:=function(x,n)return 1/x mod 2^n;end;

f(x,n)повертає інверсію xмодуля 2^nі подає повідомлення про помилку

Error, ModRat: for <r>/<s> mod <n>, <s>/gcd(<r>,<s>) and <n> must be coprime

якщо немає зворотного

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