Escrevendo números racionais como razão de fatoriais de primos

19

Nota: este desafio foi publicado na sandbox .

Introdução

Esse desafio é inspirado em 2009 Putnam B1 , um problema em um concurso de graduação em matemática. O problema é o seguinte:

Mostre que todo número racional positivo pode ser escrito como um quociente de produtos de fatoriais de primos (não necessariamente distintos). Por exemplo,

$ \ frac {10} 9 = \ frac {2! \ cdot 5!} {3! \ cdot 3! \ cdot 3!}. $

Desafio

Seu desafio é pegar um par de números inteiros positivos relativamente primos, representando o numerador e o denominador de um número racional positivo (ou apenas o próprio número racional) como entrada, e gerar duas listas (ou matrizes, etc.) de números primos para que o número racional inserido é igual à razão entre o produto dos fatoriais dos primos na primeira lista e o produto dos fatoriais dos primos na segunda lista.

Notas

  • Pode não haver números primos contidos na primeira e na segunda lista; no entanto, um primo pode aparecer quantas vezes se desejar em qualquer lista.
  • As entradas podem ser assumidas para cada uma estar (sem estrita) entre 1 e 65535; no entanto, não se pode presumir que os fatoriais dos números que você precisará fornecer estarão nesse intervalo.

Exemplo de entrada e saída

Aqui estão exemplos de entradas e saídas legais.

input=>output
10,9 => [2,5],[3,3,3]
2,1 => [2],[]
3,1 => [3],[2]
1,5 => [2,3,2],[5]     (elements of a list may be in any order)
3,2 => [3],[2,2]
6,1 => [3],[]

As entradas (2,2), (0,3), (3,0), (3,6) e (1.65536) são entradas ilegais (ou seja, seu programa não precisa se comportar de nenhuma maneira específica nelas ) Aqui estão alguns exemplos de saídas ilegais:

1,2 => [2],[2,2] (2 is in both returned lists)
5,2 => [5],[2,4] (4 is not prime)
2,1 => [2],[1] (1 is not prime either)
3,2 => [3],[2] (3!/2! = 3, not 3/2)

Pontuação

Isso é , então a pontuação mais baixa em bytes vence!

Carl Schildkraut
fonte
Algum tipo de racional minimamente reduzido precisa ser dado no caso de haver várias maneiras de expressar a resposta? Por exemplo 10/9= [2*5]/[3*3]= [(2!/1!) * (5!/4!)] / [(3!/2!) * (3!/2!)]= [2! * 5! * 2! * 2!] / [3! * 3! * 1! * 4!]= (2! * 2! * 2! *5!) / (3! * 3! * 4!).
Digital Trauma
@DigitalTrauma No; no entanto, 4 não é primo, portanto o segundo não seria válido. Acredito (e posso escrever uma prova na pergunta, se você quiser) que qualquer representação é única.
Carl Schildkraut
É aceitável considerar a entrada como a fração 10/9e não como um par de números 10e 9?
Misha Lavrov
@MishaLavrov Sure. Vou editar a pergunta para refletir isso.
Carl Schildkraut
@CarlSchildkraut Graças - sim que ajuda - Eu achava que estava faltando alguma coisa
Digital Trauma

Respostas:

5

05AB1E , 54 53 48 46 40 35 33 32 28 bytes

