output formatting - Trying to write out the prime factorization of a number with CenterDot and Superscript
I am trying to use CenterDot and Superscript, in conjunction with Apply to write out the prime factorization of any given integer. Everything works well UNLESS the prime factorization of the number contains only one prime (to some power). This is because CenterDot must have two arguments I guess.
So let's get going here...
primeFactorForm[n_] := CenterDot[Apply[Superscript, FactorInteger[n], {1}]]
primeFactorForm[9]
gives me
CenterDot[3^2]
and I don't want that obviously. So I created another function to avoid this problem, and put it before my primeFactorForm function that I created....
myCenterDot[{a_^b_}] := a^b
myCenterDot[x_] := Apply[CenterDot, x]
and then I changed my original function
primeFactorForm[n_] :=
myCenterDot[Apply[Superscript, FactorInteger[n], {1}]]
So now it SHOULD just return a^b IF the input is in the form {a^b}, but it still returns
CenterDot[3^2]
instead of just writing it out like i want it to. What have I done wrong? Just some minor syntax errors I hope! Thanks very much in advance!
EDIT: Sorry guys, I should have also mentioned this: when I suggested to my instructor that I add an If statement, he said that doing what I did (creating two myCenterDot functions) would create the same end result without the need of creating an If statement. So he basically said that I can avoid the use of an If statement by doing this that way....hmmm....
Answer
The existing answers work but I offer two improvements:
terse code via pattern replacement
making an actual formatting wrapper
This replacement rule strips the heads of any expressions with only one argument:
foo[1] /. _[x_] :> x
foo[1, 2] /. _[x_] :> x
1
foo[1, 2]
Format is used to describe the output format without losing the original expression.
Format[primeFactorForm[n_Integer]] :=
CenterDot @@ Superscript @@@ FactorInteger[n] /. _[x_] :> x
Now:
primeFactorForm[9]
$3^2$
out = primeFactorForm[5067678515625]
$3^3\cdot 5^8\cdot 11^3\cdot 19^2$
Look at the FullForm of out:
FullForm[out]
primeFactorForm[5067678515625]
You can therefore get the original integer with:
First @ out
5067678515625
Exponent one
If you wish to eliminate exponent one then you may use this instead:
Format[primeFactorForm[n_Integer]] :=
CenterDot @@ Superscript @@@ FactorInteger[n] //. _[x_] | _[x_, 1] :> x
Example:
primeFactorForm[602744404968]
$2^3\cdot 3^2\cdot 41\cdot 131\cdot 307\cdot 5077$
Performance with large integers
Since I put the actual factorization in the formatting function my method will result in the same delay every time the expression is displayed. If you would prefer to optimize any re-display by recalling the earlier result we can add memorization of the Format function. (I discovered a small problem in that my usual mem : syntax does not work here as it interferes with formatting.) For example:
Format[primeFactorForm[n_Integer]] := Format[primeFactorForm[n]] =
CenterDot @@ Superscript @@@ FactorInteger[n] //. _[x_] | _[x_, 1] :> x
Now the first display of primeFactorForm[int] takes a few seconds:
SeedRandom[0];
int = RandomInteger[1*^55];
primeFactorForm[int]
But a second display is instantaneous.
This of course consumes memory and it should not be used if a great many integers are to be displayed in this format in a given session.
Comments
Post a Comment