Tạo hai số đồng nguyên tố trong khi bảo toàn bội số chung nhỏ nhất của chúng


20

Cho hai số nguyên dương ab, xuất ra hai số nguyên dương cdsao cho:

  • c chia a
  • d chia b
  • cdlà đồng nguyên tố
  • các bội số chung nhỏ nhất của cdbằng với bội số chung nhỏ nhất của ab.

Nếu có nhiều hơn một câu trả lời có thể, bạn chỉ có thể xuất một hoặc tất cả chúng.

Các trường hợp thử nghiệm:

 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

Đây là . Câu trả lời ngắn nhất trong byte thắng.


Điều gì ngăn tôi trở lại (1, LCM)?
Neil

1
@Neil Yêu cầu dphân chiab
Leaky Nun

4
Có lẽ bạn nên định nghĩa LCM hoặc ít nhất là không sử dụng từ viết tắt. Tôi không biết những gì đang được yêu cầu một chút.
Thuật sĩ lúa mì

Câu trả lời:


7

Thạch , 21 13 byte

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

Hãy thử trực tuyến!

Nếu a = 2 A · 3 B · 5 C · Mạnhb = 2 α · 3 β · 5 γ · Trà , thì chúng tôi tính toán

  • c = 2 A> α? A: 0 · 3 B>? B: 0 · 5 C>? C: 0 · Cách

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

Bây giờ lcm (c, d) = 2 max (A> α? A: 0, A> α? 0: α) · Ném = 2 max (A, α) · 3 max (B, β) · cách = lcm ( a, b)

gcd (c, d) = 2 min (A> α? A: 0, A> α? 0: α) · Riêu = 2 0 · 3 0 · 5 0 · Lỗi = 1 .

Nói cách khác: bắt đầu từ (c, d) = (a, b) . Sau đó, với mỗi số nguyên tố, hãy chia số nguyên tố đó ra khỏi hệ số của c hoặc d : bất kỳ số nào có số mũ nhỏ nhất cho số nguyên tố đó. (Trong triển khai này, trong trường hợp hòa, c mất số mũ của nó.)

Vậy nếu a = 2250 = 2 1 · 3 2 · 5 3b = 360 = 2 3 · 3 2 · 5 1 ,

thì c = 2 0 · 3 0 · 5 3 = 125d = 2 3 · 3 2 · 5 0 = 72 .

Jonathan Allan đánh gôn xuống 8 byte! Cảm ơn bạn


Đây là thuật toán ban đầu của tôi ... Thuật toán Perl tốt hơn.
Leaky Nun

Rất đẹp. Đây là 12 byte
Jonathan Allan

Đây là một 12 byterÆEZ×Ụ’$€$ZÆẸ
dặm

Điều này bây giờ [1,18]cho [15,18]. Phiên bản ban đầu đã trả về câu trả lời đúng ( [5,18]).
Arnauld

1
À - vâng, chúng tôi sẽ cần một filler bằng 0 trên transpose. ÆEz®0iṂ$¦€ZÆẸnên thực hiện thủ thuật cho 13.
Jonathan Allan

4

R, 143 139 123 byte

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")

(Cảm ơn @Giuseppe vì đã tắt 19 byte!)

Với các vết lõm, dòng mới và một số giải thích:

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

Các trường hợp thử nghiệm:

> 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 

!có quyền ưu tiên cao hơn &|thấp hơn +*; bạn sẽ có thể đánh gôn xuống một vài byte theo cách đó; tức là, !i%%q&j%%qnên tương đương với!i%%q+j%%q
Giuseppe

1
Được rồi quan sát tốt: nếu GCD(c,d)==1, sau đó LCM(c,d)==c*d. Vì vậy, chúng tôi có thể kiểm tra GCD(c,d)==1và sau đó kiểm tra xem c*d==a*b/GCD(a,b)vì sau này là LCM(a,b)...
Giuseppe

1
Thật! (mặc dù tính toán a*b/GCD(a,b)không ngắn hơn LCM(a,b)).
plannapus

120 byte - chức năng ẩn danh + dòng mới theo nghĩa đen cho -3 byte
Giuseppe

4

Husk , 10 byte

→ÖF§-⌋⌉ΠmḊ

Lực lượng vũ phu. Lấy và trả về danh sách, và cũng hoạt động với hơn hai số. Hãy thử trực tuyến!

