Compute the inverse of an integer modulo 100000000003

21

The task is the following. Given an integer x (such that x modulo 100000000003 is not equal to 0) presented to your code in any way you find convenient, output another integer y < 100000000003 so that (x * y) mod 100000000003 = 1.

You code must take less than 30 minutes to run on a standard desktop machine for any input x such that |x| < 2^40.

Test cases

Input: 400000001. Output: 65991902837

Input: 4000000001. Output: 68181818185

Input: 2. Output: 50000000002

Input: 50000000002. Output: 2.

Input: 1000000. Output: 33333300001

Restrictions

You may not use any libraries or builtin functions that perform modulo arithmetic (or this inverse operation). This means you can't even do a % b without implementing % yourself. You can use all other non-modulo arithmetic builtin functions however.

Similar question

This is similar to this question although hopefully different enough to still be of interest.

user9206

Posted 2017-07-04T07:15:19.433

Reputation:

So a-(a/b)*b is fine? – user253751 – 2017-07-04T10:31:18.387

@immibis That looks fine. – None – 2017-07-04T11:03:59.363

tag: restricted code? – Felipe Nardi Batista – 2017-07-04T11:14:56.007

I notice you don't have any restriction that y<100000000003. I see at least one answer that could be shortened by dropping a final modulo... – Ørjan Johansen – 2017-07-04T17:53:01.077

@ØrjanJohansen I was definitely expecting y<100000000003. – None – 2017-07-04T20:23:41.127

1What's special about 100000000003? (just wondering) – NoOneIsHere – 2017-07-04T21:19:21.700

1@Lembik In that case, could you mention that requirement that y<100000000003 in the question? – isaacg – 2017-07-04T21:25:45.867

@NoOneIsHere It is the first twelve-digit prime number? – Jeppe Stig Nielsen – 2017-07-04T22:19:00.843

@JeppeStigNielsen It believe it is. – None – 2017-07-05T06:51:33.517

Do the restrictions disallow use of python's pow operator's 3rd argument? https://docs.python.org/3.3/library/functions.html#pow

– bendl – 2017-07-05T17:24:36.100

@bendi Yes they do. – None – 2017-07-05T17:28:36.887

Answers

16

Pyth, 24 bytes

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

Test suite

This uses the fact that a^(p-2) mod p = a^-1 mod p.

First, I manually reimplement modulus, for the specific case of mod 100000000003. I use the formula a mod b = a - (a/b)*b, where / is floored division. I generate the modulus with 10^11 + 3, using the code +3^T11, then save it in J, then use this and the above formula to calculate b mod 100000000003 with -b*/bJ+3^T11J. This function is defined as y with L.

Next, I start with the input, then take it to the tenth power and reduce mod 100000000003, and repeat this 11 times. y^GT is the code executed in each step, and uy^GT11Q runs it 11 times starting with the input.

Now I have Q^(10^11) mod 10^11 + 3, and I want Q^(10^11 + 1) mod 10^11 + 3, so I multiply by the input with *, reduce it mod 100000000003 with y one last time, and output.

isaacg

Posted 2017-07-04T07:15:19.433

Reputation: 39 268

Very nice indeed! – None – 2017-07-04T07:56:27.280

I am guessing it's too late for me to tighten up the test cases.... – None – 2017-07-04T09:45:04.087

1@Lembik I'd do it anyways, but opinions may vary. It's your challenge, make it work the way you want it to. – isaacg – 2017-07-04T09:56:31.057

The way the question is written, it is possible you could drop the final reduction, although I asked for a clarification whether a result <100000000003 is required. – Ørjan Johansen – 2017-07-04T17:59:13.380

9

Haskell, 118 113 105 101 bytes

Inspired from this solution.

-12 from Ørjan Johansen

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]

Try it online!

Haskell, 48 bytes

A rewrite of this solution. While fast enough for the test vector, this solution is too slow for other inputs.

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

Try it online!

bartavelle

Posted 2017-07-04T07:15:19.433

Reputation: 1 261

Awesome! I like the exponentiation by squaring approach. – isaacg – 2017-07-04T08:02:37.367

The shortest solution would be something like Try it online! but I don't think its performance is acceptable ...

– bartavelle – 2017-07-04T08:05:40.120

(1) It's shorter to make g an operator (e?b)a s|... (2) If you switch a and s then you can make ! a non-operator and inline y into it. (3) You can get rid of the expensive where by a last trick, at the cost of duplicating z. Try it online!

– Ørjan Johansen – 2017-07-04T09:02:04.803

Now those are nice tricks! – bartavelle – 2017-07-04T09:30:02.833

Oh, and |e==0=a gets rid of that pesky duplication. – Ørjan Johansen – 2017-07-04T09:43:15.703

Well spotted, updated the solution. – bartavelle – 2017-07-04T11:21:21.813

6

Brachylog, 22 bytes

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

Try it online!

This took about 10 minutes for 1000000 with a slightly different (and longer) version of the code which was exactly two times faster (checked only positive values of İ instead of both positive and negatives). Therefore this should take about 20 minutes to complete for that input.

Explanation

We simply describe that Input × Output - 1 = 100000000003 × an integer, and let constraint arithmetic find Output for us.

∧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

