# Comparing powers.

Compare two numbers N1 = abc, N2 = def by constructing a function f(a,b,c,d,e,f) that:

• returns 1 if N1 > N2
• returns -1 if N1 < N2

Note: You are not required to return any value for any other relation between N1 and N2. e.g. when they are equal or when their relation is undefined (complex numbers).

other constrains:

• all numbers are integers
• a,b,c,d,e,f may be positive or negative but not zero.
• |a|,|d| < 1000
• |b|,|c|,|e|,|f| < 1010
• running time less than few seconds

Examples:

f(100,100,100,50,100,100) = 1
f(-100,100,100,50,100,100) = 1
f(-100,99,100,50,100,100) = -1
f(100,-100,-100, -1, 3, 100) = 1
f(535, 10^9, 10^8, 443, 10^9, 10^9) = -1


This is code golf. Shortest code wins.

• What about if they're equal, should it return 0? Or you assuming that there's no way that N1 will equal N2? Commented Feb 12, 2011 at 2:28
• Can we get some sample input/outputs? Commented Feb 12, 2011 at 9:37
• @Jonathan: I'm not specifying the "being equal" case on purpose. Do as you please. You may even assume that they are never equal. Commented Feb 12, 2011 at 10:29
• @Dogbert: done. Commented Feb 12, 2011 at 10:42
• |b|,|c|,|e|,|f| < 10^10 seems to contradict your last example Commented Feb 12, 2011 at 14:28

## Ruby 1.9, 280 227 189 171 characters

z=->a,b,c,d,e,f{l=->a{Math.log a}
u=->a,b{[a.abs,a][b&1]}
a=u[a,b=u[b,c]]
d=u[d,e=u[e,f]]
d*a<0?a<=>d :b*e<0?b<=>e :(l[l[a*q=a<=>0]/l[d*q]]<=>f*l[e*r=b<=>0]-c*l[b*r])*q*r}


I know this is a bit longer than the other solutions, but at least this approach should work without calculating abc, def, bc or ef.

Edit:

• (279 -> 280) Fixed a bug when a**b**c < 0 and d = 1.
• (280 -> 227) Removed an unnecessary check for a special case.
• (227 -> 192) Removed some checks that aren't necessary with the given criteria (non-zero integers, no output necessary for complex values)
• (192 -> 189) Due to all the other checks, I can safely calculate log(log(a)/log(d)) instead of log(log(a))-log(log(d)).
• (189 -> 171) Simplified way to transform equivalent problems into one another.

Testcases:

z[100, 100, 100, 50, 100, 100] == 1
z[-100, 100, 100, 50, 100, 100] == 1
z[-100, 99, 100, 50, 100, 100] == -1
z[100, -100, -100, -1, 3, 100] == 1
z[535, 10**9, 10**8, 443, 10**9, 10**9] == -1
z[-1, -1, 1, 2, 2, 2] == -1
z[1, -5, -9, 2, -1, 2] == -1
z[1, -5, -9, 2, -1, 3] == 1
z[3, -3, 3, -4, 1, 1] == 1
z[-2, 1, 1, 1, 1, 1] == -1
z[1, 1, 1, -1, 1, 1] == 1
z[1, 1, 1, 2, 3, 1] == -1
z[1, 1, 1, 2, -3, 2] == -1
z[1, 1, 1, 2, -3, 1] == 1
z[-1, 1, 1, 1, 1, 1] == -1
z[2, 3, 1, 1, 1, 1] == 1
z[2, -3, 2, 1, 1, 1] == 1
z[2, -3, 1, 1, 1, 1] == -1


### Mathematica, 110 chars

z[a_,b_,c_,d_,e_,f_]:=With[{g=Sign[a]^(b^c),h=Sign[d]^(e^f)},If[g!=h,g,g*Sign[Log[Abs[a]]b^c-Log[Abs[d]]e^f]]]

• What kind of Mathematica do you use there and what magic incantation has to be used to actually get this to work? Putting the above into Mathematica 8 just yields »Syntax::bktwrn: "z(a_,b_,c_,d_,e_,f_)" represents multiplication; use "z[a_,b_,c_,d_,e_,f_]" to represent a function.« and »Syntax::sntxf: "z(a_" cannot be followed by ",b_,c_,d_,e_,f_):=sgn(ln(abs a)b^c-ln(abs d)e^f)".«
– Joey
Commented Mar 27, 2011 at 14:01
• Fails the testcase 3,-3,3,-4,1,1, if I'm not completely mistaken (don't have Mathematica here, but Wolfram Alpha seems to agree). Commented Mar 27, 2011 at 14:02
• Ok, got it to work now with z[a_,b_,c_,d_,e_,f_]:=Sign[Log[Abs[a]]b^c-Log[Abs[d]]e^f] which is considerably longer than what you have there, though. I probably am missing something here.
– Joey
Commented Mar 27, 2011 at 14:08
• @Joey, I don't actually have Mathematica, so I was testing with the Wolfram Alpha interface. It appears that it's much more generous with what it accepts. Ah well - the priority is that @Ventero correctly points out a bug with the logic. Commented Mar 27, 2011 at 14:13
• Will it "run in less than a few seconds" for z[535, 10^9, 10^8, 443, 10^9, 10^9]? Commented Mar 27, 2011 at 16:41

# ShortScript, 89 bytes

{CP
$M^ η1 η2$M^ ζ η3
↑Αζ
$M^ η4 η5$M^ ζ η6
↔α>ζ↑Ζ1
↔α<ζ↑Ζ-1}


The implementation isn't exactly the described one, but it works.

This answer is non-competing, since ShortScript has been published after this challenge.

## Python 2.6 (this doesn't actually work)

import cmath
g=cmath.log
f=lambda a,b,c,d,e,f:-1+2*((c*g(b)+g(g(a))-f*g(e)-g(g(d))).real>0)


today i learnt python has a complex log function. so, blindly double log both sides and look at the real component. works for 4 out of the 5 tests. not sure what's happening with the fourth one.

print f(100,100,100,50,100,100) == 1
print f(-100,100,100,50,100,100) == 1
print f(-100,99,100,50,100,100) == -1
print f(100,-100,-100, -1, 3, 100) == 1 # failure, sadness.
print f(535, 10^9, 10^8, 443, 10^9, 10^9) == -1

• Well, it is that I messsed up the example that is wrong :/ Sorry ... fixing it... Commented Feb 14, 2011 at 23:41
• my code still returns -1 for the fourth example wrong when a=100 Commented Feb 14, 2011 at 23:47
• Comparing just the real part is not correct. Commented Feb 14, 2011 at 23:57
• yeah, that part was a stab in the dark. this is where i regret skipping that course in complex analysis Commented Feb 15, 2011 at 9:06

## Python (99)

from math import*
from numpy import*
l=log
def f(a,b,c,d,e,f):return sign(l(a)*l(b)*c-l(d)*l(e)*f)

• Fails on negatives.
– J B
Commented Feb 12, 2011 at 8:53

n True=1

• And I wasn't even talking about bullshit speed/efficiency. I was referring to how (BEFORE you edited the post and changed the function b to n) the type of function f was given by f :: (Ord a, Num a, Integral b2, Integral (Bool -> t), Integral b, Integral b1) => a -> (Bool -> t) -> b -> a -> b1 -> b2 -> t Pretty strange stuff, huh? Commented Jul 22, 2011 at 22:29