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$
    – march
    Jun 6, 2016 at 19:02
  • $\begingroup$ Also you may want FactorInteger $\endgroup$
    – evanb
    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$ Jun 6, 2016 at 21:37
  • $\begingroup$ FactorInteger doesn't give exactly the same result. $\endgroup$ 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$
    – ciao
    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$ 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$ 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$ 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$ 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$ Jun 7, 2016 at 7:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.