JavaScript (ECMAScript 5) 170 164 163 113
No pude resistirme a seguir el liderazgo de MT0. Había considerado la recurrencia antes, pero me había parecido demasiado fácil equivocarme. Y realmente lo es. La más mínima variación destruye todo.
Hay un violín para quienes gustan de los violines.
function f(a,b,i,e){return i?a%i|b%i?(e?i+'^'+e+' ':'')+(i>a?'':f(a,b,i+1,0)):f(a/i,b/i,i,e+1):f(a,b,2,0).trim()}
Sin golf:
function f(a,b,i,e){
return i // Check for factor.
?a%i|b%i // Check for indivisibility.
?(
e // Check for exponent.
?i+'^'+e+' ' // Add the current factor to result string.
:'' // Omit the current non-factor.
)+(
i>a // Check for termination state.
?'' // Stop recursion.
:f(a,b,i+1,0) // Go to the next factor.
)
:f(a/i,b/i,i,e+1) // Failed indivisibility check. Increment exponent and divide subject values.
:f(a,b,2,0) // Add default factor and exponent.
.trim() // Get rid of one extra space that's usually on the end.
}
Versión antigua
function f(a,b){for(var r=[],j=-1,i=2;i<=a;)a%i|b%i?++i:(r[j]&&r[j][0]==i?r[j][1]++:r[++j]=[i,1],a/=i,b/=i);for(j=0;i=r[j];++j)r[j]=i.join('^');return r.join(' ')}
Sin golf:
function f(a,b){
for(var r=[],j=-1,i=2;i<=a;)
// We (mis)use conditional expression `?:` instead of `if(){}else{}`.
a%i|b%i ? // Bitwise OR saves one character over logical OR, where applicable.
// In the truth case, `i` has become uninteresting. Just move on.
++i : // We don't mind hitting composites because their prime factors have already been drained from `a` and `b`.
(
r[j]&&r[j][0]==i ? // Check if `i` is already a listed factor.
r[j][1]++ : // Increment the exponent count.
r[++j]=[i,1], // Otherwise, add a new factor with exponent 1.
a/=i,b/=i // Drain a used-up factor from `a` and `b`.
);
// The real work's done. Now we just format.
for(j=0; i=r[j]; ++j)
r[j]=i.join('^'); // Join each factor to its exponent.
return r.join(' ') // Join all factors into result string.
}
Aquí hay algunas pruebas:
[
f(4, 12),
f(80, 80),
f(96,162),
f(196,294)
];
gcd(n,m) == 1
?