Fermat'ın çarpanlara ayırma yardımcısı


19

Yarı-yarı çarpanlarına ayırmak istiyoruz . Bu meydan okumanın amacı iki küçük Tamsayılardaki bulmaktır ve böyle böylece kolayca faktörlerini düşeriz izin trivially Fermat'ın yöntemiyle factorized edilebilir .u v u v N NN-uvuvN-N-

Görev

Yarı yarı ve pozitif bir tamsayı verildiğinde , ve şöyle tanımlarız :k x yN-kxy

y=x2-kN

x=kN-
y=x2-kN-

Adım # 1 - bulunk

Önce ihtiyaç en küçük olası değeri bulmak için öyle ki bir olan kare sayı ( aka mükemmel kare).yky

Bu, kN'yi Fermat'ın çarpanlara ayırma yönteminin tek bir yinelemesiyle çarpanlarına izin verir . Daha somut olarak, bu hemen aşağıdakilere yol açar:kN-

kN-=(x+y)x(x-y)

(Güncelleme: bu sıra şimdi A316780 olarak yayınlandı )

Adım # 2 - Factorizek

Daha sonra ve v olmak üzere iki pozitif tamsayıyı bulmalısınız :uv

c u = x +

uv=k
cu=x+y
dv=x-y

burada ve , başlıca faktörleridir .d NcdN-

özet

Göreviniz, girdi olarak alan ve ve çıktılarını herhangi bir sırada ve makul bir formatta basan bir program veya işlev yazmaktır .u vN-uv

Misal

En düşünelimN-=199163

Aşama 1

Olabildiğince az değer olan veren:40k40

y=28232-40x199.163=7.969.329-7.966.520=2809=532k, N=(2823+53)x(2823-53)k, N=2876x2770

x=(40x199163)=2823
y=28232-40x199163=7969329-7966520=2809=532
kN-=(2823+53)x(2823-53)
kN-=2876x2770

Adım 2

Doğru çarpanlara olan çünkü:k = 4 × 10kk=4x10

k N = ( 719 × 4 ) × ( 277 × 10 ) N = 719 × 277

kN-=2876x2770
kN-=(719x4)x(277x10)
N-=719x277

Dolayısıyla, doğru cevap ya ya da .[ 10 , 4 ][4,10][10,4]

kurallar

  • Yukarıda açıklanan iki adımı kesinlikle uygulamak gerekli değildir. Doğru ve değerlerini bulduğu sürece başka bir yöntem kullanmakta serbestsiniz .vuv
  • tüm değerlerini, işaretsiz bir tamsayının yerel maksimum boyutuna kadar desteklemelisiniz .uvN-
  • Girdinin bir yarıçap olması garanti edilir.
  • Bu kod golf, bu yüzden bayttaki en kısa cevap kazanır.
  • Standart boşluklar yasaktır.

Test senaryoları

N          | k    | Output
-----------+------+------------
143        | 1    | [   1,  1 ]
2519       | 19   | [   1, 19 ]
199163     | 40   | [   4, 10 ]
660713     | 1    | [   1,  1 ]
4690243    | 45   | [   9,  5 ]
11755703   | 80   | [  40,  2 ]
35021027   | 287  | [   7, 41 ]
75450611   | 429  | [ 143,  3 ]
806373439  | 176  | [   8, 22 ]
1355814601 | 561  | [  17, 33 ]
3626291857 | 77   | [   7, 11 ]
6149223463 | 255  | [  17, 15 ]
6330897721 | 3256 | [  74, 44 ]

Örnek uygulama

Aşağıdaki pasajı olarak, fonksiyonu alan bir ungolfed uygulamasıdır giriş ve dönerken ve .N u vfN-uv

gN-uvN-Ö(1)


NGirdinin gerçekte bir yarı periyot olacağı garanti ediliyor mu?
Greg Martin

@GregMartin Evet, öylesin.
Arnauld

Yanıtlar:


8

Mathematica, 81 79 bayt

Martin Ender'e 2 bayt kazandığı için teşekkürler!

(c=Ceiling;For[j=0;z=E,c@z>z,p=(x=c@Sqrt[j+=#])+{z=Sqrt[x^2-j],-z}];p/#~GCD~p)&

Yarı-işlevi girdi olarak alan ve sıralı bir pozitif tamsayı çifti döndüren saf işlev. ForTam prosedür (kullanarak sözkonusu tarif edilen halka uygular #yerine girişi için nolan) xve saklama rağmen, orada tanımlanan j = k*nyerine kkendi başına z=Sqrt[y]yerine ytek başına. Ayrıca , bir bayt (yedinci deneme gibi) tasarrufu sağlayan döngü p={x+z,x-z}içinde de hesaplıyoruz For. Daha sonra istenen iki faktör (x+z)/GCD[#,x+z]ve (x-z)/GCD[#,x-z]öz ifadenin p/#~GCD~pdoğrudan sıralı bir çift olarak hesapladığı ve

Merak: zbir tam sayı olana kadar döngü istiyoruz ; ancak Ceilingkodda zaten kullanacağımız !IntegerQ@ziçin, tanımlamak için iki bayt kaydeder c=Ceiling(Mathematica golfçülerinin bildiği gibi dört bayta mal olur) ve sonra test edip etmediğini test eder c@z>z. Bir zşeye başlamalıyız ve bir şeyin bir tamsayı olmaması daha iyi olurdu, böylece döngü başlayabilir; Neyse ki, Ekısa bir seçimdir.


4

JavaScript (ES7), 86 81 bayt

n=>(g=k=>(y=(n*k)**.5+1|0,y+=(y*y-n*k)**.5)%1?g(k+1):n*u++%y?g(k):[--u,k/u])(u=1)

Düzenleme: @Arnauld sayesinde 4 bayt kaydedildi.


4

Piton 2, 127 121 117 111 107 104 101 99 bayt

Neil sayesinde -1 bayt ve ovs sayesinde -3 bayt

N=input()
k=u=1;p=m=.5
while p%1:p=1+(k*N)**m//1;p+=(p*p-k*N)**m;k+=1
while N*u%p:u+=1
print~-k/u,u

Çevrimiçi deneyin!

İlginç:

p.5ilk yinelemede döngü koşulu doğru olacak şekilde başlatılır . Not hafızasın- kısa olduğu p(aynı x+ sqrt(y)o, her depolamak için olanın dışında) xve yayrıca.


x*xyerine x**2?
Neil

@Neil Evet, elbette. Teşekkürler
math junkie

1

Aksiyom, 131 115 bayt

v(x)==floor(x^.5)::INT;r(n)==(k:=0;repeat(k:=k+1;x:=1+v(k*n);y:=v(x*x-k*n);x^2-y^2=k*n=>break);[w:=gcd(k,x+y),k/w])

Soruyu çözecek fonksiyon yukarıdaki r (n) 'dir. ungolf ve testi

vv(x)==floor(x^.5)::INT    

--(x-y)*(x+y)=k*n
rr(n)==
  k:=0
  repeat
     k:=k+1
     x:=1+vv(k*n)
     y:=vv(x*x-k*n)
     x^2-y^2=k*n=>break
  [w:=gcd(k,x+y),k/w]


(4) -> [[i,r(i)] for i in [143,2519,199163,660713,4690243,11755703]]
   (4)
   [[143,[1,1]], [2519,[1,19]], [199163,[4,10]], [660713,[1,1]],
    [4690243,[9,5]], [11755703,[40,2]]]
                                                      Type: List List Any
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.