Re[3]: Найти период дроби
От: Буравчик Россия  
Дата: 15.05.13 14:46
Оценка: 15 (1)
Здравствуйте, Кодт, Вы писали:

К>У меня получается, что делитель разлагается на (20, 9, 11, 13, 13, 19, 37, 47, 61, 401, 1512947)

К>Первый множитель не даёт вклад в период, а остальные — дают периоды 1, 2, 6, 6, 18, 3, 46, 60, 200, и какой-то бешеный крендельон.
К>(запустил считалку на питоне, и к сожалению, она не торопится... и ещё не досчитала...)

К>Но уже из этого видно, что итоговый период должен быть кратен 1000.

К>Или я чего-то путаю?

См. последний абзац в раздела Reciprocals of composite integers coprime to 10

1) надо одинаковые простые сомножители объединять в группы:
9, 11, 13*13, 19, 37, 47, 61, 401, 1512947

Они дают длины периодов
1, 2, 78, 18, 3, 46, 60, 200, 756473

2) эти длины надо не перемножать, в вычислять НОК. Поэтому наличие 60 и 200 в списке периодов говорит о том, что итоговое число делится на НОК(60,200), т.е. на 600 (не обязательно на 1000)

НОК от всех периодов будет равен 407133768600
... << RSDN@Home (RF) 1.2.0 alpha 5 rev. 17>>
Best regards, Буравчик
Re[4]: Найти период дроби
От: Yarik_L  
Дата: 17.05.13 17:42
Оценка: 8 (1)
Здравствуйте, Буравчик, Вы писали:

Б>В общем, "решается" уравнение

Б>10^m = 1 (mod p)
Б>Сложность, вроде, O(m)

это задача нахождения дискретного логарифма (http://en.wikipedia.org/wiki/Discrete_logarithm), сложность O(sqrt(p))
Найти период дроби
От: realitydinamomachine  
Дата: 12.05.13 15:13
Оценка:
(128201890995541793509/409169261255380051140)
Re: Найти период дроби
От: Буравчик Россия  
Дата: 13.05.13 18:59
Оценка:
Здравствуйте, realitydinamomachine, Вы писали:

R>(128201890995541793509/409169261255380051140)


Ответ: 407133768600. Верно?
... << RSDN@Home (RF) 1.2.0 alpha 5 rev. 17>>
Best regards, Буравчик
Re[2]: Найти период дроби
От: Кодт Россия  
Дата: 15.05.13 13:56
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Ответ: 407133768600. Верно?


Как посчитал?

У меня получается, что делитель разлагается на (20, 9, 11, 13, 13, 19, 37, 47, 61, 401, 1512947)
Первый множитель не даёт вклад в период, а остальные — дают периоды 1, 2, 6, 6, 18, 3, 46, 60, 200, и какой-то бешеный крендельон.
(запустил считалку на питоне, и к сожалению, она не торопится... и ещё не досчитала...)

Но уже из этого видно, что итоговый период должен быть кратен 1000.
Или я чего-то путаю?
Перекуём баги на фичи!
Re[3]: Найти период дроби
От: Кодт Россия  
Дата: 15.05.13 14:03
Оценка:
Здравствуйте, Кодт, Вы писали:

С учётом "числа Кармихаэля", должно получиться не меньше 3247050540672000
Перекуём баги на фичи!
Re[3]: Найти период дроби
От: Буравчик Россия  
Дата: 15.05.13 19:41
Оценка:
Здравствуйте, Кодт, Вы писали:

К>(запустил считалку на питоне, и к сожалению, она не торопится... и ещё не досчитала...)


Считалка длины периода дроби 1/p

Сначала из множителей удаляются двойки и пятерки, т.к. они не влияют на период. Затем на каждом шаге к числу "дописывается" ноль и вычисляется остаток от деления на p. Как только остаток станет равен единицы, период закончился (ведь в начале вычислений остаток тоже был равен единице).

В общем, "решается" уравнение
10^m = 1 (mod p)
Сложность, вроде, O(m)


На Haskell
decPeriod p | p `mod` 2 == 0 = decPeriod (p `div` 2)
            | p `mod` 5 == 0 = decPeriod (p `div` 5)
            | p <= 1         = 0
            | otherwise      = (fromJust $ elemIndex 1 $ tail $ iterate nextMod 1) + 1
  where nextMod m = m * 10 `mod` p


То же самое на Python
def dec_period(p):
    while p % 2 == 0: 
        p /= 2

    while p % 5 == 0: 
        p /= 5

    if p <= 1: 
        return 0

    m = 1*10 % p
    period = 1
    while m > 1:
        m = m*10 % p
        period += 1
    return period
... << RSDN@Home (RF) 1.2.0 alpha 5 rev. 17>>
Best regards, Буравчик
Re[4]: Найти период дроби
От: Буравчик Россия  
Дата: 15.05.13 20:14
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>В общем, "решается" уравнение

Б>10^m = 1 (mod p)
Б>Сложность, вроде, O(m)

А ведь можно еще быстрее!

Если p простое больше двух, то 10^(p-1) = 1 (mod p)
А значит искомое m является множителем числа (p-1)

Для нашего примера:
p = 1512947
p-1 = 1512947-1 = 1512946 = 2 * 149 * 5077

Т.е. для поиска m надо проверить следующие степени десятки:
2
149
5077
2
*149 = 298
2*5077 = 10154
149*5077 = 756473 <- и вот оно, искомое m

Т.е. для поиска периода достаточно было проверить всего 6 степеней вместо 756473
Правда нужно добавить разложение (p-1) на простые множители, поиск всех степеней (6 штук) и само вычисление степеней

Так будет ли быстрее?
... << RSDN@Home (RF) 1.2.0 alpha 5 rev. 17>>
Best regards, Буравчик
Re[2]: Найти период дроби
От: realitydinamomachine  
Дата: 16.05.13 04:16
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Здравствуйте, realitydinamomachine, Вы писали:


R>>(128201890995541793509/409169261255380051140)


Б>Ответ: 407133768600. Верно?


должно быть 285311670611 . не больше.
Re[4]: Найти период дроби
От: realitydinamomachine  
Дата: 16.05.13 05:20
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Здравствуйте, Кодт, Вы писали:


К>>У меня получается, что делитель разлагается на (20, 9, 11, 13, 13, 19, 37, 47, 61, 401, 1512947)

К>>Первый множитель не даёт вклад в период, а остальные — дают периоды 1, 2, 6, 6, 18, 3, 46, 60, 200, и какой-то бешеный крендельон.
К>>(запустил считалку на питоне, и к сожалению, она не торопится... и ещё не досчитала...)

К>>Но уже из этого видно, что итоговый период должен быть кратен 1000.

К>>Или я чего-то путаю?

Б>См. последний абзац в раздела Reciprocals of composite integers coprime to 10


Б>1) надо одинаковые простые сомножители объединять в группы:

