Crea due numeri in primo piano preservando il loro minimo comune multiplo


20

Dati due numeri interi positivi ae b, genera due numeri interi positivi ce dtali che:

  • c divide a
  • d divide b
  • ce dsono co-primi
  • il minimo comune multiplo di ce duguale al minimo comune multiplo di ae b.

Se ci sono più di una possibile risposta, è possibile produrre solo una o tutte.

Casi test:

 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

Questo è . Vince la risposta più breve in byte.


Cosa mi impedisce di tornare (1, LCM)?
Neil,

1
@Neil Il requisito che ddivideb
Leaky Nun,

4
Forse dovresti definire LCM o almeno non usare l'acronimo. Non sapevo cosa mi chiedesse un po '.
Mago del grano,

Risposte:


7

Gelatina , 21 13 byte

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

Provalo online!

Se a = 2 A · 3 B · 5 C ·… e b = 2 α · 3 β · 5 γ ·… , calcoliamo

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

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

Ora mcm (c, d) = 2 max (A> α? A: 0, A> α? 0: α) ·… = 2 max (A, α) · 3 max (B, β) ·… = mcm ( a, b)

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

In altre parole: inizia da (c, d) = (a, b) . Quindi, per ogni primo, dividi quel primo completamente fuori dalla fattorizzazione di c o d : qualunque sia l'esponente più piccolo per quel primo. (In questa implementazione, in caso di pareggio, c perde il suo esponente.)

Quindi, se a = 2250 = 2 1 · 3 2 · 5 3 e b = 360 = 2 3 · 3 2 · 5 1 ,

quindi c = 2 0 · 3 0 · 5 3 = 125 e d = 2 3 · 3 2 · 5 0 = 72 .

Jonathan Allan ha giocato a golf con ben 8 byte! Grazie ~


Questo è il mio algoritmo originale ... L'algoritmo Perl è migliore.
Leaky Nun,

Molto bella. Eccolo in 12 byte
Jonathan Allan,

Ecco un altro 12 byterÆEZ×Ụ’$€$ZÆẸ
miglia

Questo ora dà [1,18]per [15,18]. La versione iniziale stava restituendo la risposta corretta ( [5,18]).
Arnauld,

1
Ah - sì, avremmo bisogno di un filler pari a zero sulla trasposizione. ÆEz®0iṂ$¦€ZÆẸdovrebbe fare il trucco per 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")

(Grazie a @Giuseppe per quei 19 byte di sconto!)

Con rientri, nuove righe e alcune spiegazioni:

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

Casi test:

> 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 

!ha una precedenza maggiore di &e |ma inferiore di +e *; dovresti essere in grado di giocare a golf di qualche byte in quel modo; cioè, !i%%q&j%%qdovrebbe essere equivalente a!i%%q+j%%q
Giuseppe,

1
Va bene osservazione: se GCD(c,d)==1, allora LCM(c,d)==c*d. Quindi possiamo testare GCD(c,d)==1e poi verificare se c*d==a*b/GCD(a,b)dal momento che quest'ultimo è LCM(a,b)...
Giuseppe,

1
Infatti! (sebbene il calcolo a*b/GCD(a,b)non sia più breve di LCM(a,b)).
plannapus,

120 byte - funzione anonima + newline letterale per -3 byte
Giuseppe

4

Buccia , 10 byte

→ÖF§-⌋⌉ΠmḊ

Forza bruta. Prende e restituisce elenchi e funziona anche per più di due numeri.Provalo online!

Spiegazione

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

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

Non ne sono sicuro, ma non è possibile utilizzare l'indicizzazione dell'elenco Select[...][[1]]invece di First@Select[...]salvare un byte?
Jonathan Frech,

si, ma poi potrei usarlo #&@@invece di [[1]]salvarne un altro ;-)
J42161217

3

JavaScript (ES6), 90 84 80 byte

Accetta input nella sintassi del curry (a)(b)e restituisce un array di 2 numeri interi.

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]

Casi test

Come?

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

Provalo online!

Stesso metodo della soluzione Jelly di Lynn

È da un po 'che non uso MATL (o MATLAB per quella materia), quindi molti miglioramenti sono probabilmente possibili.


3

Haskell ,50 48 47 45 42 byte

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

Idea: l'ho notato c*d = a*b/gcd(a,b). Quindi l'algoritmo esegue due passaggi:

  1. Inizia con c' = a/gcd(a,b)e d' = b. Ciò soddisfa tutti i requisiti tranne quello c'e d'deve essere co-prime.
  2. Per farli co-prime, calcolo e = gcd(c',d')e poi setto c = c'*ee d = d'/e. Ciò mantiene tutte le proprietà (poiché i fattori combinati rimangono gli stessi), ma poiché rimuovo tutti i fattori condivisi da d, creo ce dcoprimi.

Nella mia implementazione, c'è appena chiamato c.

Provalo online!

-3 byte grazie a Laikoni


L'uso di un pattern guard per il binding cconsente di risparmiare 3 byte: provalo online!
Laikoni,

@Laikoni Ooh, non sapevo nemmeno quel trucco. Grazie!
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,]

Provalo online!

Questo ha un approccio diverso (e apparentemente meno golfico) nel trovare i valori rispetto all'altra risposta R .

