Haz que dos números co-primen mientras conservas su mínimo común múltiplo

20

Dados dos enteros positivos ay b, generar dos enteros positivos cy dtal que:

Si hay más de una respuesta posible, puede generar solo una o todas.

Casos de prueba:

 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

Este es el . La respuesta más corta en bytes gana.

Monja permeable
fuente
¿Qué me impide volver (1, LCM)?
Neil
1
@Neil El requisito que ddivideb
Leaky Nun
44
Tal vez deberías definir LCM o al menos no usar el acrónimo. No sabía lo que se pedía un poco.
Wheat Wizard

Respuestas:

7

Jalea , 21 13 bytes

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

Pruébalo en línea!

Si a = 2 A · 3 B · 5 C · ... y b = 2 α · 3 β · 5 γ · ... , entonces calculamos

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

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

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

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

En otras palabras: comenzar desde (c, d) = (a, b) . Entonces, para cada primo, brecha que el primer todo el camino de la factorización de cualquiera de C o D : el que tenga el menor exponente para que el primer. (En esta implementación, en caso de empate, c pierde su exponente).

Así que si a = 2,250 = 2 1 · 3 2 · 5 3 y b = 360 = 2 3 · 3 2 · 5 1 ,

a continuación, c = 2 0 · 3 0 · 5 3 = 125 y d = 2 3 · 3 2 · 5 0 = 72 .

¡Jonathan Allan jugó unos 8 bytes! Gracias ~

Lynn
fuente
Este es mi algoritmo original ... El algoritmo Perl es mejor.
Leaky Nun
Muy agradable. Aquí está en 12 bytes
Jonathan Allan
Aquí hay otro 12 byterÆEZ×Ụ’$€$ZÆẸ
millas
Esto ahora da [1,18]por hecho [15,18]. La versión inicial estaba devolviendo la respuesta correcta ( [5,18]).
Arnauld
1
Ah, sí, necesitaríamos un relleno de cero en la transposición. ÆEz®0iṂ$¦€ZÆẸdebería hacer el truco para 13.
Jonathan Allan
4

R, 143 139 123 bytes

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

(¡Gracias a @Giuseppe por esos 19 bytes de descuento!)

Con hendiduras, nuevas líneas y algunas explicaciones:

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

Casos de prueba:

> 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 
plannapus
fuente
!tiene mayor prioridad que &y |pero menor que +y *; deberías poder jugar unos pocos bytes de esa manera; es decir, !i%%q&j%%qdebería ser equivalente a!i%%q+j%%q
Giuseppe
1
Bien, bien observación: si GCD(c,d)==1, entonces LCM(c,d)==c*d. Entonces podemos probar GCD(c,d)==1y luego verificar si c*d==a*b/GCD(a,b)este último es LCM(a,b)...
Giuseppe
1
¡En efecto! (aunque el cálculo a*b/GCD(a,b)no es más corto que LCM(a,b)).
plannapus
120 bytes - función anónima + nueva línea literal para -3 bytes
Giuseppe
4

Casco , 10 bytes

→ÖF§-⌋⌉ΠmḊ

Fuerza bruta. Toma y devuelve listas, y también funciona para más de dos números. Pruébalo en línea!

Explicación

→Ö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]
Zgarb
fuente
3

Mathematica, 82 bytes

#&@@Select[Subsets[Flatten@Divisors[{t=#,r=#2}],{2}],GCD@@#==1&&LCM@@#==t~LCM~r&]&
J42161217
fuente
No estoy seguro, pero ¿no podría usar la indexación de listas en Select[...][[1]]lugar de First@Select[...]guardar un byte?
Jonathan Frech
sí, pero podría usar en #&@@lugar de [[1]]guardar uno más ;-)
J42161217
3

JavaScript (ES6), 90 84 80 bytes

Toma la entrada en la sintaxis de curry (a)(b)y devuelve una matriz de 2 enteros.

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]

Casos de prueba

¿Cómo?

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
Arnauld
fuente
3

MATL , 17 16 bytes

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

Pruébalo en línea!

El mismo método que la solución de jalea de Lynn

Ha pasado un tiempo desde que usé cualquier MATL (o matlab para el caso), es probable que haya muchas mejoras posibles.

B. Mehta
fuente
3

Haskell ,50 48 47 45 42 bytes

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

Idea: me di cuenta de eso c*d = a*b/gcd(a,b). Entonces el algoritmo realiza dos pasos:

  1. Comience con c' = a/gcd(a,b)y d' = b. Esto cumple con todos los requisitos, excepto eso c'y d'tiene que ser primo.
  2. Para que sean primos, calculo e = gcd(c',d')y luego establezco c = c'*ey d = d'/e. Esto mantiene todas las propiedades (ya que los factores combinados permanecen iguales), pero como elimino todos los factores compartidos d, creo cy dcoprimo.

En mi implementación, c'solo se llama c.

Pruébalo en línea!

-3 bytes gracias a Laikoni

Sacchan
fuente
Usar un protector de patrón para enlazar cahorra 3 bytes: ¡ Pruébelo en línea!
Laikoni
@Laikoni Ooh, ni siquiera sabía ese truco. ¡Gracias!
Sacchan
2

R , 126 bytes

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

Pruébalo en línea!

Esto toma un enfoque diferente (y aparentemente menos golfista) para encontrar los valores que la otra respuesta R .

Explicación:

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
}

excepto que calzo todas las definiciones como argumentos predeterminados y hago todos los cálculos en una línea para el golf.

Giuseppe
fuente
2

J , 19 bytes

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

Pruébalo en línea!

Basado en @ Lynn's solución de .

Explicación

(*/:"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
millas
fuente
2

Haskell , 91 74 bytes

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]