Б>9, 11, 13*13, 19, 37, 47, 61, 401, 1512947

Б>Они дают длины периодов

Б>1, 2, 78, 18, 3, 46, 60, 200, 756473

Б>2) эти длины надо не перемножать, в вычислять НОК. Поэтому наличие 60 и 200 в списке периодов говорит о том, что итоговое число делится на НОК(60,200), т.е. на 600 (не обязательно на 1000)


Б>НОК от всех периодов будет равен 407133768600


Уточнение. Период 1/47 равен 23, не 46.
Re[5]: Найти период дроби
От: Буравчик Россия  
Дата: 16.05.13 06:15
Оценка:
Здравствуйте, realitydinamomachine, Вы писали:

R>Уточнение. Период 1/47 равен 23, не 46.


Первые 200 цифр после запятой:

0212765957446808510638297872340425531914893617
0212765957446808510638297872340425531914893617
0212765957446808510638297872340425531914893617
0212765957446808510638297872340425531914893617
0212765957446808...

Период 46
Best regards, Буравчик
Re[5]: Найти период дроби
От: Буравчик Россия  
Дата: 17.05.13 18:03
Оценка:
Здравствуйте, Yarik_L, Вы писали:

Y_L>Здравствуйте, Буравчик, Вы писали:


Б>>В общем, "решается" уравнение

Б>>10^m = 1 (mod p)
Б>>Сложность, вроде, O(m)

Y_L>это задача нахождения дискретного логарифма (http://en.wikipedia.org/wiki/Discrete_logarithm), сложность O(sqrt(p))


Интересно, не знал.
Правда, в нашем случае стоит более узкая задача (=1), и, возможно, существуют еще более быстрые алгоритмы.
... << RSDN@Home (RF) 1.2.0 alpha 5 rev. 17>>
Best regards, Буравчик
Re[6]: Найти период дроби
От: Буравчик Россия  
Дата: 17.05.13 18:25
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>>>10^m = 1 (mod p)

Б>Правда, в нашем случае стоит более узкая задача (=1), и, возможно, существуют еще более быстрые алгоритмы.

Вот здесь ( Показатель числа по модулю) утверждается, что m можно найти за O(полином от ln p)
... << RSDN@Home (RF) 1.2.0 alpha 5 rev. 17>>
Best regards, Буравчик
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.