We technically do not need the explicit labeling , however if we do not use it, will not check the case N = [100000000003,1] (because it's often useless), meaning that this will be very slow for input 2 for example because it will need to find the second smallest integer instead of the first.

Fatalize

Posted 2017-07-04T07:15:19.433

Reputation: 32 976

1Wow, I never would have expected constraint arithmetic to pull that off. Awesome! – isaacg – 2017-07-04T08:21:13.480

1@isaacg The speed of this is unfortunately completely dependent on the value of İ, so this is still pretty slow for big products. – Fatalize – 2017-07-04T08:23:13.167

Updated the question. Does your code always take less than 30 minutes? – None – 2017-07-04T09:59:27.317

6

Python, 53 51 49 58 53 49 bytes

-2 bytes thanks to orlp
-2 bytes thanks to officialaimm
-4 bytes thanks to Felipe Nardi Batist
-3 bytes thanks to isaacg
-1 byte thanks to Ørjan Johansen
-2 bytes thanks to Federico Poloni

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

Try it Online!

It took me ~30 minutes to figure this one out. My solution is to start with the first number that will mod to 1. This number is 1. If its divisible by x, then y is that number divided by x. If not, add 10000000003 to this number to find the second number which mod 1000000003 will equal 1 and repeat.

Zachary Cotton

Posted 2017-07-04T07:15:19.433

Reputation: 679

The first number that will mod to 1 is 1... – orlp – 2017-07-04T09:07:22.087

@orlp lol thanks. That saved me 2 bytes :) – Zachary Cotton – 2017-07-04T09:08:27.770

Interesting, on TIO this is fast for all the test cases but a bit random keyboard banging gave me 421385994 which times out. – Ørjan Johansen – 2017-07-04T09:10:49.910

@ØrjanJohansen Good sleuthing. – None – 2017-07-04T09:11:32.697

Why not write b=3+10**11? – officialaimm – 2017-07-04T09:13:22.457

I really like this algorithm, but I can't upvote because of the unnecessary y=0, and more importantly the fact that both the input and output code are missing. – isaacg – 2017-07-04T09:57:44.967

I have updated the question to make it clear it should not to be too slow for any input values. Apologies for the late change. – None – 2017-07-04T09:58:35.650

1If you need b only once, why not hardcoding it? – Federico Poloni – 2017-07-04T18:07:16.167

The OP has relaxed the input/output requirements. You can write a function that returns an integer, instead of actually printing.

– Peter Cordes – 2017-07-04T18:15:05.443

@PeterCordes I think that would be 3 bytes longer. – Ørjan Johansen – 2017-07-04T18:30:55.690

Shouldn't the // be a /? – Ørjan Johansen – 2017-07-04T18:32:24.297

5

JavaScript (ES6), 153 143 141 bytes

Inspired by this answer from math.stackexchange.com.

A recursive function based on the Euclidean algorithm.

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)

Modulo is implemented by computing:

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

Because the quotient is also needed, doing it that way does actually make some sense.

Test cases

let f =

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)

console.log(f(2))
console.log(f(50000000002))
console.log(f(1000000))

Arnauld

Posted 2017-07-04T07:15:19.433

Reputation: 111 334

You only need 64 bit flooring in the last occurence so you can replace the other ones with 0|x/y and remove the declaration – Oki – 2017-07-04T11:19:49.637

5

C++11 (GCC/Clang, Linux), 104 102 bytes

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

Ungolfed, based on Euler's theorem and binary exponentation.

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;
}

SteelRaven

Posted 2017-07-04T07:15:19.433

Reputation: 741

ISO C++ only requires long to be at least 32-bit, so it can't necessarily hold 1e11 + 3. It's 32-bit on x86-64 Windows. long is a 64-bit type on x86-64 Linux (and other OSes that use the SystemV ABI), though. So to be fully portable, you'd need to use long long, which is guaranteed to be at least 64-bit since C++11.

– Peter Cordes – 2017-07-04T18:21:27.480

__int128_t doesn't seem to be standard C++, it seems to be a gcc extension, it would be cool if you'd state this as a language (C++11 + gcc). – Felix Dombek – 2017-07-04T18:38:02.350

3This is not supposed to be a C++ experts site, I hoped no one will notice. – SteelRaven – 2017-07-04T18:47:09.383

@PeterCordes Code golf doesn't need to be portable or even well-formed, it just needs to work on one implementation. – aschepler – 2017-07-04T22:25:49.777

1@aschepler: I know, which is why I said "you would need". I thought it was useful to point out which platform it would/wouldn't work on, in case anyone tried it and ran into trouble. – Peter Cordes – 2017-07-05T05:50:45.673

4

Mathematica, 49 bytes

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

J42161217

Posted 2017-07-04T07:15:19.433

Reputation: 15 931

How long does this take to run? – None – 2017-07-05T06:52:18.340

Less than 0.001s on my computer (for case 2^40-1) – Keyu Gan – 2017-07-11T08:37:24.640

2

PHP, 71 bytes

for(;($r=bcdiv(bcadd(bcmul(++$i,1e11+3),1),$argn,9))!=$o=$r^0;);echo$o;

Testcases

Jörg Hülsermann

Posted 2017-07-04T07:15:19.433

Reputation: 13 026

1

Ruby, 58 bytes

Uses isaacg's application of Fermat's little theorem for now while I finish timing the brute-force solution.

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

Current brute force version, which is 47 bytes but might be is too slow:

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

Try it online!

Value Ink

Posted 2017-07-04T07:15:19.433

Reputation: 10 608