Skip to main content

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

Popular posts from this blog

front end - keyboard shortcut to invoke Insert new matrix

I frequently need to type in some matrices, and the menu command Insert > Table/Matrix > New... allows matrices with lines drawn between columns and rows, which is very helpful. I would like to make a keyboard shortcut for it, but cannot find the relevant frontend token command (4209405) for it. Since the FullForm[] and InputForm[] of matrices with lines drawn between rows and columns is the same as those without lines, it's hard to do this via 3rd party system-wide text expanders (e.g. autohotkey or atext on mac). How does one assign a keyboard shortcut for the menu item Insert > Table/Matrix > New... , preferably using only mathematica? Thanks! Answer In the MenuSetup.tr (for linux located in the $InstallationDirectory/SystemFiles/FrontEnd/TextResources/X/ directory), I changed the line MenuItem["&New...", "CreateGridBoxDialog"] to read MenuItem["&New...", "CreateGridBoxDialog", MenuKey["m", Modifiers-...

How to thread a list

I have data in format data = {{a1, a2}, {b1, b2}, {c1, c2}, {d1, d2}} Tableform: I want to thread it to : tdata = {{{a1, b1}, {a2, b2}}, {{a1, c1}, {a2, c2}}, {{a1, d1}, {a2, d2}}} Tableform: And I would like to do better then pseudofunction[n_] := Transpose[{data2[[1]], data2[[n]]}]; SetAttributes[pseudofunction, Listable]; Range[2, 4] // pseudofunction Here is my benchmark data, where data3 is normal sample of real data. data3 = Drop[ExcelWorkBook[[Column1 ;; Column4]], None, 1]; data2 = {a #, b #, c #, d #} & /@ Range[1, 10^5]; data = RandomReal[{0, 1}, {10^6, 4}]; Here is my benchmark code kptnw[list_] := Transpose[{Table[First@#, {Length@# - 1}], Rest@#}, {3, 1, 2}] &@list kptnw2[list_] := Transpose[{ConstantArray[First@#, Length@# - 1], Rest@#}, {3, 1, 2}] &@list OleksandrR[list_] := Flatten[Outer[List, List@First[list], Rest[list], 1], {{2}, {1, 4}}] paradox2[list_] := Partition[Riffle[list[[1]], #], 2] & /@ Drop[list, 1] RM[list_] := FoldList[Transpose[{First@li...

plotting - How to draw lines between specified dots on ListPlot?

I would like to create a plot where I have unconnected dots and some connected. So far, I have figured out how to draw the dots. My code is the following: ListPlot[{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4,13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full] I have thought using ListLinePlot command, but I don't know how to specify to the command to draw only selected lines between the dots. Do have any suggestions/hints on how to do that? Thank you. Answer One possibility would be to use Epilog with Line : ListPlot[ {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4, 13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full, Epilog -> { Line[ ...