En az ortak olan katlarını korurken iki sayıyı birlikte kullanın


20

İki pozitif tamsayı verilir ave biki pozitif tamsayı çıkarılır cve dşöyle olur:

  • c böler a
  • d böler b
  • cve dbaşbakan
  • en küçük ortak kat arasında cve den küçük ortak katı eşittir ave b.

Birden fazla olası cevap varsa, bunlardan yalnızca birini veya tümünü çıktısını alabilirsiniz.

Test senaryoları:

 a  b  c  d
12 18  4  9
18 12  9  4
 5  7  5  7
 3  6  1  6 or 3 2
 9  9  9  1 or 1 9
 6 15  2 15 or 6 5
 1  1  1  1

Bu . Bayt cinsinden en kısa cevap kazanır.


Geri dönmeme engel olan nedir (1, LCM)?
Neil

1
Gereksinimi @Neil o dbölerb
Çatlak Nun

4
Belki LCM tanımlamalısınız veya en azından kısaltmayı kullanmamalısınız. Biraz ne istediğini bilmiyordum.
Buğday Büyücüsü

Yanıtlar:


7

Jöle , 21 13 bayt

ÆEz®0iṂ$¦€ZÆẸ

Çevrimiçi deneyin!

Eğer a = 2 bir · 3 B · 5 ° C · ... ve b = 2 α · 3 β · 5 γ · ... , o zaman hesaplamak

  • c = 2 A> α? A: 0 · 3 B> β? B: 0 · 5 C> γ? C: 0 ·…

  • d = 2 A> α? 0: α · 3 B> β? 0: β · 5 C> γ? 0: γ ·…

Şimdi lcm (c, d) = 2 maks. (A> α? A: 0, A> α? 0: α) ·… = maks. 2 (A, α) · 3 maks. (B, β) ·… = lcm ( a, b)

ve gcd (c, d) = 2 dk (A> α? A: 0, A> α? 0: α) ·… = 2 0 · 3 0 · 5 0 ·… = 1 .

Başka bir deyişle: (c, d) = (a, b) ' den başlayın . Daha sonra, her bir başbakan için, o başbakanı c veya d' nin çarpanlarına ayırma işleminden sonuna kadar ayırın : hangisi o ana için en küçük üsse sahipse. (Bu uygulamada, bir beraberlik durumunda, c üssünü kaybeder.)

Eğer a = 2250 = 2 1 · 3 2 · 5 3 ve b = 360 = 2 3 · 3 2 · 5 1 ,

o zaman c = 2 0 · 3 0 · 5 3 = 125 ve d = 2 3 · 3 2 · 5 0 = 72 .

Jonathan Allan 8 baytlık büyük bir golf oynuyor! Teşekkür ederim ~


Bu benim orijinal algoritmam ... Perl algoritması daha iyi.
Leaky Nun

Çok hoş. İşte 12 bayt
Jonathan Allan

İşte 12 bayt dahaÆEZ×Ụ’$€$ZÆẸ
mil

Bu artık verir [1,18]için [15,18]. İlk sürüm doğru cevabı ( [5,18]) döndürüyordu .
Arnauld

1
Ah - evet, devrik üzerinde sıfır doldurucuya ihtiyacımız var. ÆEz®0iṂ$¦€ZÆẸ13 numara yapmalı
Jonathan Allan

4

R, 143 139 123 bayt

f=function(a,b,q=1:(a*b))for(i in 1:a)for(j in 1:b)if(!a%%i+b%%j&max(q[!i%%q+j%%q])<2&i*j==min(q[!q%%a+q%%b]))cat(i,j,"\n")

