Bézout'un Kimliği


11

Giriş Bezout kimliği

İki A, B tamsayısının GCD'si, her ikisini de hiçbir kalıntı bırakmadan ayıran en büyük pozitif tamsayıdır. Şimdi Öklid'in özelliği nedeniyle her bir tamsayı N'nin aşağıdaki gibi başka bir tamsayı M'ye bölünebileceği:

                                           Öklid bölümü

yazabileceğimiz u, v çiftleri var:

                                           Bézout'un Kimliği

Bu çiftlerin sonsuz miktarda olması nedeniyle özel çiftler bulmak istiyoruz. Aslında tam olarak (A, B sıfır değil),

                                           Anlamlı (u, v) çiftler için kısıtlamalar


Örneğin                                    19 ve 17 ile örnek


Meydan okuma

Bu zorluğun amacı, yukarıdaki kısıtlamaları doyuran ve u'nun pozitif olması gereken (sıralı) katsayı çiftini (u, v) bulmaktır. Bu, çıkışı benzersiz bir çifte daraltır.


Giriş

Girişin pozitif olduğunu varsayabiliriz, ayrıca A her zaman B'den daha büyük olacaktır (A> B).


Çıktı

Programımızın / fonksiyonumuzun çıktısı, meydan okumada belirtilen (sıralı) çift olmalıdır.


kurallar

Yerleşik genişletilmiş Öklid algoritmaları kullanılmamalıdır (örneğin Mathematica'da kullanılmasına izin verilir, GCDancak kullanılmaz ExtendedGCD- yine de 5,3 için başarısız olur).

Cevap tam bir program (STDIN veya benzeri yoluyla giriş ve STDOUT yoluyla çıkış) veya bir işlev (çifti döndürme) olabilir.

Çiftin (u, v) yanında herhangi bir çıktı olmayacak, sondaki satırlara veya boşluklara izin verilecektir. (parantez veya virgül iyi)

Bu kod golf, tüm standart boşluklar yasaktır ve en düşük bayt sayısına sahip program kazanır.


Örnekler

(A, B) -> (u, v)
(42, 12) -> (1, -3)
(4096, 84) -> (4, -195)
(5, 3) -> (2, -3)
(1155, 405) -> (20, -57)
(37377, 5204) -> (4365, -31351)
(7792, 7743) -> (7585, -7633)
(38884, 2737) -> (1707, -24251)
(6839, 746) -> (561, -5143)
(41908, 7228) -> (1104, -6401)
(27998, 6461) -> (3, -13)
(23780, 177) -> (20, -2687)
(11235813, 112358) -> (8643, -864301)

Yanıtlar:


1

MATL , 37 40 bayt

ZdXK2Gw/:1G*1GK/t_w2$:XI2G*!+K=2#fIb)

Bu sorundan daha eski olan (9.3.1) sürümünü kullanır .

Bu kaba kuvvet yaklaşımıdır, bu nedenle büyük girdiler için çalışmayabilir.

Çevrimiçi deneyin! Çevrimiçi derleyici daha yeni bir sürüme dayanmaktadır, ancak aynı sonuçları üretir.

açıklama

Zd            % implicitly input A and B. Compute their GCD. Call that C
XK            % copy C to clipboard K
2Gw/:         % vector [1, 2, ..., B/C]
1G*           % multiply that vector by A
1GK/t_w2$:    % vector [-A/C, -A/C+1 ..., A/C]
XI            % copy to clipboard I
2G*           % multiply that vector by B
!+            % all pairwise sums of elements from those vectors
K=2#f         % find row and column indices of sum that equals C
Ib)           % index second vector with column (indexing first vector with
              % row is not needed, because that vector is of the form [1, 2, ...])

7

Haskell, 51 bayt

a#b=[(u,-v)|v<-[1..],u<-[1..v],gcd a b==u*a-v*b]!!0

Kullanım örneği: 27998 # 6461-> (3,-13).

