计算整数模100000000003的逆


21

任务如下。给定以您认为方便的任何方式呈现给您的代码的整数x(以至于x模数100000000003不等于0),输出另一个整数,y < 100000000003使(x * y) mod 100000000003 = 1

您的代码必须采取不超过30分钟为标准的台式机上运行的任何输入x这样|x| < 2^40

测试用例

输入:400000001.输出:65991902837

输入:4000000001.输出:68181818185

输入:2.输出:50000000002

输入:50000000002.输出:2。

输入:1000000.输出:33333300001

限制条件

您不得使用任何执行模算术(或此反操作)的库或内置函数。这意味着您甚至无法a % b不实施%自己。但是,您可以使用所有其他非模算术内置函数。

类似问题

这与该问题类似,尽管希望有足够的不同以引起人们的兴趣。


那么a-(a / b)* b很好吗?
user253751'7

@immibis看起来不错。

标签:受限代码?
费利佩·纳尔迪·巴蒂斯塔

1
有什么特别之处100000000003?(只是想知道)
NoOneIsHere

1
@Lembik在这种情况下,您能否提及问题中y <100000000003的要求?
isaacg

Answers:


16

Pyth,24个字节

L-b*/bJ+3^T11Jy*uy^GT11Q

测试套件

这利用了a ^(p-2)mod p = a ^ -1 mod p的事实。

首先,对于mod 100000000003的特定情况,我手动重新实现模数。我使用公式a mod b = a - (a/b)*b,其中/为地板除法。我10^11 + 3使用代码生成模+3^T11,然后将其保存J,然后使用此公式和上面的公式使用来计算b mod 100000000003 -b*/bJ+3^T11J。该功能的定义y与相同L

接下来,我从输入开始,然后将其取至第十次幂并减少mod 100000000003,并将此重复11次。y^GT是在每个步骤中执行的代码,并uy^GT11Q从输入开始运行11次。

现在我有了Q^(10^11) mod 10^11 + 3,我想要Q^(10^11 + 1) mod 10^11 + 3,所以我将输入乘以,最后一次*将其减为100000000003 y,然后输出。


的确很好!

我猜测这是为时已晚,我收紧测试用例....

1
@Lembik无论如何我都会这样做,但是意见可能会有所不同。这是您的挑战,使其以您想要的方式工作。
isaacg

问题的编写方式可能使您可以放弃最后的减少,尽管我要求澄清是否需要小于100000000003的结果。
与Orjan约翰森

9

Haskell中118个 113 105 101字节

这个解决方案中得到启发。

ØrjanJohansen的-12

p=10^11+3
k b=((p-2)?b)b 1
r x=x-div x p*p
(e?b)s a|e==0=a|1<2=(div e 2?b$r$s*s)$last$a:[r$a*s|odd e]

在线尝试!

Haskell,48个字节

重写此解决方案。虽然对于测试向量足够快,但是对于其他输入而言,该解决方案太慢了。

s x=until(\t->t-t`div`x*x==0)(+(10^11+3))1`div`x

在线尝试!


太棒了!我喜欢平方的幂运算。
isaacg

最短的解决方案是类似“ 在线尝试”!但我认为它的表现不可接受...
bartavelle

(1)创建g一个运算符要短一些(e?b)a s|...(2)如果您进行切换as则可以使!一个 -operator并内联y到其中。(3)您可以where通过last花招来摆脱昂贵的东西,但要花很多钱z在线尝试!
与Orjan约翰森

现在这些都是不错的把戏!
bartavelle

哦,|e==0=a摆脱了那些讨厌的重复。
与Orjan约翰森

6

Brachylog,22个字节

∧10^₁₁+₃;İ≜N&;.×-₁~×N∧

在线尝试!

1000000代码的版本稍有不同(和更长)大约花了10分钟,而版本却快了两倍(仅检查正值İ而不是正值和负值)。因此,该输入大约需要20分钟才能完成。

说明

我们只描述它Input × Output - 1 = 100000000003 × an integer,然后让约束算法Output为我们找到。

∧10^₁₁+₃                   100000000003
        ;İ≜N               N = [100000000003, an integer (0, then 1, then -1, then 2, etc.)]
            &;.×           Input × Output…
                -₁         … - 1…
                  ~×N∧     … = the product of the elements of N

从技术上讲,我们不需要显式标记,但是,如果不使用它,则不会检查大小写N = [100000000003,1](因为它通常是无用的),这意味着输入将非常缓慢2,例如,因为它需要找到第二个最小整数而不是第一个。