(@Giuseppe'ye bu 19 bayt için teşekkürler!)

Girintiler, yeni satırlar ve bazı açıklamalar ile:

f=function(a,b,
           q=1:(a*b)) #Defined as function arguments defaults to avoid having to use curly brackets
    for(i in 1:a)
        for(j in 1:b)
            if(!a%%i + b%%j & #Is a divided by c and b divided by d
               max(q[!i%%q+j%%q])<2 & #Are c and d coprimes
               i*j==min(q[!q%%a+q%%b])) #Is this the same lcm
                   cat(i,j,"\n") #Then print

Test senaryoları:

> f=function(a,b,q=1:(a*b))for(i in 1:a)for(j in 1:b)if(!a%%i+b%%j&max(q[!i%%q+j%%q])<2&i*j==min(q[!q%%a+q%%b]))cat(i,j,"\n")
> f(5,7)
5 7 
> f(12,18)
4 9 
> f(6,15)
2 15 
6 5 
> f(1,1)
1 1 

!daha yüksek önceliğe sahiptir &ve |daha ancak daha düşük +ve *; bu şekilde birkaç bayt golf oynayabilmelisiniz; yani, !i%%q&j%%qeşdeğer olmalıdır!i%%q+j%%q
Giuseppe

1
İyi gözlem: eğer GCD(c,d)==1öyleyse LCM(c,d)==c*d. Bu yüzden test edebilir GCD(c,d)==1ve sonra c*d==a*b/GCD(a,b)ikincisi olup olmadığını kontrol edebiliriz LCM(a,b)...
Giuseppe

1
Aslında! (hesaplama a*b/GCD(a,b)daha kısa olmamasına rağmen LCM(a,b)).
plannapus

120 bayt - anonim işlev + -3 bayt için literal yeni satır
Giuseppe

4

Kabuk , 10 bayt

→ÖF§-⌋⌉ΠmḊ

Kaba kuvvet. Listeleri alır ve döndürür ve ikiden fazla sayı için çalışır. Çevrimiçi deneyin!

açıklama

→ÖF§-⌋⌉ΠmḊ  Implicit input, say [6,15]
        mḊ  Map divisors: [[1,2,3,6],[1,3,5,15]]
       Π    Cartesian product:[[1,1],[2,1],[1,3],[2,3],[3,1],[1,5],[3,3],[6,1],[1,15],[2,5],[3,5],[6,3],[2,15],[6,5],[3,15],[6,15]]
 Ö          Sort by
  F         reduce by
     ⌉      lcm
   -⌋       minus gcd: [[1,1],[3,3],[2,1],[1,3],[3,1],[6,3],[1,5],[2,3],[6,1],[2,5],[3,15],[1,15],[3,5],[6,15],[2,15],[6,5]]
→           Get last element: [6,5]

3

Mathematica, 82 bayt

#&@@Select[Subsets[Flatten@Divisors[{t=#,r=#2}],{2}],GCD@@#==1&&LCM@@#==t~LCM~r&]&

Emin değilim, ancak bayt kaydetmek Select[...][[1]]yerine liste dizine ekleme özelliğini kullanamaz First@Select[...]mısınız?
Jonathan Frech

evet, ama sonra kullanabilirsiniz #&@@yerine [[1]];-) bir daha kurtarmak için
J42161217

3

JavaScript (ES6), 90 84 80 bayt

Curried sözdiziminde girdi alır (a)(b)ve 2 tamsayıdan oluşan bir dizi döndürür.

a=>g=(b,c=1)=>(G=(a,b)=>b?G(b,a%b):a)(c,d=a*b/G(a,b)/c)-1|a%c|b%d?g(b,c+1):[c,d]

Test senaryoları

Nasıl?

a =>                            // a = first input
  g = (                         // g = recursive function that takes:
    b,                          //   b = second input
    c = 1                       //   c = first output divisor, initially set to 1
  ) =>                          //
    (G = (a, b) =>              // G = function that takes a and b
      b ? G(b, a % b) : a       //     and returns the greatest common divisor
    )(                          // we call it with:
      c,                        //   - c
      d = a * b / G(a, b) / c   //   - d = LCM(a, b) / c = a * b / GCD(a, b) / c
    ) - 1 |                     // if the result is not 1 (i.e. c and d are not coprime)
    a % c |                     // or c does not divide a
    b % d ?                     // or d does not divide b:
      g(b, c + 1)               //   do a recursive call with c + 1
    :                           // else:
      [c, d]                    //   return [c, d], a valid factorization of the LCM

3

MATL , 17 16 bayt

&YFt&X>2:!=*^!Xp

Çevrimiçi deneyin!

Lynn'in Jelly çözümü ile aynı yöntem

Herhangi bir MATL (veya bu konu için matlab) kullandığımdan beri bir süredir çok fazla gelişme mümkün.


3

Haskell ,50 48 47 45 42 bayt

(?)=gcd;a!b|c<-div a$a?b=(c*c?b,div b$c?b)

Fikir: Bunu fark ettim c*d = a*b/gcd(a,b). Böylece algoritma iki adım gerçekleştirir:

  1. İle başlayın c' = a/gcd(a,b)ve d' = b. Bu, bunun haricindeki tüm gereklilikleri yerine getirir c've d'birlikte kullanılmalıdır.
  2. Onları birlikte yapmak için hesaplar e = gcd(c',d')ve sonra c = c'*eve ayarlarım d = d'/e. Bu, tüm özellikleri korur (birleşik faktörler aynı kaldığından), ancak tüm paylaşılan faktörleri kaldırdığımdan d, yapıyorum cve demektarım.

Benim uygulamada, c'sadece denir c.

Çevrimiçi deneyin!

Laikoni sayesinde -3 bayt


Bağlamak için bir desen koruması kullanmak c3 bayt tasarruf sağlar: Çevrimiçi deneyin!
Laikoni

@ Laikoni Ooh, bu numarayı bile bilmiyordum. Teşekkürler!
Sacchan


2

R , 126 bayt

function(a,b,g=function(x,y)ifelse(o<-x%%y,g(y,o),y),l=a*b/g(a,b))matrix(c(C<-(1:l)[!l%%1:l],D<-l/C),,2)[g(C,D)<2&!a%%C+b%%D,]

Çevrimiçi deneyin!

Bu, değerleri bulmak için diğer R cevabından daha farklı (ve görünüşe göre daha az golfik) bir yaklaşım gerektirir .

Açıklama:

function(a,b){
 G <- function(x,y)ifelse(o<-x%%y,G(y,o),y) #gcd function, vectorized for x,y
 l <- a*b/g(a,b)                            #lcm of a,b
 C <- (1:l)[!l%%1:l]                        #divisors of l
 D <- l/C                                   #l/C is the other half of the pair
 rel_prime <- G(C, D) < 2                   #pairs where C,D are relatively prime, lol, GCD
 a_div <- !a%%C                             #divisors of a
 b_div <- !b%%D                             #divisors of b
 C <- C[rel_prime & a_div & b_div]
 D <- D[rel_prime & a_div & b_div]          #filter out the bad pairs
 matrix(c(C,D),,ncol = 2)                   #matrix of pairs, returned
}

dışında varsayılan argümanlar olarak tüm tanımları ayakkabı çeker ve golfiness için bir satırda tüm hesaplamaları yapmak.


2

J , 19 bayt

(*/:"1)&.|:&.(_&q:)

Çevrimiçi deneyin!

@ Lynn'in çözümüne dayanmaktadır .

açıklama

(*/:"1)&.|:&.(_&q:)  Input: [a, b]
              _&q:   Get exponenets of each prime
         |:&         Transpose
  /:"1 &             Grade each row
 *                   Multiply elementwise
       &.|:          Transpose
           &. _&q:   Convert exponents back to numbers

2

Haskell , 91 74 bayt

a!b=[(x,y)|x<-[1..a],y<-[1..b],rem a x+rem b y+gcd x y<2,lcm a b==lcm x y]

Çevrimiçi deneyin!

Kaydedilen 17 Laikoni sayesinde bayt


1
u*v`div`gcd u vbir bayt kaydeder.
Lynn

Yerleşik lcmişlevi kullanmamak için herhangi bir neden var mı ?
Laikoni

Ayrıca rem a x+rem b y+gcd x y<2çalışması gerekir.
Laikoni

@Laikoni çok iyi bir neden: Yerleşikin lcmvar olduğunu bile bilmiyordum . rem a x+rem b y+gcd x y<2işe yarıyor ve merak ediyorum eğer rem a x+rem b y+gcd x y+lcm a b-lcm x y<2 çalışıyor. Orada belki bir (matematiksel) garanti olduğunu lcm a b>=lcm x y.
jferard

1
Nitekim lcm a b>=lcm x y1. çünkü x=x1*...*xi(asal ayrışma), y=y1*...yj, lcm x y=z1*...*zknerede z1,...,zkortak olan x1,...,xive y1,...,yj. 2. a=u1*...*um*x1*...*xi(asal ayrışma), b=v1*...vn*y1*...yj, lcm a b=t1*...*tlnerede t1,...,tlortak olan u1*...*um*x1*...*xive v1*...vn*y1*...yj. Bu aşikardır t1,...,tliçeren z1,...,zkböylece lcm a b>=lcm x y. Ancak bu, koşulu bir miktar olarak yazmak için yararlı değildir.
jferard


1

Python 3 , 129 bayt

lambda a,b:[[c,d]for c in range(1,-~a)for d in range(1,-~b)if((gcd(c,d)<2)*a*b/gcd(a,b)==c*d/gcd(c,d))>a%c+b%d]
from math import*

Çevrimiçi deneyin!veya Test paketini deneyin.

Tüm olası kombinasyonları iç içe liste biçiminde çıktılar.


3
Sen ve bitsel şeyler ... -~ave -~btıpkı tekrar yazılabilir a+1ve b+1okunabilir olmaları için: P
Stephen

1
@Stephen Gördüğünüz gibi, ben uzmanlaşmak gizleme
Sn Xcoder

Yeni eklenen ikinci test çantam için çalışmıyor.
Leaky Nun

@LeakyNun Geri döndü. Golf geçerliliğini kontrol etmek için zaman yoktu.
Bay Xcoder

1

Jöle ,  19 15  14 bayt

İşaretçi ile -4 Leaky Nun (yerleşik bölen kullanın)

Neredeyse% 100 eminim, bunu yapmanın yolu bu değil, ama burada ilk deneme.
Bakalım kim yedi ya da sekiz byter ile bunu geçiyor!
Evet ... Lynn'in açıklamasına verdiği cevaba bakınız !

g/־l/
ÆDp/ÇÐṂ

İki sayının bir listesini alan ve olasılıkların bir listesini döndüren monadik bir bağlantı.

Çevrimiçi deneyin!

Nasıl?

g/־l/  - Link: gcd divided by lcm: list [x, y]
g/      - reduce by gcd = gcd(x, y)
   æl/  - reduce by lcm = lcm(x,y)
  ÷     - divide

ÆDp/ÇÐṂ - Main link: list [a, b]    e.g. [160, 90]
ÆD      - divisors (vectorises)          [[1,2,4,5,8,10,16,20,32,40,80,160],[1,2,3,5,6,9,10,15,18,30,45,90]]
  p/    - reduce by Cartesian product    [[1,1],[1,2],...,[1,90],[2,1],[2,2],...,[2,90],....,[160,90]]
     ÐṂ - entries for which this is minimal:
    Ç   -   call the last link (1) as a monad

Bakalım kim yedi ya da sekiz byter ile bunu geçiyor! - Sanmıyorum ...
Bay Xcoder

Altı mı düşünüyorsun? ...BEŞ?!
Jonathan Allan

: P Hayır ... ~ 13-15'ten daha az mümkün olduğunu düşünmüyorum (Dennis elbette aynı fikirde değil!)
Bay Xcoder

Divizör yerleşik mi?
Leaky Nun

Evet ÆDama (omuz silkmek) beyin açıkça viteste değil ...
Jonathan Allan

1

Perl 6 , 72 bayt

{([X] map {grep $_%%*,1..$_},@^a).grep:{([lcm] @a)==([lcm] $_)==[*] $_}}

Çevrimiçi deneyin!

Bir liste alır (a, b). Tüm olası listelerin bir listesini döndürür (c, d).

Açıklama:

-> @ab {
    # Generate all pairs (c, d)
    ([X]
         # where c divides a and d divides b.
         map { grep $_%%*, 1..$_ }, @ab)
    # Only keep pairs with lcm(a, b) = lcm(c, d) and lcm(c, d) = c * d.
    # The latter implies gcd(c, d) = 1.
    .grep: { ([lcm] @ab) == ([lcm] $_) == [*] $_ }
}


1

Python 2 + sympy , 148 bayt

from sympy import*
a,b=input()
c=d=z=1
while(a/c*c+b/d*d<a+b)+gcd(c,d)-1+(lcm(c,d)!=lcm(a,b)):E=c==d==z;Q=c==z;d=+E or Q+d;c=+Q or-~c;z+=E
print c,d

Çevrimiçi deneyin!

-1 Jonathan Frech sayesinde .

Bu cevap kullanarak, Python 2 (değil Python 3) çalışır sympy.gcdve sympy.lcmyerine math.gcdve math.lcmhangi Python 3. sunulduğunu Ve evet, bu kaba kuvvet olduğunu :)


Golf devam ediyor ...
Erik Outgolfer

Sen tanımlayarak bir byte kaydetmek mümkün olabilir Q=c==z;while döngüsünün başlangıcında (7 bayt) ve değiştirme or(c==z)+dile or Q+d(-4 bayt) ve c=+(c==z)orile c=+Q or(-4 bayt). ( TIO )
Jonathan Frech

Sadece bir soru olarak, kullandığınız +operatöre d=+Eveya c=+(c==z)bir tamsayı içine bir boolean dönüştürmek için?
Jonathan Frech

@JonathanFrech Evet, çünkü sen kullanamazsın Trueve Falseonun yerine 1ve 0senfonik olarak kullanamazsın.
Outgolfer Erik

Vanilya'nın nerelerde +...faydası olduğunu ilk gördüğüm örnek bu .
Jonathan Frech

1

Jöle , 13 bayt

Ụ€’×
ÆEz0ÇZÆẸ

Çevrimiçi deneyin! İlk Jelly cevabım! Düzenleme: ÆEz0µỤ€’×µZÆẸ13 bayt için de çalışır. Açıklama:

ÆE              Get prime factor exponents of both values (vectorises)
  z0            Zip but fill the shorter array with 0
    µ           New monadic link
     Ụ€         Grade up each pair (1-indexed)
       ’        Convert to 0-indexing (vectorises)
        ×       Multiply each pair by its grade (vectorises)
         µ      New monadic link
          Z     Zip back into separate lists of prime factor exponents
           ÆẸ   Turn prime exponent lists back into values (vectorises)

1

PARI / GP, 86 bayt

Bu Lynn'in cevabında söylediklerini yapar:

f(a,b)=forprime(p=2,a*b,v=valuation(a,p);w=valuation(b,p);if(w<v,b/=p^w,a/=p^v));[a,b]

Parçayı saymazsam f(a,b)=, 79 bayt olur.


1

05AB1E , 32 26 24 22 20 19 bayt

Ó0ζεD`›0sǝ}øεā<ØsmP

Çevrimiçi deneyin! Bu dilde nasıl yazılacağımı hala bilmiyorum, ama en azından kaba kuvvet algoritması değil. Açıklama:

Ó                       Get exponents of prime factors (vectorised)
 0ζ                     Zip, filling with 0
   ε      }             For each prime
    D`                  Extract the pair of exponents
      ›0sǝ              Overwrite the smaller with 0
           ø            Zip back into two lists of prime exponents
            ε           For each list (} implied)
             ā<Ø        Get a list of primes
                sm      Raise each prime to the exponent
                  P     Take the product

Ne yapıyor?
Lynn

Sizinkiyle aynı, ancak aslında üsleri çarpanlarına ayırarak ve karşılaştırarak ve faktörleri yeniden birleştirerek.
Neil
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.