Giải trình

→Ö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

Toán học, 82 byte

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

Tôi không chắc chắn, nhưng bạn có thể không sử dụng lập chỉ mục danh sách Select[...][[1]]thay vì First@Select[...]để lưu một byte không?
Jonathan Frech

có, nhưng sau đó tôi có thể sử dụng #&@@thay vì [[1]]để tiết kiệm thêm một lần nữa ;-)
J42161217

3

JavaScript (ES6), 90 84 80 byte

Lấy đầu vào theo cú pháp currying (a)(b)và trả về một mảng gồm 2 số nguyên.

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]

Các trường hợp thử nghiệm

Làm sao?

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 byte

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

Hãy thử trực tuyến!

Phương pháp tương tự như giải pháp Lynn của Jelly

Đã được một thời gian kể từ khi tôi sử dụng bất kỳ MATL (hoặc matlab nào cho vấn đề đó) nên có thể có nhiều cải tiến.


3

Haskell ,50 48 47 45 42 byte

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

Ý tưởng: Tôi nhận thấy rằng c*d = a*b/gcd(a,b). Vì vậy, thuật toán thực hiện hai bước:

  1. Bắt đầu với c' = a/gcd(a,b)d' = b. Điều này đáp ứng tất cả các yêu cầu ngoại trừ điều đó c'd'phải là đồng nguyên tố.
  2. Để làm cho chúng đồng nguyên tố, tôi tính toán e = gcd(c',d')và sau đó thiết lập c = c'*ed = d'/e. Điều này giữ cho tất cả các thuộc tính (vì các yếu tố kết hợp giữ nguyên), nhưng vì tôi loại bỏ tất cả các yếu tố được chia sẻ khỏi d, tôi thực hiện cdđồng thời.

Trong thực hiện của tôi, c'chỉ được gọi c.

Hãy thử trực tuyến!

-3 byte nhờ Laikoni


Sử dụng một bảo vệ mẫu để liên kết ctiết kiệm 3 byte: Hãy thử trực tuyến!
Laikoni

@Laikoni Ooh, tôi thậm chí không biết mẹo đó. Cảm ơn!
Sacchan


2

R , 126 byte

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,]

Hãy thử trực tuyến!

Điều này cần một cách tiếp cận khác (và dường như ít chơi gôn hơn) để tìm các giá trị so với câu trả lời R khác .

Giải trình:

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
}

ngoại trừ tôi đánh bóng tất cả các định nghĩa làm đối số mặc định và thực hiện tất cả các phép tính trên một dòng cho tính golf.


2

J , 19 byte

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

Hãy thử trực tuyến!

Dựa trên giải pháp của @ Lynn .

Giải trình

(*/:"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 byte

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]

Hãy thử trực tuyến!

Đã lưu 17 byte nhờ Laikoni


1
u*v`div`gcd u vtiết kiệm một byte.
Lynn

Có bất kỳ lý do để không sử dụng lcmchức năng tích hợp?
Laikoni

Cũng rem a x+rem b y+gcd x y<2nên làm việc.
Laikoni

@Laikoni một lý do rất chính đáng: Tôi thậm chí còn không biết nội dung lcmtồn tại. rem a x+rem b y+gcd x y<2hoạt động, và tôi tự hỏi nếu rem a x+rem b y+gcd x y+lcm a b-lcm x y<2 làm việc. Có thể có một (toán học) đảm bảo rằng lcm a b>=lcm x y.
jferard

1
Thật vậy, lcm a b>=lcm x ybởi vì 1. x=x1*...*xi(phân rã nguyên tố) y=y1*...yj, lcm x y=z1*...*zknơi z1,...,zkphổ biến x1,...,xiy1,...,yj. 2. a=u1*...*um*x1*...*xi(phân rã nguyên tố) b=v1*...vn*y1*...yj,, lcm a b=t1*...*tlnơi t1,...,tlphổ biến u1*...*um*x1*...*xiv1*...vn*y1*...yj. Rõ ràng là t1,...,tlcó chứa z1,...,zk, do đó lcm a b>=lcm x y. Nhưng điều đó không hữu ích để viết điều kiện dưới dạng tổng.
jferard

2

Python 2 , 75 byte

def f(x):n=1;exec'n+=1;j=k=1\nwhile x[j]%k<1:k*=n**j;j^=1\nx[j]/=k/n;'*x[0]

