Question

In Mathematica

a = FactorInteger[44420069694]

assigns

{{2, 1}, {3, 1}, {7, 1}, {11, 2}, {13, 1}, {23, 2}, {31, 1}, {41, 1}}

to a. Now instead of the factors with their exponents I would like each of those lists expanded. The above factorization would then become

{2, 3, 7, 11, 11, 13, 23, 23, 31, 41}

I wrote the following function:

b = {}; Do[Do[b = Append[b, a[[i]][[1]]], {a[[i]][[2]]}], {i, Length[a]}]

but if you ask me it looks fugly. There sure must be a neater way to do achieve this?

Was it helpful?

Solution

Yet another way in Mathematica 6 or later.

In:= Flatten[ConstantArray @@@ a]

Out={2, 3, 7, 11, 11, 13, 23, 23, 31, 41}

even shorter:

Join @@ ConstantArray @@@ a


A speed comparison of methods posted

Using the these functions (in the order they were posted):

zvrba = Flatten[Map[Table[#[[1]], {#[[2]]}] &, #]] &;
dreeves = Sequence @@ Table[#1, {#2}] & @@@ # &;
gdelfino = Flatten[# /. {p_, n_} :> Table[p, {n}]] &;
mrwizard = Join @@ ConstantArray @@@ # &;
sasha = Function[{p, e}, Array[p &, e, 1, Sequence]] @@@ # &;

and assigning them the letters Z, D, G, M, S respectively, here are Timing charts of their efficiency.

First, for increasing number of lists in the input:

enter image description here

Second, for increasing exponent (length of repetition) in each list:

enter image description here

Note that these charts are logarithmic. Lower is better.

OTHER TIPS

Yes, for example:

Flatten[Map[Table[#[[1]], {#[[2]]}] &, a]]

Here's another way to do it:

rptseq[x_, n_] := Sequence @@ Table[x, {n}]
rptseq @@@ a

Which can be condensed with a lambda function to:

Sequence @@ Table[#1, {#2}] & @@@ a

zvrba's answer can also be condensed a bit, if you're into that sort of thing:

Flatten[Table[#1, {#2}]& @@@ a]

(Now that I look at that, I guess my version is a very minor variant on zvrba's.)

You could also use:

a /. {p_, n_} -> Table[p, {n}] // Flatten

UPDATE 2017/10/18:

My answer above fails "in the case of two distinct prime factors" as pointed out by Cory Walker. This update fixes it:

a /. {p_Integer, n_Integer} -> Table[p, {n}] // Flatten

notice that the benchmark done by Mr Wizard was done with the original version before this update.

One can also use Array to process the answer. Here is a short code doing this:

In[11]:= PrimeFactorInteger[i_Integer] := 
 Function[{p, e}, Array[p &, e, 1, Sequence]] @@@ FactorInteger[i]

In[12]:= PrimeFactorInteger[2^3 3^2 5]

Out[12]= {2, 2, 2, 3, 3, 5}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top