Dados dos números positivos x
y n
con x<2^n
, escriba la función más corta posible para calcular x^-1 mod 2^n
. En otras palabras, encuentre y
tal que x*y=1 mod 2^n
.
Su función debe completarse en un tiempo razonable al menos n=64
, por lo que una búsqueda exhaustiva no funcionará.
Si el inverso no existe, debe indicarlo al llamador de alguna manera (lanzar una excepción, devolver un valor centinela, etc.).
Si se pregunta por dónde comenzar, pruebe el Algoritmo Euclidiano Extendido .
Respuestas:
Python
9589c
es tu funcion Devuelve 0 si no hay inverso (es decir, cuando x es par).fuente
Python, 29 bytes
Esto devuelve 0 para incluso x . Utiliza el teorema de Euler, con la observación de que 2 ^ n - 1 es divisible por 2 ^ ( n - 1) - 1, a través de la exponenciación modular rápida incorporada de Python. Esto es lo suficientemente rápido para n hasta 7000 más o menos, donde comienza a tomar más de aproximadamente un segundo.
fuente
Mathematica - 22
f[x,n]
vuelvey
conx*y=1 mod 2^n
, de lo contrariox is not invertible modulo 2^n
fuente
GolfScript (23 caracteres)
El resultado centinela para un inverso inexistente es
0
.Esta es una aplicación simple del teorema de Euler . , entonces x - 1 ≡ x 2 n - 1 - 1xφ(2n)≡1(mod2n) x−1≡x2n−1−1(mod2n)
Desafortunadamente, es un exponencial demasiado grande para calcular directamente, por lo que tenemos que usar un bucle y hacer una reducción modular dentro del bucle. El paso iterativo es y tenemos una opción de caso base: ya sea conx2k−1=(x2k−1−1)2×x
k=1
o
k=2
conEstoy trabajando en otro enfoque, pero el centinela es más difícil.
La observación clave es que podemos construir el inverso hacia arriba poco a poco: sixy≡1(mod2k−1) xy∈{1,1+2k−1}(mod2k) x x(y+xy−1)≡1(mod2k) y′=(x+1)y−1
Eso le da la función de 19 caracteres
x&1
1
n x f
fuente
Ruby - 88 caracteres
Usa la función
f
.Simplemente la función recursiva de la página wiki vinculada, devuelve 0 en caso de error.
fuente
(e=->a,b{...})[x,2**n][0]
. También puede guardar un personaje probando ena%b<1
lugar dea%b==0
.Haskell, 42 bytes
Usando un algoritmo basado en el lema de Hensel que duplica el número de dígitos en cada iteración, ¡esto se ejecuta en menos de un segundo por n hasta aproximadamente 30 millones !
fuente
Pyth , 9 bytes
Pruébalo aquí!
Toma la entrada en orden inverso. O, 9 bytes demasiado:
.^EtK^2QK
.Explicación
fuente
GAP, 39 bytes
f(x,n)
devuelve el inverso delx
módulo2^n
y muestra un mensaje de errorsi no existe inversa
fuente