1
哇,我从来没有期望约束算法能够实现这一目标。太棒了!
isaacg

1
@isaacg遗憾的是,此操作的速度完全取决于的值İ,因此对于大型产品而言,这仍然相当慢。
致命

更新了问题。您的代码是否总是少于30分钟?

6

蟒蛇,53 51 49 58 53 49字节

感谢orlp
-2个字节-感谢Officialaimm -2个
字节-感谢Felipe Nardi Batist感谢-4个字节-感谢isaacg
感谢-3个字节感谢ØrjanJohansen
感谢-1个
字节感谢Federico Poloni 感谢-2个字节

x=input()
t=1
while t-t/x*x:t+=3+10**11
print t/x

在线尝试!

我花了大约30分钟的时间才弄清楚这一点。我的解决方案是从第一个将Mod修改为1的数字开始。此数字为1。如果将其除以x,则y是该数字除以x。如果不是,将10000000003添加到该数字以找到第二个数字,该数字1000000003将等于1并重复。


会修改为1的第一个数字是1 ...
orlp

@orlp哈哈,谢谢。那节省了我2个字节:)
Zachary Cotton

有趣的是,在TIO上,这对于所有测试用例都是快速的,但是随机的键盘敲击使我421385994超时了。
与Orjan约翰森

@ØrjanJohansen善于侦探。

1
如果b只需要一次,为什么不对其进行硬编码?
Federico Poloni's

5

的JavaScript(ES6),153个 143 141字节

受到math.stackexchange.com这个答案的启发

基于欧几里得算法的递归函数。

f=(n,d=(F=Math.floor,m=1e11+3,a=1,c=n,b=F(m/n),k=m-b*n,n>1))=>k>1&d?(e=F(c/k),a+=e*b,c-=e*k,f(n,c>1&&(e=F(k/c),k-=e*c,b+=e*a,1))):a+d*(m-a-b)

模是通过计算实现的:

quotient = Math.floor(a / b);
remainder = a - b * quotient;

因为也需要商,所以这样做确实有意义。

测试用例


您只需在最后一次出现时使用64位地板,即可用0 | x / y替换其他地板,并删除声明
Oki

5

C ++ 11(GCC /铛和Linux),104 102个字节

using T=__int128_t;T m=1e11+3;T f(T a,T r=1,T n=m-2){return n?f(a*a-a*a/m*m,n&1?r*a-r*a/m*m:r,n/2):r;}

https://ideone.com/gp41rW

基于Euler定理和二元指数计算的非高尔夫。

using T=__int128_t;
T m=1e11+3;
T f(T a,T r=1,T n=m-2){
    if(n){
        if(n & 1){
            return f(a * a - a * a / m * m, r * a - r * a / m * m, n / 2);
        }
        return f(a * a - a * a / m * m, r, n / 2);
    }
    return r;
}

ISO C ++仅要求long至少为32位,因此不必保留1e11 + 3。在x86-64 Windows上为32位。 long但是,在x86-64 Linux(和其他使用SystemV ABI的操作系统)上,它是64位类型。因此,要完全可移植,就需要使用long long从C ++ 11开始,它必须至少为64位
彼得·科德斯

__int128_t似乎不是标准的C ++,它似乎是gcc扩展,如果您将其声明为一种语言(C ++ 11 + gcc),那就太酷了。
Felix Dombek

3
我不希望这不是C ++专家网站,我希望没人注意。
SteelRaven

@PeterCordes Code golf不需要是便携式的,甚至不需要格式良好的,它只需要一种实现即可。
aschepler '17

1
@aschepler:我知道,这就是为什么我说:“你需要”。我认为指出在哪个平台上/将无法使用该平台很有用,以防有人尝试并遇到麻烦。
彼得·科德斯

4

Mathematica,49个字节

x/.FindInstance[x#==k(10^11+3)+1,{x,k},Integers]&

这需要多长时间才能运行?

我的计算机上的时间少于0.001秒(对于2 ^ 40-1)
Keyu Gan'7


1

红宝石,58字节

我现在使用isaacg的Fermat小定理的应用程序,而我要完成对蛮力解的计时。

->n,x=10**11+3{i=n;11.times{i**=10;i-=i/x*x};i*=n;i-i/x*x}

当前蛮力版本,这是47个字节,但可能 太慢:

->n,x=10**11+3{(1..x).find{|i|i*=n;i-i/x*x==1}}

在线尝试!

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.