Pruébalo en línea!

Guardado 17 bytes gracias a Laikoni

jferard
fuente
1
u*v`div`gcd u vGuarda un byte.
Lynn
¿Hay alguna razón para no usar la lcmfunción incorporada?
Laikoni
También rem a x+rem b y+gcd x y<2debería funcionar.
Laikoni
@Laikoni, una muy buena razón: ni siquiera sabía que lcmexistía la construcción . rem a x+rem b y+gcd x y<2funciona, y me pregunto si rem a x+rem b y+gcd x y+lcm a b-lcm x y<2 funciona. Hay tal vez un (matemática) garantía de que lcm a b>=lcm x y.
jferard
1
De hecho, lcm a b>=lcm x ydebido a 1. x=x1*...*xi(primer descomposición), y=y1*...yj, lcm x y=z1*...*zken donde z1,...,zkson comunes a x1,...,xiy y1,...,yj. 2. a=u1*...*um*x1*...*xi(descomposición primaria) b=v1*...vn*y1*...yj, lcm a b=t1*...*tldonde t1,...,tlson comunes a u1*...*um*x1*...*xiy v1*...vn*y1*...yj. Es obvio que t1,...,tlcontiene z1,...,zk, por lo tanto lcm a b>=lcm x y. Pero eso no es útil para escribir la condición como una suma.
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]

La entrada se toma como una lista, que la función modifica en su lugar.

Pruébalo en línea!

Dennis
fuente
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*

Pruébalo en línea! o Prueba la suite de prueba.

Emite todas las combinaciones posibles en forma de una lista anidada.

Sr. Xcoder
fuente
3
Usted y sus cosas bit a bit ... -~ay -~bpueden reescribirse como a+1y b+1para facilitar su lectura: P
Stephen
1
@Stephen Como puede ver, me especializo en ofuscación
Sr. Xcoder
No funciona para mi segundo caso de prueba recién agregado.
Leaky Nun
@LeakyNun Rodó hacia atrás. No tuve tiempo para verificar la validez del golf.
Sr. Xcoder
1

Jalea ,  19 15  14 bytes

-4 con puntero de Leaky Nun (usar divisor incorporado)

Estoy casi 100% seguro de que esta no es la forma de hacerlo, pero aquí hay un primer intento.
¡Veamos quién lo supera con un byte de siete u ocho!
Sí ... ¡mira la respuesta de Lynn con explicación!

g/־l/
ÆDp/ÇÐṂ

Un enlace monádico que toma una lista de los dos números y devuelve una lista de listas de posibilidades.

Pruébalo en línea!

¿Cómo?

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
Jonathan Allan
fuente
¡Veamos quién lo supera con un byte de siete u ocho! - No lo creo ...
Sr. Xcoder
¿Crees que seis? ...¡¿CINCO?!
Jonathan Allan
: P No ... no creo que sea posible menos de ~ 13-15 (¡Dennis no estaría de acuerdo, por supuesto!)
Sr. Xcoder
Divisor incorporado?
Leaky Nun
Sí, ÆDpero (encogiéndose de hombros) el cerebro obviamente no está en marcha ...
Jonathan Allan
1

Perl 6 , 72 bytes

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

Pruébalo en línea!

Toma una lista (a, b). Devuelve una lista de todas las listas posibles (c, d).

Explicación:

-> @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] $_) == [*] $_ }
}
nwellnhof
fuente
1

Python 2 , 126 121 bytes

def f(a,b):
 c=[1,1];p=2
 while p<=a*b:
	t=m=1
	while(a*b)%p<1:m*=p;t=b%p<1;a/=p**(a%p<1);b/=p**t
	p+=1;c[t]*=m
 return c

Pruébalo en línea!

Chas Brown
fuente
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

Pruébalo en línea!

-1 gracias a Jonathan Frech .

Esta respuesta funciona en Python 2 (no Python 3), usando sympy.gcdy en sympy.lcmlugar de math.gcdy math.lcmque solo están disponibles en Python 3. Y sí, esta es la fuerza bruta :)

Erik el Outgolfer
fuente
Golf en progreso ...
Erik the Outgolfer
Puede guardar un byte definiendo Q=c==z;(+7 bytes) al comienzo del ciclo while y reemplazándolo or(c==z)+dcon or Q+d(-4 bytes) y c=+(c==z)orcon c=+Q or(-4 bytes). ( TIO )
Jonathan Frech
Solo como una pregunta, ¿está utilizando el +operador en d=+Eo c=+(c==z)para convertir un booleano en un entero?
Jonathan Frech
@JonathanFrech Sí, ya que no puedes usar Truey en Falselugar de 1y 0en sympy.
Erik the Outgolfer
Esa es la primera vez que vi donde la vainilla +...tiene algún uso.
Jonathan Frech
1

Jalea , 13 bytes

Ụ€’×
ÆEz0ÇZÆẸ

Pruébalo en línea! Mi primera respuesta Jelly! Editar: ÆEz0µỤ€’×µZÆẸtambién funciona para 13 bytes. Explicación:

Æ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)
Neil
fuente
1

PARI / GP, 86 bytes

Esto solo hace lo que dice Lynn en su respuesta:

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]

Si no cuento el f(a,b)= parte, son 79 bytes.

Jeppe Stig Nielsen
fuente
1

05AB1E , 32 26 24 22 20 19 bytes

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

Pruébalo en línea! Todavía no tengo idea de cómo escribir en este idioma, pero al menos no es un algoritmo de fuerza bruta. Explicación:

Ó                       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
Neil
fuente
¿Que esta haciendo?
Lynn
Igual que el tuyo, pero factorizando y comparando los exponentes y recombinando los factores.
Neil