Spiegazione:

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
}

tranne che calzascarpe tutte le definizioni come argomenti predefiniti e faccio tutti i calcoli su una riga per il golfiness.


2

J , 19 byte

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

Provalo online!

Basato sulla soluzione di @ Lynn .

Spiegazione

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

Provalo online!

Risparmiato 17 byte grazie a Laikoni


1
u*v`div`gcd u vsalva un byte.
Lynn,

C'è qualche motivo per non usare la lcmfunzione integrata?
Laikoni,

Inoltre rem a x+rem b y+gcd x y<2dovrebbe funzionare.
Laikoni,

@Laikoni un ottimo motivo: non sapevo nemmeno che lcmesistesse il builtin . rem a x+rem b y+gcd x y<2funziona e mi chiedo se rem a x+rem b y+gcd x y+lcm a b-lcm x y<2 funziona. C'è forse una garanzia (matematica) che lcm a b>=lcm x y.
jferard,

1
Anzi, lcm a b>=lcm x yperché 1. x=x1*...*xi(decomposizione primaria) y=y1*...yj, lcm x y=z1*...*zkdove z1,...,zksono comuni x1,...,xie y1,...,yj. 2. a=u1*...*um*x1*...*xi(decomposizione primaria) b=v1*...vn*y1*...yj, lcm a b=t1*...*tldove t1,...,tlsono comuni a u1*...*um*x1*...*xie v1*...vn*y1*...yj. È ovvio che t1,...,tlcontiene z1,...,zk, quindi lcm a b>=lcm x y. Ma questo non è utile per scrivere la condizione come somma.
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]

L'input viene preso come un elenco, che la funzione modifica in atto.

Provalo online!


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*

Provalo online! oppure Prova la suite di test.

Emette tutte le possibili combinazioni sotto forma di un elenco nidificato.


3
Tu e le tue cose bitwise ... -~ae -~bpotete semplicemente riscriverle come a+1e b+1per leggibilità: P
Stephen,

1
@Stephen Come puoi vedere, sono specializzato in offuscamento
Mr. Xcoder,

Non funziona per il mio secondo testcase appena aggiunto.
Leaky Nun,

@LeakyNun Eseguito il rollback. Non ho avuto il tempo di verificare la validità del golf.
Mr. Xcoder,

1

Gelatina ,  19 15  14 byte

-4 con puntatore da Leaky Nun (usa il divisore incorporato)

Sono quasi sicuro al 100% che questo non è il modo di farlo, ma ecco un primo tentativo.
Vediamo chi lo supera con un sette o otto byter!
Sì ... vedi la risposta di Lynn con spiegazione!

g/־l/
ÆDp/ÇÐṂ

Un collegamento monadico che prende un elenco dei due numeri e restituisce un elenco di elenchi delle possibilità.

Provalo online!

Come?

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

Vediamo chi lo supera con un sette o otto byter! - Non la penso così ...
Mr. Xcoder,

Ne pensi sei? ...CINQUE?!
Jonathan Allan,

: P No ... Non credo che sia possibile meno di ~ 13-15 (Dennis non sarebbe d'accordo, ovviamente!)
Mr. Xcoder

Divisor integrato?
Leaky Nun,

ÆDma il cervello (scrollando le spalle) ovviamente non è in marcia ...
Jonathan Allan,

1

Perl 6 , 72 byte

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

Provalo online!

Prende un elenco (a, b). Restituisce un elenco di tutti gli elenchi possibili (c, d).

Spiegazione:

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

Provalo online!

-1 grazie a Jonathan Frech .

Questa risposta funziona in Python 2 (non in Python 3), usando sympy.gcde sympy.lcminvece di math.gcde math.lcmche sono disponibili solo in Python 3. E sì, questa è forza bruta :)


Giocare a golf in corso ...
Erik the Outgolfer,

È possibile salvare un byte definendo Q=c==z;(+7 byte) all'inizio del ciclo while e sostituendolo or(c==z)+dcon or Q+d(-4 byte) e c=+(c==z)orcon c=+Q or(-4 byte). ( TIO )
Jonathan Frech,

Proprio come una domanda, stai usando l' +operatore d=+Eo c=+(c==z)per convertire un valore booleano in un numero intero?
Jonathan Frech,

@JonathanFrech Sì, dato che non puoi usare Truee Falseinvece di 1e 0in sintonia.
Erik the Outgolfer,

Questo è il primo caso che abbia mai visto dove la vaniglia +...ha qualche utilità.
Jonathan Frech,

1

Gelatina , 13 byte

Ụ€’×
ÆEz0ÇZÆẸ

Provalo online! La mia prima risposta Jelly! Modifica: ÆEz0µỤ€’×µZÆẸfunziona anche per 13 byte. Spiegazione:

Æ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

Questo fa proprio quello che dice Lynn nella sua risposta:

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]

Se non conto la f(a,b)=parte, sono 79 byte.


1

05AB1E , 32 26 24 22 20 19 byte

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

Provalo online! Non ho ancora idea di come scrivere in questa lingua, ma almeno non è un algoritmo a forza bruta. Spiegazione:

Ó                       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

Che cosa sta facendo?
Lynn,

Come il tuo, ma concretizzando e confrontando gli esponenti e ricombinando i fattori.
Neil,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.