Bu tüm kombinasyonları bulan bir kaba kuvvet yaklaşımıdır uve vgöre sıralanmış geçerli çözümler olduğunu uve ilk olanı seçer. Büyük miktarlarda çalışmak biraz zaman alır |v|.


[]!!0Fikri seviyorum =)
kusur

3

Piton 3, 101 106 bayt

Düzenleme: Bruce_Forte tarafından önerilen bazı iyileştirmeler ve düzeltmeler eklendi .

Genişletilmiş Öklid algoritmasını kullanan bir cevap. Gerçi yerlerde biraz tıknaz ve ben biraz daha golf umuyoruz. Tamsayı bölmesinde bir bayt kaydetmek için Python 2'ye dönüştürebilirim ( //) ama %çıktıyı doğru almak için çok önemli olduğu için Python 2'nin modül operatörünün negatif bir ikinci argümanla nasıl çalıştığından emin değilim .

def e(a,b):
 r=b;x=a;s=z=0;t=y=1
 while r:q=x/r;x,r=r,x%r;y,s=s,y-q*s;z,t=t,z-q*t
 return y%(b/x),z%(-a/x)

Ungolfed:

def e(a, b):
    r = b
    x = a    # becomes gcd(a, b)
    s = 0
    y = 1    # the coefficient of a
    t = 1
    z = 0    # the coefficient of b
    while r:
        q = x / r
        x, r = r, x % r
        y, s = s, y - q * s
        z, t = t, z - q * t
    return y % (b / x), z % (-a / x) # modulus in this way so that y is positive and z is negative

Anonim bir kullanıcı k, ungolfed sürümünüzün son satırındaki değişkenin tanımsız olduğuna dikkat çekti .
Jonathan Frech

@JonathanFrech Ah, teşekkür ederim!
Sherlock9

1

Mathematica, 80 bayt

f@l_:=Mod@@NestWhile[{Last@#,{1,-Quotient@@(#.l)}.#}&,{{1,0},{0,1}},Last@#.l>0&]

Açıklama :

Genişletilmiş Öklid algoritması burada bir Nesttarzda kullanılır. Katsayıların dizilerde depolanma yöntemi, kullanımını mümkün kılar Dot.

Başka bir olası gösterimi olan sadece sembolik ifade kullanıyor u a - v bolan {a->19, b->17}. Bu temsil Mathematica'nın özelliğini kullanır ve ilginçtir, ancak bayt olarak çok daha uzundur.


Test senaryoları :

f[{5, 3}]              (* {2, -3} *)
f[{42, 12}]            (* {1, -3} *)
f[{11235813, 112358}]  (* {8643, -864301} *)

1

Ruby, 83 bayt

Bu çözümü ince ayarlamanın ve golf oynamanın birkaç yolu olduğunu düşünüyorum, ancak şimdiye kadar beğendim. Belki bir sonraki Öklid algoritması çözümünü deneyeceğim.

->x,y{a=b=0;y.downto(0).map{|u|(-x..0).map{|v|a,b=u,v if u*x+v*y==x.gcd(y)}};p a,b}

Nasıl çalışır

Bir döngü ile bu kod başlar ugelen ybir iç döngü ile aşağı 0, vdan -xher kontrol 0, iç uve veğer u*x+v*y == gcd(x, y). Yol boyunca birden çok eşleşme (bu kullanımları çok ayrıntılı arama) olabilir bu yana, biz birden maçların son olsun bu yüzden, birincisi bu kadar 0'dan başlamak |u|ve |v|0'a yakın olan.

def bezout(x,y)
  a=b=0
  y.downto(0).each do |u|
    (-x..0).each do |v|
      if u*x + v*y == x.gcd(y)
        a,b=u,v
      end
    end
  end
  p a,b
end

@Bruce_Forte Darn. Bu test durumu için IRB'nin belleği doldu. Mümkün olan en kısa sürede genişletilmiş Öklid algoritması çözümü yazacağım.
Sherlock9
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.