0
$\begingroup$

I am new to Mathematica and was trying to make a function that lists the Collatz sequence stating with a given number, but I can´t get it to work. Here is my function:

collatz[x_] := NestWhileList[If[Mod[x, 2] == 0, x/2, x*3 + 1], x, x != 1]
$\endgroup$
2
  • $\begingroup$ Welcome to Mathematica.SE! I hope you will become a regular contributor. To get started, 1) take the introductory Tour now, 2) when you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge, 3) remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign, and 4) give help too, by answering questions in your areas of expertise. $\endgroup$
    – bbgodfrey
    Jul 28, 2015 at 20:42
  • $\begingroup$ Also mathematica.stackexchange.com/search?q=collatz $\endgroup$ Jul 28, 2015 at 20:45

2 Answers 2

3
$\begingroup$

x is just your starting value for the iteration. The function to apply, and the stopping condition, should both be applied to the current value obtained by the iteration, and are probably best expressed using pure functions:

collatz[x_] := NestWhileList[If[Mod[#, 2] == 0, #/2, #*3 + 1] &, x, # != 1 &]

collatz[5]
(* Out: {5, 16, 8, 4, 2, 1} *)

This topic has been discussed in some detail on MMA.SE. You could start here: Collatz optimization

$\endgroup$
2
  • $\begingroup$ You beat me by a about a minute :) $\endgroup$
    – m_goldberg
    Jul 28, 2015 at 20:37
  • $\begingroup$ @m_goldberg :-) Thank you! $\endgroup$
    – MarcoB
    Jul 28, 2015 at 20:39
1
$\begingroup$

You need anonymous functions. The way it's written currently will replace every instance of x on the right hand side with the number you provide as the argument for collatz. What you want is something which can act on the value produced by NestWhileList on each iteration. So use

Clear[collatz]
collatz[x_] :=NestWhileList[If[Mod[#, 2] == 0, #/2, #*3 + 1]&, x, # != 1&]

What's happening here is that the & tells the MMA interpreter that everything preceeding it is an anonymous (or inline) function and the # will all be replaced by the first argument of that anonymous function. To make it more general,

NestWhileList[f[#]&,x,g[#]&]

NestWhileList applies f to x on the first iteration and evaluates f[x]. Next it applies g and expects a Boolean results so if g[f[x]] is False it stops. If True it goes on to the next iteration, now applying f again to the previous result, evaluating now f[f[x]] and continues until g[f[...f[x]...] evaluates false.

$\endgroup$

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