Bir tamsayı modülünün tersini hesaplayın 100000000003


21

Görev şudur. Uygun bir şekilde kodunuza sunulan bir tamsayı x( xmoduloya 100000000003eşit olmadığı şekilde 0) verilmişse, başka bir tamsayı alın y < 100000000003.(x * y) mod 100000000003 = 1 .

Giriş yaptığınız herhangi bir giriş için standart bir masaüstü makinesinde çalıştırmak için kodunuzun 30 dakikadan kısa sürmesi gerekir x.|x| < 2^40 .

Test durumları

Giriş: 400000001. Çıktı: 65991902837

Giriş: 4000000001. Çıkış: 68181818185

Giriş: 2. Çıkış: 50000000002

Giriş: 50000000002. Çıkış: 2.

Giriş: 1000000. Çıktı: 33333300001

Kısıtlamalar

Modulo aritmetiği (veya bu ters işlem) gerçekleştiren hiçbir kütüphaneyi veya yerleşik işlevi kullanamazsınız. Bu, a % buygulama yapmadan bile yapamayacağınız anlamına gelir% kendinizi . Bununla birlikte, diğer tüm modulo olmayan aritmetik yerleşik fonksiyonlarını kullanabilirsiniz.

Benzer soru

Bu soruya benzer, ancak yine de ilginizi çekecek kadar farklıdır.


Yani a- (a / b) * b iyi mi?
user253751

@ immibis Bu iyi görünüyor.

etiketi: kısıtlı kod?
Felipe Nardi Batista

1
Özel olan ne 100000000003? (sadece merak ediyorum)
NoOneIsHere

1
@Lembik Bu durumda, sorudaki y <100000000003 gerekliliğinden bahseder misiniz?
isaacg,

Yanıtlar:


16

Pyth, 24 bayt

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

Test odası

Bu, bir ^ (p-2) mod p = a ^ -1 mod p olduğu gerçeğini kullanır.

Öncelikle, mod 100000000003'ün özel durumu için modülü manuel olarak yeniden a mod b = a - (a/b)*byerleştiriyorum /. Döşenmiş bölmenin olduğu formülü kullanıyorum . Modül 10^11 + 3kullanarak kodu kullanarak +3^T11, sonra kaydedin J, sonra bunu ve yukarıdaki formülü kullanarak b mod 100000000003 ile hesaplayın -b*/bJ+3^T11J. Bu fonksiyon olarak tanımlanır yile L.

Sonra, girişle başlıyorum, sonra onuncu güce alıyorum ve mod 100000000003'ü azalttım ve bunu 11 kez tekrarlıyorum. y^GTHer adımda yürütülen koddur uy^GT11Qve girdiden başlayarak kodu 11 defa çalıştırır.

Şimdi sahibim Q^(10^11) mod 10^11 + 3ve istiyorum Q^(10^11 + 1) mod 10^11 + 3, bu yüzden giriş ile *çarpıyorum, mod 100000000003'ü yson kez azalttım ve çıktısını aldım .


Gerçekten çok iyi!

Sanırım test davalarını sıkmak için artık çok geç ....

1
@Lembik Yine de yapardım, ama görüşler değişebilir. Bu senin işin, istediğin gibi çalışmasını sağla.
isaacg,

Sorunun yazıldığı şekilde, bir sonuca varılması gerekip gerekmediğine dair bir açıklama talep etmeme rağmen, son indirimi düşürebilirsiniz.
Ørjan Johansen

9

Haskell , 118 113 105 101 bayt

Bu çözümden ilham alındı .

-12, Ørjan Johansen'dan

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]

Çevrimiçi deneyin!

Haskell , 48 bayt

Bu çözümün bir tekrarı . Test vektörü için yeterince hızlı olsa da, bu çözüm diğer girişler için çok yavaştır.

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

Çevrimiçi deneyin!


Müthiş! Ben üstelik kareyi yaklaşarak seviyorum.
isaacg,

En kısa çözüm, çevrimiçi deneyin! ama performansının kabul edilebilir olduğunu sanmıyorum ...
bartavelle

(1) Bu yapmak daha kısa gbir operatör (e?b)a s|...size geçerseniz (2) ave sardından yapabilir !bir sigara -Operatör ve inline yiçine. (3) Kopyalama pahasına pahalı wherebir lastnumaradan kurtulabilirsiniz z. Çevrimiçi deneyin!
Ørjan Johansen

Şimdi bunlar güzel numaralar!
bartavelle

Oh, ve |e==0=abu sinir bozucu kopyadan kurtulur.
Ørjan Johansen

6

Brachylog , 22 bayt

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

Çevrimiçi deneyin!

