Faça dois números co-prime enquanto preserva o múltiplo menos comum

20

Dado dois inteiros positivos ae b, produz dois inteiros positivos ce dtal que:

  • c divide a
  • d divide b
  • ce dsão co-prime
  • o múltiplo menos comum de ce dé igual ao múltiplo menos comum de ae b.

Se houver mais de uma resposta possível, você poderá gerar apenas uma ou todas elas.

Casos de teste:

 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

Isso é . A resposta mais curta em bytes vence.

Freira Furada
fonte
O que me impede de retornar (1, LCM)?
Neil
1
@Neil O requisito que ddivideb
Leaky Nun
4
Talvez você deva definir o LCM ou pelo menos não usar o acrônimo. Eu não sabia o que estava sendo pedido um pouco.
Assistente de trigo

Respostas:

7

Geléia , 21 13 bytes

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

Experimente online!

Se a = 2 Um · 3 B · 5 C · ... e b = 2 α · 3 β · 5 γ · ... , em seguida, calcular

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

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

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

e mcd (c, d) = 2 min (A> α <A: 0, A> α <0: α) · ... = 2 0 · 3 0 · 5 0 · ... = 1 .

Em outras palavras: comece com (c, d) = (a, b) . Então, para cada privilegiada, divisão que o primeiro- todo o caminho para fora da fatoração de qualquer c ou d : o que tem o menor expoente para que prime. (Nesta implementação, em caso de empate, c perde seu expoente.)

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

em seguida, c = 2 0 · 3 0 · 5 3 = 125 e d = 2 3 · 3 2 · 5 0 = 72 .

Jonathan Allan jogou uns incríveis 8 bytes! Obrigado ~

Lynn
fonte
Este é o meu algoritmo original ... O algoritmo Perl é melhor.
gotejante Nun
Muito agradável. Aqui está em 12 bytes
Jonathan Allan
Aqui está outro 12 byterÆEZ×Ụ’$€$ZÆẸ
milhas
Isso agora dá [1,18]para [15,18]. A versão inicial estava retornando a resposta correta ( [5,18]).
Arnauld
1
Ah - sim, precisaríamos de um zero na transposição. ÆEz®0iṂ$¦€ZÆẸdeve fazer o truque 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")

(Obrigado a @ Giuseppe por esses 19 bytes de folga!)

Com recuos, novas linhas e algumas explicações:

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 teste:

> 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
fonte
!tem maior precedência que &e |mas menor que +e *; você deve conseguir jogar alguns bytes dessa maneira; ou seja, !i%%q&j%%qdeve ser equivalente a!i%%q+j%%q
Giuseppe
1
Ok, bem observação: se GCD(c,d)==1, então LCM(c,d)==c*d. Assim, podemos testar GCD(c,d)==1e, em seguida, verificar se c*d==a*b/GCD(a,b)uma vez que este é LCM(a,b)...
Giuseppe
1
De fato! (embora o cálculo a*b/GCD(a,b)não seja menor que LCM(a,b)).
plannapus
120 bytes - função anônima + nova linha literal para -3 bytes
Giuseppe
4

Casca , 10 bytes

→ÖF§-⌋⌉ΠmḊ

Força bruta. Pega e devolve listas e também trabalha por mais de dois números. Experimente online!

Explicação

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

Mathematica, 82 bytes

#&@@Select[Subsets[Flatten@Divisors[{t=#,r=#2}],{2}],GCD@@#==1&&LCM@@#==t~LCM~r&]&
J42161217
fonte
Não tenho certeza, mas você não pode usar a indexação de lista Select[...][[1]] vez de First@Select[...]salvar um byte?
Jonathan Frech
sim, mas então eu poderia usar #&@@em vez de [[1]]salvar mais um ;-)
J42161217
3

JavaScript (ES6), 90 84 80 bytes

Recebe entrada na sintaxe de curry (a)(b)e retorna uma matriz de 2 números inteiros.

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 teste

Quão?

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
fonte
3

MATL , 17 16 bytes

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

Experimente online!

Mesmo método que a solução Jelly de Lynn

Já faz algum tempo desde que eu usei qualquer MATL (ou matlab), é provável que muitas melhorias sejam possíveis.

B. Mehta
fonte
3

Haskell ,50. 48. 47 45 42 bytes

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

Idéia: eu notei isso c*d = a*b/gcd(a,b). Portanto, o algoritmo executa duas etapas:

  1. Comece com c' = a/gcd(a,b)e d' = b. Isso atende a todos os requisitos, exceto isso, c'e d'deve ser co-prime.
  2. Para torná-los co-primos, calculo e = gcd(c',d')e depois defino c = c'*ee d = d'/e. Isso mantém todas as propriedades (já que os fatores combinados permanecem os mesmos), mas, como removo todos os fatores compartilhados d, crio ce dcoprime.

Na minha implementação, c'é apenas chamado c.

Experimente online!

-3 bytes graças a Laikoni

Sacchan
fonte
O uso de uma proteção de padrão para vincular ceconomiza 3 bytes: Experimente online!
Laikoni 25/10
@Laikoni Ooh, eu nem conhecia esse truque. Obrigado!
Sacchan 25/10
2

05AB1E , 12 bytes

