评估模块化电力塔


13

给定两个数字n和m,请评估无限大功率塔:

n ^(n + 1)^(n + 2)^(n + 3)^(n + 4)^ ... mod m

请记住,^是右关联的。因此2 ^ 3 ^ 4 = 2 ^(3 ^ 4)。现在,您如何可能将一个值分配给无数个右联想运算符?

将f(n,m,i)定义为包含无限功率塔的前i个项的功率塔。然后有一个常数C,使得对于每个i> C,f(n,m,i)= f(n,m,C)。因此,您可以说无限大功率塔收敛于某个值。我们对此价值感兴趣。


您的程序必须能够在合理的现代PC上在不到10秒的时间内计算出n = 2017,m = 10 ^ 10。也就是说,您应该实现一个实际的算法,不要强行使用。

您可以假设您的编程语言中的数值限制为n <2 30m <2 50,但是理论上您的算法必须适用于任何大小nm。但是,对于这些大小限制内的输入,您的程序必须正确,如果输入在这些限制内,则不会原谅中间值溢出。

例子:

2, 10^15
566088170340352

4, 3^20
4

32, 524287
16

提示(针对竞争者):n并且不能保证是m互质的。
Leaky Nun

1
10 ^ 10(对于有符号整数,则为10 ^ 20,可能为3 ^ 20)大于许多语言的默认整数类型。是否需要支持这么大的输入?
Doorknob

1
@orlp“是”是否包括10 ^ 20?因为那不适合64位整数,所以如果您需要它,我建议明确指出它,因为否则,您将仅假定64位就得到很多无效答案。整数将足够准确。
Martin Ender

1
无论哪种方式,我们需要支持的最大投入什么?
Martin Ender

@Doorknob我为挑战添加了更多宽松的限制。但是,理论上,您的算法必须适用于任何大小m,n
Orlp

Answers:


7

Pyth,23个字节

M&tG.^HsgBu-G/GH{PGGhHG

定义一个函数g,按mn的顺序排列。

在线尝试

怎么运行的

M&tG.^HsgBu-G/GH{PGGhHG
M                         def g(G, H):
 &tG                        0 if G == 1, else …
                 PG         prime factors of G
                {           deduplicate that
          u-G/GH   G        reduce that on lambda G,H:G-G/H, starting at G
                              (this gives the Euler totient φ(G))
        gB          hH      bifurcate: two-element list [that, g(that, H + 1)]
       s                    sum
    .^H               G     H^that mod G

Python 2,109 76字节

import sympy
def g(n,m):j=sympy.totient(m);return m-1and pow(n,j+g(n+1,j),m)

在线尝试!

为什么有效

我们使用以下欧拉定理的推广

引理。 Ñ 2φ(Ñ φ((MOD )的所有Ñ(无论是否Ñ是互质)。

证明:对于所有素数p k除以m

  • 如果p划分Ñ,然后因为φ)≥ φp ķ)= p ķ - 1p - 1)≥2 ķ - 1ķ,我们有Ñ 2φ( ≡0≡ Ñ φ((mod p k)。
  • 否则,因为φp ķ)划分φ),欧拉定理给出Ñ 2φ( ≡1≡ Ñ φ((MOD p ķ)。

因此,Ñ 2φ(Ñ φ((MOD )。

结果。如果ķ ≥φ(),则Ñ ķÑ φ()+(ķ模φ())(MOD )。

证明:如果ķ ≥2φ(),外稃给出Ñ ķ = Ñ 2φ(ñ ķ - 2φ(Ñ φ(ñ ķ - 2φ( = Ñ ķ - φ(( mod m),然后重复直到指数小于2φ(m)。


如何处理基数和模数不是互质的情况?PS sympy具有求知功能。
orlp

@orlp我添加了一个证明。不知道我怎么想念的sympy.totient
Anders Kaseorg

我现在明白了。好方法!
Orlp

5

Haskell,156个字节

(?)取两个Integers并返回一个Integer,用作as (10^10)?2017(与OP相反的顺序)。

1?n=0
m?n=n&m$m#2+m#2?(n+1)
1#_=1
n#p|m<-until((<2).gcd p)(`div`p)n=m#(p+1)*1`max`div(n*p-n)(p*m)
(_&_)0=1
(x&m)y|(a,b)<-divMod y 2=mod(x^b*(mod(x*x)m&m)a)m

在线尝试!(这次,我将这些案例放在标题中进行测试,因为它们使用了幂表示法。)

奇怪的是,最慢的测试用例不是有速度限制的(几乎是即时的),而是524287 ? 32一个,因为524287它的质数比其他测试用例中的因素大得多。

怎么运行的

  • (x&m)yx^y `mod` m,或幂模,通过平方求幂。
  • n#p是的Euler上位性函数n,假定n其主因子不小于p
    • mn所有p因素都分开。
    • 如果存在k这样的因素,则待办事项本身应该获得一个对应的因数(p-1)*p^(k-1),其计算公式为div(n*p-n)(p*m)
    • 1`max`...处理n未被实际整除的情况p,使得另一个参数max等于0
  • 主要功能m?n用途,当y足够大,n^y `mod` m是一样的n^(t+(y`mod`t)) `mod` m,如果t是的欧拉m。(t+对于那些主要因素而言n,这是必需的,它们m具有共同点,所有因素都得到了最大化。)
  • 该算法停止,因为迭代的目标函数最终达到1。

1

Mathematica,55个字节

n_~f~1=0;n_~f~m_:=PowerMod[n,(t=EulerPhi@m)+f[n+1,t],m]

例子:

In[1]:= n_~f~1=0;n_~f~m_:=PowerMod[n,(t=EulerPhi@m)+f[n+1,t],m]

In[2]:= f[2, 10^15]

Out[2]= 566088170340352

In[3]:= f[4, 3^20]

Out[3]= 4

In[4]:= f[32, 524287]

Out[4]= 16

In[5]:= f[2017, 10^10]

Out[5]= 7395978241

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.