Bu 1000000, kodun tam olarak iki kat daha hızlı (biraz daha uzun (yalnızca İhem pozitif hem de negatif) yerine yalnızca pozitif değerleri kontrol edilir) denetlenen) sürümünün biraz farklı (ve daha uzun) bir sürümüyle yaklaşık 10 dakika sürdü . Bu nedenle bu girişin tamamlanması yaklaşık 20 dakika sürecektir.

açıklama

Bunu basitçe açıklarız Input × Output - 1 = 100000000003 × an integerve kısıtlamaların aritmetiğinin Outputbizim için bulmasına izin veririz .

∧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

Teknik olarak açık etiketlemeye ihtiyacımız yok , ancak kullanmazsak davayı kontrol etmeyeceğiz N = [100000000003,1](genellikle işe yaramaz), yani bunun girdi 2için çok yavaş olacağı anlamına geliyor, çünkü en küçük ikinci tamsayıyı bulması gerekecek ilk yerine.


1
Vay be, kısıtlama aritmetiğinin bunu çıkarmasını beklemiyordum. Müthiş!
isaacg,

1
@isaacg Bunun hızı ne yazık ki tamamen değerine bağlı İ, bu yüzden büyük ürünler için hala oldukça yavaş.
17'de

Soru güncellendi. Kodunuz her zaman 30 dakikadan az sürüyor mu?

6

Python, 53 51 49 58 53 49 bayt

Orlp sayesinde
-2 bayt-officialaimm sayesinde
-4 bayt-Felipe Nardi Batist sayesinde -4 bayt--
3 bayt isaacg
-1 bayt ile Ørjan Johansen
sayesinde -2 bayt Federico Poloni sayesinde

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

Çevrimiçi Deneyin!

Bunu anlamak için bana ~ 30 dakika sürdü. Benim çözümüm, 1 olacak şekilde ayarlanacak ilk sayı ile başlamaktır. Bu sayı 1'dir. Değilse, 10000000003'ün 1'e eşitleneceği ikinci sayıyı bulmak için bu sayıya 10000000003 ekleyin ve tekrarlayın.



@orlp lol teşekkürler. Bu beni 2 bayt kurtardı :)
Zachary Cotton

İlginçtir ki, TIO'da bu tüm test durumları için hızlıdır ancak biraz rastgele klavye çarpması bana 421385994hangi zaman aşımını verdi .
Ørjan Johansen

@ ØrjanJohansen İyi uyuma.

1
bSadece bir kere ihtiyacınız varsa , neden kodlamıyorsunuz?
Federico Poloni,

5

JavaScript (ES6), 153 143 141 bayt

Math.stackexchange.com tarafından verilen cevaptan esinlenmiştir .

Öklid algoritmasına dayanan özyinelemeli bir işlev.

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 hesaplanarak uygulanır:

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

Bölüme de ihtiyaç duyulduğundan, bu şekilde yapmak aslında bir anlam ifade ediyor.

Test durumları


Sadece son bitimde 64 bit döşemeye ihtiyacınız var, diğerlerini 0 | x / y ile değiştirebilir ve bildirimi kaldırabilirsiniz
Oki

5

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

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, Euler teoremine ve ikili üstelliğe dayalı.

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 ++ yalnızca longen az 32 bit olmalıdır, bu nedenle mutlaka tutamaz 1e11 + 3. Windows x86-64'te 32 bit. longYine de, x86-64 Linux (ve SystemV ABI kullanan diğer işletim sistemlerinde) 64-bit türüdür. Tamamen taşınabilir olmak için long long, C ++ 11'den bu yana en az 64 bit olacağı garantili olan kullanmanız gerekir .
Peter Cordes,

__int128_tstandart bir C ++ gibi görünmüyor, bir gcc uzantısı gibi görünüyor, bunu bir dil olarak belirtmeniz iyi olurdu (C ++ 11 + gcc).
Felix Dombek,

3
Burası bir C ++ uzmanı sitesi olmamalıydı, kimsenin farkına varamayacağını umuyordum.
SteelRaven

@PeterCordes Code golfün taşınabilir olması ya da iyi biçimlendirilmesi gerekmiyor, sadece bir uygulama üzerinde çalışması gerekiyor.
aschepler

1
@aschepler: Ben "dedin, o yüzden biliyorum ediyorum gerek". Kimsenin denediği ve başının dertte olması durumunda hangi platformda çalışacağını / çalışmayacağını belirtmenin faydalı olacağını düşündüm.
Peter Cordes,

4

Mathematica, 49 bayt

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

Bu ne kadar sürecek?

Bilgisayarımda 0.001'den daha az (durum 2 ^ 40-1 için)
Keyu Gan


1

Ruby , 58 bayt

Ben kaba kuvvet çözümünü zamanlamayı bitirirken isaacg'ın Fermat'ın küçük teoremini kullanmasını kullanıyor.

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

47 bayt ancak Güncel kaba kuvvet versiyonu olabileceğini olduğunu çok yavaş:

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

Çevrimiçi deneyin!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.