Đầu vào được lấy dưới dạng một danh sách, mà chức năng sửa đổi tại chỗ.

Hãy thử trực tuyến!


1

Python 3 , 129 byte

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*

Hãy thử trực tuyến! hoặc Thử bộ kiểm tra.

Xuất ra tất cả các kết hợp có thể dưới dạng một danh sách lồng nhau.


3
Bạn và công cụ bitwise của bạn ... -~a-~bcó thể được viết lại thành a+1b+1để dễ đọc: P
Stephen

1
@Stephen Như bạn có thể thấy, tôi chuyên về obfuscation
Ông Xcoder

Không hoạt động cho testcase thứ hai mới thêm của tôi.
Leaky Nun

@LeakyNun Cuộn lại. Không có thời gian để kiểm tra tính hợp lệ của golf.
Ông Xcoder

1

Thạch ,  19 15  14 byte

-4 với con trỏ từ Leaky Nun (sử dụng ước số tích hợp)

Tôi gần như chắc chắn 100% đây không phải là cách để thực sự làm điều này, nhưng đây là một nỗ lực đầu tiên.
Chúng ta hãy xem ai vượt qua nó bằng bảy hoặc tám lần!
Đúng ... xem câu trả lời của Lynn với lời giải thích!

g/־l/
ÆDp/ÇÐṂ

Một liên kết đơn âm lấy danh sách hai số và trả về danh sách các danh sách các khả năng.

Hãy thử trực tuyến!

Làm sao?

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

Chúng ta hãy xem ai vượt qua nó bằng bảy hoặc tám lần! - Đừng nghĩ vậy ...
Ông Xcoder

Bạn nghĩ sáu? ...SỐ NĂM?!
Jonathan Allan

: P Không ... Tôi không nghĩ ít hơn ~ 13-15 là có thể (dĩ nhiên Dennis sẽ không đồng ý!)
Ông Xcoder

Chia số tích hợp?
Leaky Nun

Vâng, ÆDnhưng (nhún vai) bộ não rõ ràng không có trong thiết bị ...
Jonathan Allan

1

Perl 6 , 72 byte

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

Hãy thử trực tuyến!

Đưa ra một danh sách (a, b). Trả về một danh sách tất cả các danh sách có thể (c, d).

Giải trình:

-> @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 byte

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

Hãy thử trực tuyến!

-1 cảm ơn Jonathan Frech .

Câu trả lời này hoạt động trong Python 2 (không phải Python 3), sử dụng sympy.gcdsympy.lcmthay vì math.gcdmath.lcmchỉ có sẵn trong Python 3. Và vâng, đây là vũ lực :)


Chơi gôn đang diễn ra ...
Erik the Outgolfer

Bạn có thể lưu một byte bằng cách xác định Q=c==z;(+7 byte) khi bắt đầu vòng lặp while và thay thế or(c==z)+dbằng or Q+d(-4 byte) và c=+(c==z)orbằng c=+Q or(-4 byte). ( TIO )
Jonathan Frech

Cũng giống như một câu hỏi, bạn đang sử dụng +toán tử trong d=+Ehoặc c=+(c==z)để chuyển đổi một boolean thành một số nguyên?
Jonathan Frech

@JonathanFrech Vâng, tôi là vậy, vì bạn không thể sử dụng TrueFalsethay vào đó 10trong sympy.
Erik the Outgolfer

Đó là ví dụ đầu tiên tôi từng thấy nơi vani +...có công dụng.
Jonathan Frech

1

Thạch , 13 byte

Ụ€’×
ÆEz0ÇZÆẸ

Hãy thử trực tuyến! Câu trả lời Jelly đầu tiên của tôi! Chỉnh sửa: ÆEz0µỤ€’×µZÆẸcũng hoạt động cho 13 byte. Giải trình:

Æ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 byte

Đây chỉ là những gì Lynn nói trong câu trả lời của mình:

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]

If I do not count the f(a,b)= part, it is 79 bytes.


1

05AB1E, 32 26 24 22 20 19 bytes

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

Try it online! I still have no idea how to write in this language, but at least it's not a brute-force algorithm. Explanation:

Ó                       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

What’s it doing?
Lynn

Same as yours, but by actually factorising and comparing the exponents and recombining the factors.
Neil
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.