2
$\begingroup$

I cannot realise if it is a duplicate question. Sorry; if it is. This

fl[x0_] := Module[{x = 1}, While[x <= x0, If[Mod[x0, x] == 0, Print[x]]; x++]] 

print the factors of $x_0$. But a printed value cannot be reused. How to put those values in a list to reuse them. I have tried something like that

fl[x0_] := Module[{x = 1 }, A = {}; While[x <= x0, If[Mod[x0, x] == 0, Append[A, x] && Print[A]]; x++]] 

but it return empty lists.

$\endgroup$
5
  • $\begingroup$ Maybe use AppendTo instead of Append. $\endgroup$ Commented Jun 6, 2016 at 19:02
  • $\begingroup$ Also you may want FactorInteger $\endgroup$ Commented Jun 6, 2016 at 19:07
  • $\begingroup$ Certainly, it would be the case if I was not only trying to understand the syntax. It's better to always use a predefined function. $\endgroup$ Commented Jun 6, 2016 at 21:37
  • $\begingroup$ FactorInteger doesn't give exactly the same result. $\endgroup$ Commented Jun 6, 2016 at 23:09
  • $\begingroup$ Divisors@... will be the fastest to accomplish goal, and should you feel the need to go through self-made machinations vs using a bult-in, With[{r = Range@#}, Pick[r, Mod[#, r], 0]] & will handily clobber the existing answers in performance. $\endgroup$ Commented Jun 22, 2016 at 21:31

4 Answers 4

3
$\begingroup$

Another approach is to use Table combined with Nothing which is only available in version 10.2 or later.

f[x0_] := Table[If[Mod[x0, x] == 0, x, Nothing], {x, 1, x0}] 

and then

fl[10] (* {1, 2, 5, 10} *) 

I found this to be slightly faster than using Select or the Sow and Reap approach.

$\endgroup$
7
$\begingroup$

When you're processing an element at a time using procedural constructs like Module, While, If, and Print in Mathematica, it's usually a sign that you're fighting the language rather than using it. It's much easier and more concise to use functional constructs that work on arrays:

fl[x0_] := Select[Range[x0], Mod[x0, #] == 0 &] 
$\endgroup$
3
  • $\begingroup$ You are perfectly right but I am learning and I was following a documentation posted on internet about modules. As I understand, it's better not to use it ? $\endgroup$ Commented Jun 6, 2016 at 21:35
  • $\begingroup$ You are perfectly right but I am learning and I was following a documentation posted on internet about modules. As I understand, it's better not to use it ? Also it is so compact, and clearly understandable.. But there is a drawback your solution take more tha 3% time than the one with AppendTo $\endgroup$ Commented Jun 6, 2016 at 23:14
  • $\begingroup$ Certainly it is not meant that it is better not to use Module in general. Specifically for this case it is not needed and one achieves a better performance with other solutions. $\endgroup$ Commented Jun 7, 2016 at 0:12
2
$\begingroup$

Use of "Sow" and "Reap" allow a simple modification of the existing code. E.g.

fl[x0_] := Module[{x = 1}, While[x <= x0, If[Mod[x0, x] == 0, Sow[x]]; x++]] 

and

Reap[fl[12]] 

returns

{Null, {{1, 2, 3, 4, 6, 12}}} 
$\endgroup$
1
  • $\begingroup$ This result is not the one I was expecting since it gives a sequence of an expending set not only the final one $\endgroup$ Commented Jun 6, 2016 at 23:14
1
$\begingroup$

Here is yet another version

fl[x0_] := Cases[Range[x0], y_ /; Mod[x0, y] == 0] 

On my computer my version is slightly faster than everything else offered so far. In particular, I get the following AbsoluteTiming results on fl[10000000]:

  1. "Cases": 9.4 sec
  2. "Select": 9.8 sec
  3. "Table": 10.8 sec
  4. "AppendTo": 15.5 sec
  5. "Sow": 15.6 sec

Added: Using Divisible[x0,x] instead of Mod[x0,x]==0speeds up the computations 30-40%.

$\endgroup$
1
  • $\begingroup$ To precise a point : In the case of Table, one must add the deletion of Nothing to have a true comparable result. Nevertheless, Thanks to all the discutant, it was a very illuminating discussion $\endgroup$ Commented Jun 7, 2016 at 7:45

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.