今天我遇到了this article about decimal expansion,我立刻受到启发,在Project Euler Problem 26上修改我的解决方案,将这种新的数学知识包含在一个更有效的解决方案中(没有强制执行)。简而言之,问题是找到d范围为1-1000的值,这将使表达式“1 / d”中的重复循环的长度最大化。
如果没有对可以进一步提高解决问题的有效性的问题做出任何进一步的假设,我决定坚持使用
10^s=10^(s+t) (mod n)
允许我在任何D值找到最长的重复周期(t)和周期的起点。
问题在于等式的指数部分,因为这将在通过使用模数减小之前产生非常大的值。没有整数值可以处理这个大值,并且浮点数据类型似乎计算错误。
我目前正在使用此代码:
Private Function solveDiscreteLogarithm(ByVal D As Integer) As Integer
Dim NumberToIndex As New Dictionary(Of Long, Long)()
Dim maxCheck As Integer = 1000
For index As Integer = 1 To maxCheck
If (Not NumberToIndex.ContainsKey((10 ^ index) Mod D)) Then
NumberToIndex.Add((10 ^ index) Mod D, index)
Else
Return index - NumberToIndex((10 ^ index) Mod D)
End If
Next
Return -1
End Function
在某一点上将计算“(10 ^ 47)mod 983”,导致783,这不是正确的结果。正确的结果应该是732.我假设它是因为我正在使用整数数据类型而且它导致溢出。我尝试使用double,但这甚至给出了更奇怪的结果。
那么我的选择是什么?
答案 0 :(得分:6)
我不是使用^来做你的力量,而是使用乘法做一个for循环,然后通过使用条件检查所计算的数量是否大于mod来获取数字的mod。这有助于使数字更小并且在你的mod编号的范围内。
答案 1 :(得分:1)
我会从我自己的解决方案中给你一个提示。
对于分数的每个十进制扩展,最后得到一个余数,如果乘以当前小数位,则为整数。由于这个剩余部分是您确定下一个十进制扩展所需的全部内容,因此您可以使用它来预测后续扩展。
答案 2 :(得分:0)
请参阅我的帖子,了解另一个问题,getting the nth digit of a fraction,您可能会发现一些有用的线索可以尝试。 (答案是答案是最小的素数小于1000.)(更正:最大素数或Carmichael number小于1000。)