See collatz.rkt
(define (collatz n)
(if (= (modulo n 2) 0) (/ n 2)
(+ 1 (* n 3))))
Let's try it out.
(collatz 11)
34
(collatz 34)
17
(collatz 17)
52
We can have collatz
call its own result.
(collatz (collatz (collatz 11)))
52
Having a function call itself is known as recursion. We can generate the series based on Collatz using recursion.
The function c-series
calls itself until the result converges to 1. The function uses let
to introduce a local variable next
(define (c-series n)
(print n)
(newline)
(if (equal? n 1) 'done
(let ((next (collatz n)))
(c-series next))))
(c-series 11)
11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
'done
We can generate the series based on Collatz using recursion as above, but without the
temporary variable next
(define (c-series2 n)
(print n)
(newline)
(if (equal? n 1) 'done
(c-series2 (collatz n))))
(c-series2 11)
11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
'done
We can trace the execution of the recursive functions using the trace
function, which prints out each call to the given function.
When writing recursive code, you will often find it useful to use trace
to see what is going on underneath the hood.
(require racket/trace)
(trace c-series)
(c-series 11)
>(c-series 11) 11 >(c-series 34) 34 >(c-series 17) 17 >(c-series 52) 52 >(c-series 26) 26 >(c-series 13) 13 >(c-series 40) 40 >(c-series 20) 20 >(c-series 10) 10 >(c-series 5) 5 >(c-series 16) 16 >(c-series 8) 8 >(c-series 4) 4 >(c-series 2) 2 >(c-series 1) 1 <'done
'done
We define a c-series3
which does not print out results.
(define (c-series3 n)
(if (equal? n 1) 'done
(c-series3 (collatz n))))
(c-series3 11)
'done
Not really too useful, unless we trace it.
(trace c-series3)
(c-series3 11)
>(c-series3 11) >(c-series3 34) >(c-series3 17) >(c-series3 52) >(c-series3 26) >(c-series3 13) >(c-series3 40) >(c-series3 20) >(c-series3 10) >(c-series3 5) >(c-series3 16) >(c-series3 8) >(c-series3 4) >(c-series3 2) >(c-series3 1) <'done
'done
End of Collatz notebook.