Skip to content

Instantly share code, notes, and snippets.

@LeftofZen
Created August 10, 2017 00:04
Show Gist options
  • Save LeftofZen/1bcc23993d051a9dac8c00557feb4f6f to your computer and use it in GitHub Desktop.
Save LeftofZen/1bcc23993d051a9dac8c00557feb4f6f to your computer and use it in GitHub Desktop.
Solves the max decimal expansion length from 1 to N in a general way using the discrete logarithm. O(n^4)
using System;
namespace Test
{
class RepeatingDecimalLength
{
// Solves the discrete logarithm problem in O(n^3). See https://arxiv.org/ftp/arxiv/papers/0912/0912.2269.pdf
// Returns k that solves for x^k = y (mod p)
public static UInt64 DiscreteLogarithm(UInt64 x, UInt64 y, UInt64 p)
{
UInt64 lv_lng_x = x;
UInt64 lv_lng_y = y;
UInt64 lv_lng_p = p;
UInt64 lv_lng_vx1 = lv_lng_x;
UInt64 lv_lng_vx2 = 0;
UInt64 lv_lng_vy1 = lv_lng_y;
UInt64 lv_lng_vy2 = lv_lng_vy1;
UInt64 lv_lng_v1 = 1;
UInt64 k = 0;
for (System.UInt64 i = 0; i < lv_lng_p; i++)
{
lv_lng_vx2 = 0;
for (System.UInt64 j = 0; j < lv_lng_x; j++)
{
lv_lng_vx2 += lv_lng_vx1;
}
lv_lng_vx1 = lv_lng_vx2;
lv_lng_v1 += 1;
while (lv_lng_vx1 > lv_lng_p)
{
lv_lng_vx1 -= lv_lng_p;
}
if (lv_lng_vy2 == lv_lng_vx1)
{
k = lv_lng_v1;
break;
}
}
return k;
}
public static void Main(string[] args)
{
// Multiplicative Order (Wolfram Alpha)
// The multiplicative order of 10 mod an integer n relatively prime
// to 10 gives the period of the decimal expansion of the reciprocal
// of n (Glaisher 1878, Lehmer 1941).
UInt64 k = 0;
int num = 0;
for (int i = 0; i < 1000; i++)
{
var result = DiscreteLogarithm(10, 1, (UInt64)i);
if (result > k)
{
k = result;
num = i;
Console.WriteLine("{0} has {1} decimal expansion length", num, k);
}
}
Console.ReadLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment