Ułóż dwie liczby jednocześnie, zachowując ich najmniejszą wspólną wielokrotność


20

Biorąc pod uwagę dwie dodatnie liczby całkowite ai bwyprowadzamy dwie dodatnie liczby całkowite ci dtakie, że:

Jeśli istnieje więcej niż jedna możliwa odpowiedź, możesz wydrukować tylko jedną lub wszystkie z nich.

Przypadki testowe:

 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

To jest . Najkrótsza odpowiedź w bajtach wygrywa.


Co powstrzyma mnie przed powrotem (1, LCM)?
Neil

1
@Neil Wymóg, który ddzielib
Leaky Nun

4
Może powinieneś zdefiniować LCM, a przynajmniej nie używać akronimu. Nie wiedziałem, o co proszono.
Wheat Wizard

Odpowiedzi:


7

Galaretka , 21 13 bajtów

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

Wypróbuj online!

W przypadku a = 2 · 3 B · 5 C · ... i b = 2 α · 3 β · 5 γ · ... , a następnie obliczyć

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

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

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

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

Innymi słowy: zacznij od (c, d) = (a, b) . Następnie, dla każdej liczby pierwszej, podziel tę liczbę pierwszą do faktoryzacji albo c lub d : w zależności od tego, który ma najmniejszy wykładnik dla tej liczby pierwszej. (W tej implementacji, w przypadku remisu, c traci wykładnik).

Więc jeśli a = 2250 = 2 1 · 3 2 · 5 3 i b = 360 = 2 3 · 3 2 · 5 1 ,

następnie c = 2 0 · 3 0 · 5 3 = 125 i D = 2 3 · 3 2 · 5 0 = 72 .

Jonathan Allan grał w golfa aż 8 bajtów! Dziękuję ~


To jest mój oryginalny algorytm ... Algorytm Perla jest lepszy.
Leaky Nun

Bardzo dobrze. Tutaj jest w 12 bajtach
Jonathan Allan

Oto kolejne 12 bajtówÆEZ×Ụ’$€$ZÆẸ
mile

To daje teraz [1,18]za [15,18]. Początkowa wersja zwracała poprawną odpowiedź ( [5,18]).
Arnauld,

1
Ach - tak, potrzebowalibyśmy wypełnienia zerowego podczas transpozycji. ÆEz®0iṂ$¦€ZÆẸpowinien załatwić sprawę za 13.
Jonathan Allan

4

R, 143 139 123 bajtów

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

(Dzięki @Giuseppe za 19 bajtów off!)

Z wcięciami, znakami nowej linii i niektórymi objaśnieniami:

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

Przypadki testowe:

> 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 

!ma wyższy priorytet niż &a |, ale niższa niż +a *; powinieneś być w stanie grać w golfa o kilka bajtów w ten sposób; tzn. !i%%q&j%%qpowinien być równoważny z!i%%q+j%%q
Giuseppe

1
Dobra obserwacja: jeśli GCD(c,d)==1, to LCM(c,d)==c*d. Możemy więc przetestować, GCD(c,d)==1a następnie sprawdzić, czy c*d==a*b/GCD(a,b)skoro to drugie jest LCM(a,b)...
Giuseppe,

1
W rzeczy samej! (choć obliczenia a*b/GCD(a,b)nie są krótsze niż LCM(a,b)).
plannapus

120 bajtów - funkcja anonimowa + dosłowny znak nowej linii dla -3 bajtów
Giuseppe

4

Łuska , 10 bajtów

→ÖF§-⌋⌉ΠmḊ

Brutalna siła. Pobiera i zwraca listy i działa również dla więcej niż dwóch liczb. Wypróbuj online!

Wyjaśnienie

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

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

Nie jestem pewien, ale czy nie możesz użyć indeksowania list Select[...][[1]]zamiast First@Select[...]zapisać bajt?
Jonathan Frech

tak, ale wtedy mógłbym użyć #&@@zamiast [[1]]zaoszczędzić jeszcze jednego ;-)
J42161217

3

JavaScript (ES6), 90 84 80 bajtów

Pobiera dane wejściowe w składni curry (a)(b)i zwraca tablicę 2 liczb całkowitych.

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]

Przypadki testowe

W jaki sposób?

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 bajtów

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

Wypróbuj online!

Ta sama metoda, co rozwiązanie Jelly firmy Lynn

Minęło trochę czasu, odkąd użyłem MATL (lub Matlaba w tym przypadku), więc prawdopodobnie jest możliwych wiele ulepszeń.


3

Haskell ,50 48 47 45 42 bajty

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

Pomysł: zauważyłem to c*d = a*b/gcd(a,b). Algorytm wykonuje więc dwa kroki:

  1. Zacznij od c' = a/gcd(a,b)i d' = b. Spełnia to wszystkie wymagania oprócz tego c'i d'musi być współdzielone.
  2. Aby uczynić je pierwszymi, obliczam, e = gcd(c',d')a następnie ustawiam c = c'*ei d = d'/e. Zachowuje to wszystkie właściwości (ponieważ połączone czynniki pozostają takie same), ale ponieważ usuwam wszystkie wspólne czynniki d, tworzę ci dkopiuję.

W mojej implementacji c'właśnie się nazywa c.

Wypróbuj online!

-3 bajty dzięki Laikoni


Użycie osłony wzoru do wiązania cpozwala zaoszczędzić 3 bajty: Wypróbuj online!
Laikoni

@Laikoni Ooh, nawet nie znałem tej sztuczki. Dzięki!
Sacchan


2

R , 126 bajtów

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

Wypróbuj online!

To wymaga innego (i pozornie mniej Golfy) podejście do znalezienia wartości niż drugi R odpowiedź .

Wyjaśnienie:

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
}

z wyjątkiem tego, że podsuwam wszystkie definicje jako domyślne argumenty i wykonuję wszystkie obliczenia w jednym wierszu dla golfisty.


2

J , 19 bajtów

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

Wypróbuj online!

Na podstawie rozwiązania @ Lynn .

Wyjaśnienie

(*/:"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 bajtów

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]

Wypróbuj online!

Zaoszczędź 17 bajtów dzięki Laikoni


1
u*v`div`gcd u vzapisuje bajt.
Lynn

Czy jest jakiś powód, aby nie korzystać z wbudowanej lcmfunkcji?
Laikoni

rem a x+rem b y+gcd x y<2Powinien też działać.
Laikoni

@Laikoni bardzo dobry powód: nawet nie wiedziałem, że wbudowane lcmistniało. rem a x+rem b y+gcd x y<2działa i zastanawiam się, czy rem a x+rem b y+gcd x y+lcm a b-lcm x y<2 działa. Być może istnieje (matematyczna) gwarancja lcm a b>=lcm x y.
Jferard

1
Rzeczywiście, lcm a b>=lcm x yponieważ 1. x=x1*...*xi(rozkład pierwotny) y=y1*...yj, lcm x y=z1*...*zkgdzie z1,...,zksą wspólne dla x1,...,xii y1,...,yj. 2. a=u1*...*um*x1*...*xi(rozkład pierwotny) b=v1*...vn*y1*...yj, lcm a b=t1*...*tlgdzie t1,...,tlsą wspólne dla u1*...*um*x1*...*xii v1*...vn*y1*...yj. To oczywiste, że t1,...,tlzawiera z1,...,zk, w ten sposób lcm a b>=lcm x y. Ale to nie jest przydatne do zapisania warunku jako sumy.
Jferard

2

Python 2, 75 bytes

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]

Input is taken as a list, which the function modifies in place.

Try it online!


1

Python 3, 129 bytes

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*

Try it online! or Try the test suite.

Outputs all possible combinations in the form of a nested list.


3
You and your bitwise stuff... -~a and -~b can just be rewritten as a+1 and b+1 for readability :P
Stephen

1
@Stephen As you can see, I specialize in obfuscation
Mr. Xcoder

Doesn't work for my newly added second testcase.
Leaky Nun

@LeakyNun Rolled back. Didn't have time to check the validity of the golf.
Mr. Xcoder

1

Jelly,  19 15  14 bytes

-4 with pointer from Leaky Nun (use divisor built-in)

I am almost 100% certain this is not the way to actually do this one, but here is a first attempt.
Let's see who outgolfs it with a seven or eight byter!
Yep... see Lynn's answer with explanation!

g/־l/
ÆDp/ÇÐṂ

A monadic link taking a list of the two numbers and returning a list of lists of the possibilities.

Try it online!

How?

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

Let's see who outgolfs it with a seven or eight byter! - Don't think so...
Mr. Xcoder

You think six? ...FIVE?!
Jonathan Allan

:P No... I don't think less than ~13-15 is possible (Dennis would disagree, of course!)
Mr. Xcoder

Divisor built-in?
Leaky Nun

Yeah ÆD but (shrug) brain obviously not in gear...
Jonathan Allan

1

Perl 6, 72 bytes

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

Try it online!

Takes a list (a, b). Returns a list of all possible lists (c, d).

Explanation:

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

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

Try it online!

-1 thanks to Jonathan Frech.

This answer works in Python 2 (not Python 3), using sympy.gcd and sympy.lcm instead of math.gcd and math.lcm which are only available in Python 3. And yes, this is brute force :)


Golfing in progress...
Erik the Outgolfer

You may be able to save a byte by defining Q=c==z; (+7 bytes) at the start of the while loop and replacing or(c==z)+d with or Q+d (-4 bytes) and c=+(c==z)or with c=+Q or (-4 bytes). (TIO)
Jonathan Frech

Just as a question, are you using the + operator in d=+E or c=+(c==z) to convert a boolean into an integer?
Jonathan Frech

@JonathanFrech Yes I am, since you can't use True and False instead of 1 and 0 in sympy.
Erik the Outgolfer

That is the first instance I ever saw where the vanilla +... has any use.
Jonathan Frech

1

Jelly, 13 bytes

Ụ€’×
ÆEz0ÇZÆẸ

Try it online! My first Jelly answer! Edit: ÆEz0µỤ€’×µZÆẸ also works for 13 bytes. Explanation:

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

This just does what Lynn says in her answer:

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.