2016-05-02 1 views
4

для заданных x, мне нужно вычислить минимальную n, который приравнивает верно для формулы 10^n ≡ 1 (mod 9x)Как искать минимальный п, что 10^п ≡ 1 модам (ая) для данных х

Моего алгоритм прост. Для i = 1 to inf, я петлю, пока не получаю результат. Всегда есть результат, если gcd(10, x) = 1. Между тем, если я не получу результата, я увеличиваю i на 1.

Это очень медленно для больших чисел или чисел с факторизацией больших значений, поэтому я спрашиваю, есть ли другой способ рассчитать его быстрее. Я пробовал с потоками, получая каждый поток следующим 10^i для расчета. Производительность немного лучше, но большие штрихи все еще не заканчиваются.

+0

Вы можете избежать НОДА/модуля расчета на каждая итерация, вычисляя '10^(n + 1)% 9x' в терминах' 10^n% 9x'. –

+0

Если вы делаете расчет mod 9x, это не должно быть медленным. Btw. Каков типичный размер 'x'? – Henry

+0

@OliverCharlesworth Я избегаю GCD, потому что я никогда не передаю свой алгоритм число с делителями 2 или 5. –

ответ

1

Я просто попытался пример, он работает менее чем за одну секунду:

public class Main { 

    public static void main(String[] args) { 
     int n = 1; 
     int x = 954661; 
     int v = 10; 
     while (v != 1) { 
      n++; 
      v = (v * 10) % (9*x); 
     } 
     System.out.println(n); 
    } 
} 

При больших значениях x переменные должны быть типа long.

+0

Да, я тоже получил этот результат. Попробуйте с 'x = 58630544' –

+0

Извините, для' x = 3664409 (= 58630544/16) ' –

+0

Примечание: Мне нужно работать с BigIntegers, потому что' v' легко переполняется 2^31, а также 2^63 в случае «длинный». –

-3

Как вы указали, вы на самом деле пытаетесь получить модуль с 1, который равен 1mod(9x). Это всегда даст вам информацию.

И вам не нужно вычислять эту деталь точно, что может снизить ваши расчеты.

С другой стороны, для 10^n = 1, это всегда будет 0. Так что вы можете точно определить, что вы пытаетесь сделать

+0

Это четко указано. Может быть, вы будете смотреть лучше, как '((10^n) mod (9x)) = 1' –

4

Вы можете использовать Fermat's Little Theorem.

Предполагая, что ваш x взаимно простое с 10, справедливо следующее:

10^φ(9x) ≡ 1 (mod 9x) 

Здесь φ является Euler's totient function. Таким образом, вы можете легко вычислить хотя бы один n (не обязательно самый маленький), для которого выполняется ваше уравнение. Чтобы найти наименьший такой n, просто перейдите по списку n 's divisors.


Пример: x = 89 (простое число просто для простоты).

9x = 801 
φ(9x) = 6 * (89 - 1) = 528 (easy to calculate for a prime number) 

Список делители 528:

1 
2 
3 
4 
6 
8 
11 
12 
16 
22 
24 
33 
44 
48 
66 
88 
132 
176 
264 
528 

Пытается каждый из них, вы можете обнаружить, что уравнение справедливо для 44:

10^44 ≡ 1 (mod 801) 
+0

В этом случае '44' я доказал, что это самый маленький' n'. Но, как вы сказали, не всегда ли ваш алгоритм возвращает minimun 'n'? Мне нужно самое маленькое: S –

+0

Это легко доказать – anatolyg

+0

Самый маленький делитель, который содержит уравнение, является наименьшим 'n' желаемым? –