这是'数学',但我在这里发帖是因为它是项目欧拉问题,&我有可能有错误的工作代码。
问题Determing longest repeating cycle in a decimal expansion使用对数解决问题,但我有兴趣用简单的蛮力解决。更准确地说,我有兴趣理解为什么我的算法和代码没有返回正确的解决方案。
算法很简单:
这是私人字段,按要求
private int numerator;
private int recurrence;
private int result;
private int resultRecurrence;
private List<dynamic> digits;
这是代码:
private void Go()
{
foreach (var i in primes)
{
digits = new List<dynamic>();
numerator = 1;
recurrence = 0;
while (numerator != 0)
{
numerator *= 10;
// quotient
var q = numerator / i;
// remainder
var r = numerator % i;
digits.Add(new { Divisor = q, Remainder = r });
// if we've found a repetition then break out
var m = digits.Where(p => p.Divisor == q && p.Remainder == r).ToList();
if (m.Count > 1)
{
recurrence = digits.LastIndexOf(m[0]) - digits.IndexOf(m[0]);
break;
}
numerator = r;
}
if (recurrence > resultRecurrence)
{
resultRecurrence = recurrence;
result = i;
}
}}
测试整数时&lt; 10和&lt; 20我得到了正确的结果;我也正确地确定了i
的价值。然而,我得到的十进制表示不正确 - 我计算i-1
而正确的结果远远少于i-250
。
所以我可能有一个编程错误 - 我找不到 - 或者是一个逻辑错误。
我很困惑,因为对我来说感觉就像multiplicative group over p,其中会有p-1元素。我确定我错过了什么,有人可以提供建议吗?
修改
我不会包含我的素数代码 - 它不相关,正如我在上面解释的那样我正确地识别i
的值(从内存中它是983)但是我在找到正确的问题时遇到了问题resultRecurrence
的值。
答案 0 :(得分:2)
我很困惑因为它对我来说感觉像是一个乘法组,其中会有p-1个元素。我确定我错过了什么,有人可以提供建议吗?
关闭。
对于除2和5(除以10)之外的所有素数,剩余序列是通过从1开始并通过
转换而形成的。remainder = (10 * remainder) % prime
因此 k -th余数为10 k (mod prime),剩余集合形成非零组的子组余数模数[1]。循环周期的长度是该子组的顺序,也称为10模数的阶数。
模数为素数的非零余数群的顺序为prime-1
,费马有一个定理:
让
G
成为订单g
的有限组,H
是G
的子组。然后,h
的订单H
除以g
。
因此,周期的长度始终是prime-1
的除数,有时它是prime-1
,例如为7或19。
[1]对于复合数n
互译为10,这将是模n
的余数组n
。
答案 1 :(得分:1)
首先,你不需要除数,你只需要余数。
其次,我将函数拆分为多个独立的部分,而不是将所有东西都放在一个大方法中:循环长度的长除/找到与其余部分无关(=找到最长的循环)。
break
上的Where
加上Count
是不直观的。为什么不使用条件为while
的{{1}}循环? (这需要在循环开始之前将(! digits.Contains(r))
作为余数放入0
列表。)
这给我们留下了一个更清晰的代码,应该可以直接调试。
答案 2 :(得分:1)
recurrence = digits.LastIndexOf(m[0]) - digits.IndexOf(m[0]);
resultRecurrence
的值总是将是i-1
?因为对于1/n
形式的一小部分,当正在进行的除法(i
数字)给出与第一个相同的商 - 余数时,十进制开始重复。 em>试验师(1
,因此i-1
)。
(作为附注,我可以向您介绍Math.DivRem
)。