Ñ`âʒ.¿I.¿Q}н

Experimente online! ou como um conjunto de testes

Emigna
fonte
Ainda um de força bruta: c
Leaky Nun
@LeakyNun: Sim, há provavelmente uma maneira Mathier para fazer isso :)
Emigna
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,]

Experimente online!

Este tem uma abordagem diferente (e aparentemente menos golfy) para encontrar os valores do que a outra resposta R .

Explicação:

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
}

exceto que calço todas as definições como argumentos padrão e faço todos os cálculos em uma linha para a golfiness.

Giuseppe
fonte
2

J , 19 bytes

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

Experimente online!

Baseado na solução da @ Lynn .

Explicação

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

Experimente online!

Economizou 17 bytes graças a Laikoni

jferard
fonte
1
u*v`div`gcd u vsalva um byte.
Lynn
Existe algum motivo para não usar a lcmfunção interna?
Laikoni 16/09
Além disso rem a x+rem b y+gcd x y<2 deve funcionar.
Laikoni 16/09
@Laikoni, uma razão muito boa: eu nem sabia que o builtin lcmexistia. rem a x+rem b y+gcd x y<2funciona, e eu me pergunto se rem a x+rem b y+gcd x y+lcm a b-lcm x y<2 funciona. Há simTalvez uma garantia (matemática) disso lcm a b>=lcm x y.
jferard
1
De fato, lcm a b>=lcm x yporque 1. x=x1*...*xi(decomposição primária) y=y1*...yj, lcm x y=z1*...*zkonde z1,...,zksão comuns x1,...,xie y1,...,yj. 2. a=u1*...*um*x1*...*xi(decomposição primária) b=v1*...vn*y1*...yj, lcm a b=t1*...*tlonde t1,...,tlsão comuns u1*...*um*x1*...*xiev1*...vn*y1*...yj . É óbvio que t1,...,tlcontém z1,...,zk, assim lcm a b>=lcm x y. Mas isso não é útil para escrever a condição como uma soma.
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]

A entrada é tomada como uma lista, que a função modifica no local.

Experimente online!

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

Experimente online! ou Experimente a suíte de testes.

Produz todas as combinações possíveis na forma de uma lista aninhada.

Mr. Xcoder
fonte
3
Você e seu material bit a bit ... -~ae -~bpode ser reescrito como a+1e b+1para facilitar a leitura: P
Stephen
1
@Stephen Como você pode ver, eu especializar em ofuscação
Mr. Xcoder
Não funciona para o meu segundo testcase recém-adicionado.
Freira vazada
@LeakyNun Revertida. Não teve tempo de verificar a validade do golfe.
Mr. Xcoder
1

Geléia ,  19 15  14 bytes

-4 com ponteiro da Freira Furada (use o divisor embutido)

Estou quase 100% certo de que essa não é a maneira de realmente fazer essa, mas aqui está uma primeira tentativa.
Vamos ver quem é melhor do que um sete ou oito byter!
Sim ... veja a resposta de Lynn com explicação!

g/־l/
ÆDp/ÇÐṂ

Um link monádico que pega uma lista dos dois números e retorna uma lista de listas de possibilidades.

Experimente online!

Quão?

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
fonte
Vamos ver quem é melhor do que um sete ou oito byter! - Acho que não ...
Sr. Xcoder 15/17 '13
Você acha seis? ...CINCO?!
Jonathan Allan
: P Não ... Eu não acho que menos de ~ 13-15 é possível (Dennis discordaria, é claro!)
Mr. Xcoder
Divisor embutido?
gotejante Nun
Sim ÆD, mas (ombros) do cérebro, obviamente, não na engrenagem ...
Jonathan Allan
1

Perl 6 , 72 bytes

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

Experimente online!

Leva uma lista (a, b). Retorna uma lista de todas as listas possíveis (c, d).

Explicação:

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

Experimente online!

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

Experimente online!

-1 graças a Jonathan Frech .

Essa resposta funciona no Python 2 (não no Python 3), usando sympy.gcde em sympy.lcmvez de math.gcde math.lcmque só estão disponíveis no Python 3. E sim, isso é força bruta :)

Erik, o Outgolfer
fonte
Golfe em andamento ...
Erik the Outgolfer
Você pode salvar um byte definindo Q=c==z;(+7 bytes) no início do loop while e substituindo or(c==z)+dpor or Q+d(-4 bytes) e c=+(c==z)orpor c=+Q or(-4 bytes). ( TIO )
Jonathan Frech
Apenas como uma pergunta, você está usando o +operador d=+Eou c=+(c==z)para converter um booleano em um número inteiro?
Jonathan Frech
@ JonathanFrech Sim, eu sou, já que você não pode usar Truee em Falsevez de 1e 0no sympy.
Erik the Outgolfer
Essa é a primeira instância que eu já vi onde a baunilha +...tem alguma utilidade.
Jonathan Frech
1

Gelatina , 13 bytes

Ụ€’×
ÆEz0ÇZÆẸ

Experimente online! Minha primeira resposta Jelly! Editar: ÆEz0µỤ€’×µZÆẸtambém funciona para 13 bytes. Explicação:

Æ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
fonte
1

PARI / GP, 86 bytes

Isso apenas faz o que Lynn diz em sua resposta:

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 eu não contar a f(a,b)=parte, são 79 bytes.

Jeppe Stig Nielsen
fonte
1

05AB1E , 32 26 24 22 20 19 bytes

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

Experimente online! Ainda não tenho idéia de como escrever nessa linguagem, mas pelo menos não é um algoritmo de força bruta. Explicação:

Ó                       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
fonte
O que esta fazendo?
Lynn
O mesmo que o seu, mas fatorando e comparando os expoentes e recombinando os fatores.
Neil