[D¿÷Z#DÓ€gZD<ØŠQ*DˆR!*]¯øεʒĀ

Experimente online! Editar: salvou 2 bytes graças a @ ASCII-only. Guardado 1 2 3 4 bytes graças a @Emigna. (Só preciso salvar mais uma e reduzi para metade a minha contagem de bytes original!) Explicação:

[       Begin an infinite loop
D¿÷     Reduce to lowest terms
Z#      Exit the loop if the (largest) value is 1
DÓ€g    Find the index of the largest prime factor of each value
Z       Take the maximum
D<ØŠ    Convert index back to prime and save for later
Q       Convert to an pair of which value had the largest prime factor
*       Convert to an pair with that prime factor and zero
Dˆ      Save the pair in the global array for later
R!*     Multiply the other input value by the factorial of the prime
]       End of infinite loop
¯ø      Collect all the saved primes
εʒĀ     Forget all the saved 0s
Neil
fonte
Eu amo scripts "emocionais" -¦D
RedClover
46 bytes
somente ASCII
39 bytes
Sr. Xcoder 9/10
5

Mathematica, 175 177 169 169 154 108 bytes

Join@@@Table[x[[1]],{s,{1,-1}},{x,r@#},x[[2]]s]&@*(If[#==1,1,{p,e}=Last@(r=FactorInteger)@#;p^e#0[p!^-e#]]&)

Experimente online!

Como funciona

Esta é a composição de duas funções. O primeiro, que os incrédulos

If[# == 1,
  1,
  {p,e} = Last[FactorInteger[#]];
  p^e * #0[p!^-e * #]
]&

é uma função recursiva para realmente calcular a fatoração desejada. Especificamente, dada uma entrada racional x, calculamos os primos cujos fatoriais devem estar no numerador e denominador e retornamos a fração com todos esses primos multiplicados juntos. (Por exemplo, na entrada 10/9 = 2!*5!/(3!*3!*3!), retornamos 10/27 = 2*5/(3*3*3).)

Fazemos isso lidando com o maior fator primo em cada etapa: se p e ocorre na fatoração de x, garantimos que p! e ocorre na fatoração fatorial e recursiva em x dividido por p! e .

(Antes, eu tinha uma estratégia mais inteligente que evita grandes números olhando o número primo anterior antes de p, mas o Mathematica pode lidar com números tão grandes quanto 65521! Facilmente, então não faz sentido. A versão antiga que você pode encontrar na história é muito mais rápido: no meu computador, foram necessários 0,05 segundos nas entradas que esta versão manipula em 1,6 segundos.)

A segunda função transforma a saída da primeira função em listas de números primos.

Join @@@ 
  Table[x[[1]],
    {s,{1,-1}},
    {x,FactorInteger[#]},
    x[[2]]*s
  ]&

Para s=1(potências positivas) e s=-1(potências negativas), e para cada termo {prime,exponent}na fatoração r@#, repetimos o número primo prime exponent*smuitas vezes.

Versão não competidora com 109 62 bytes

If[#==1,∇1=1,{p,e}=Last@FactorInteger@#;(∇p)^e#0[p!^-e#]]&

O mesmo que acima, mas em vez de fornecer a saída como uma lista, fornece a saída como uma expressão, usando o operador ((porque não possui significado interno) como substituto de fatoriais. Assim, uma entrada de 10/9fornece uma saída de (∇2*∇5)/(∇3)^3para representar (2!*5!)/(3!)^3.

Isso é mais curto porque pulamos a segunda parte da função.


+2 bytes: a atribuição f=Firstdeve ser feita no lugar certo para evitar que o Mathematica fique chateado.

-8 bytes: corrigido um bug para saídas inteiras, o que na verdade tornava o código mais curto.

-15 bytes: FactorIntegerretorna a saída classificada, da qual podemos tirar proveito.

-46 bytes: na verdade, não precisamos ser espertos.

Misha Lavrov
fonte
2

Python 2, 220 202 195 183 bytes

g=lambda a,b:a and g(b%a,a)or b;n,d=input();m=c=()
while n+d>2:
 t=n*d;f=p=2
 while t>p:
	if t%p:p+=1;f*=p
	else:t/=p
 if n%p:c+=p,;n*=f
 else:m+=p,;d*=f
 t=g(n,d);n/=t;d/=t
print m,c

Experimente online! Edit: Salvo 18 25 bytes graças a @ Mr.Xcoder. Economizou 12 bytes graças a @JonathanFrech.

Neil
fonte
202 bytes
Sr. Xcoder 07/10
Você pode reduzi-lo ainda mais em Python 2, desde que você pode substituir vários espaços com guias no recuo
Mr. Xcoder
189 bytes .
Jonathan Frech
183 bytes .
Jonathan Frech