How to write this as a recursive Clojure function? - recursion

I'll illustrate what I want to do using Python (I want to write this in Clojure). I have this function:
def f(n):
s=0
for d in range(1,n+1):
s+=d*(n//d)
return(s)
Which is basically looping from d=1 to n inclusive, and summing up the values of d times the floor of n/d.
In Clojure I want to make this a recursive function. Python equivalent:
def f(d, n):
if d == 0: return 0
else: return d*(n//d) + f(d-1, n)
and then I'd call the function with f(n, n).
I am trying this:
(defn f
([n] (f n n))
([d n]
(if (> d 0)
(recur (dec d) n)
0)))
But I don't know if this is right so far or where to slip in the sum or how to do it, etc.

If you look at your Clojure f function, the [d n] arity recurs with
d decremented and
n unchanged
... until d is zero, when it returns 0.
If we write this arity as a distinct local function, using letfn, we can drop the unchanging n argument, picking it up from the f argument:
(defn f [n]
(letfn [(g [d]
(if (> d 0)
(recur (dec d))
0))]
(g n)))
This produces the wrong answer of course, always returning 0:
(f 10)
=> 0
But we can see where to put the sum in:
(defn f [n]
(letfn [(g [d]
(if (> d 0)
(+ (* d (quot n d)) (g (dec d)))
0))]
(g n)))
We have to revert the recur to an explicit recursive call to g, as it is surrounded by the +.
But at least it works:
(f 10)
=> 87
In Clojure I want to make this a recursive function.
Don't. I've done it above just to show you where the calculation fits in.
Explicit recursion is rare in idiomatic Clojure. Better use the functions that encapsulate its common patterns. I won't repeat what Carciginate has given, but once you get used to threading macros, I think you'll find the following clear and concise:
(defn f [n]
(->> (range 1 (inc n))
(map (fn [d] (* d (quot n d))))
(reduce +)))
By the way, a reasonable analogue of your Python code is
(defn f [n]
(loop [s 0, d 1]
(if (> d n)
s
(recur (+ s (* d (quot n d))) (inc d)))))

I managed to get 3 ways working. Unfortunately, this algorithm doesn't seem to lend itself to nice recursion.
To get safe recursion, I had to introduce a third parameter. I just couldn't get it arranged so the recur was in the tail position. I also decided to count up instead of down. I don't think there's anything left field here, although it did get quite long unfortunately.
(defn f3
([n] (f3 n 1 0))
([n d s]
(if (> d (inc n))
s
(recur n (inc d)
(+ s (* d (quot n d)))))))
(f3 10)
If unsafe recursion is ok, this can be simplified quite a bit. Instead of adding multiple argument lists, I decided to allow d to be defaultable using & [d?]] and a check later down. I tend to avoid adding multiple argument lists since par-infer has a difficult time handling the indentation required to make it work. This trick isn't possible with the first way due to how recur handles var args. It only works if you're not using recur, or you do use recur, but only destructure 1 var-arg.
(defn f2 [n & [d?]]
(let [d (or d? 1)]
(if (> d (inc n))
0
(+ (f2 n (inc d)) (* d (quot n d))))))
(f2 10)
Unless you really need recursion though, I'd just write it as a map and reduction:
(defn f1 [n]
(reduce + 0
(map #(* % (quot n %)))
(range 1 (inc n)))))
(f1 10)
Which to me is about as neat as it gets (without using a threading macro. See Thumbnail's answer).

Try this:
(defn f
([n] (f n n))
([d n]
(if (> d 0)
(+ (* d (quot n d)) (recur (dec d) n))
0)))

Related

Tail recursion in clojure

This is a lisp code that uses tail recursion.
(defun factorial (f n)
(if (= n 1)
f
(factorial (* f n) (- n 1))))
I translate this into clojure code expecting the same tail recursion optimization.
(defn fact [f n]
(if (= n 1)
f
(fact (* f n) (dec n))))
However I got this integer overflow (not stack overflow) even with small number such as (fact 1 30).
ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1374)
I tried with recur, but got the same error.
(defn factorial [f n]
(if (= n 1)
f
(recur (* f n) (dec n))))
What's wrong with the clojure code?
Nothing, just use BigInts:
(factorial 1N 30N) ;=> 265252859812191058636308480000000N
The arguments may be small, but the result is not!
Note that ticked versions of the arithmetic operators are also available, which support arbitrary precision:
(reduce *' (range 1 31)) ;=> 265252859812191058636308480000000N

Lambda Recursion in Dr Racket

Im trying to created the function "apply N times" in Dr Racket but Don't know where I'm going wrong. My code seems to be correct but clearly I'm missing something. Printed below is the code and the error I'm getting.
(define (applyNtimes F n)
(lambda (x)
(if (= n 0) x
(F (applyNtimes F (- n 1))))))
(define cdr3 (applyNtimes cdr 3))
(cdr3 '(1 2 3 4 4 5))
and This is the error I'm getting:
cdr: contract violation
expected: pair?
given: #
the expected output should be
(4 4 5)
Here's the problem, you are trying to apply F to the return of applyNtimes but think for a second, what does that return? a lambda.
This means in your case, we're trying to apply cdr to a lambda, whoops.
In order to get the value of this lambda to actually use it, we have to invoke it. Doing this is pretty easy, just changing
(F (applyNtimes F (- n 1))))))
to
(F ( (applyNtimes F (- n 1)) ;;Get the Lambda
x))))) ;; and apply it to x
To understand this let's break it apart, first we apply F to something. Since in our case F is really cdr we'd better give it some form of pair.
In this code the 'Something' is the result of applying (applyNTimes F (- n 1)) to x.
Well this leads us to some recursion, where what we're really doing is
(F (F (F ... ((applyNTimes F (- n whatever)) x))))
Ok so how does this recursion end? Well when (- n whatever) is 0, we return the lambda
(lambda (x) x)
Which really turns this whole thing into
(F (F (F (F (F (F x))))))
Which is our desired applyNtimes function.

a recursive Fibonacci function in Clojure

I'm a newcomer to clojure who wanted to see what all the fuss is about. Figuring the best way to get a feel for it is to write some simple code, I thought I'd start with a Fibonacci function.
My first effort was:
(defn fib [x, n]
(if (< (count x) n)
(fib (conj x (+ (last x) (nth x (- (count x) 2)))) n)
x))
To use this I need to seed x with [0 1] when calling the function. My question is, without wrapping it in a separate function, is it possible to write a single function that only takes the number of elements to return?
Doing some reading around led me to some better ways of achieving the same funcionality:
(defn fib2 [n]
(loop [ x [0 1]]
(if (< (count x) n)
(recur (conj x (+ (last x) (nth x (- (count x) 2)))))
x)))
and
(defn fib3 [n]
(take n
(map first (iterate (fn [[a b]] [b (+ a b)]) [0 1]))))
Anyway, more for the sake of the exercise than anything else, can anyone help me with a better version of a purely recursive Fibonacci function? Or perhaps share a better/different function?
To answer you first question:
(defn fib
([n]
(fib [0 1] n))
([x, n]
(if (< (count x) n)
(fib (conj x (+ (last x) (nth x (- (count x) 2)))) n)
x)))
This type of function definition is called multi-arity function definition. You can learn more about it here: http://clojure.org/functional_programming
As for a better Fib function, I think your fib3 function is quite awesome and shows off a lot of functional programming concepts.
This is fast and cool:
(def fib (lazy-cat [0 1] (map + fib (rest fib))))
from:
http://squirrel.pl/blog/2010/07/26/corecursion-in-clojure/
In Clojure it's actually advisable to avoid recursion and instead use the loop and recur special forms. This turns what looks like a recursive process into an iterative one, avoiding stack overflows and improving performance.
Here's an example of how you'd implement a Fibonacci sequence with this technique:
(defn fib [n]
(loop [fib-nums [0 1]]
(if (>= (count fib-nums) n)
(subvec fib-nums 0 n)
(let [[n1 n2] (reverse fib-nums)]
(recur (conj fib-nums (+ n1 n2)))))))
The loop construct takes a series of bindings, which provide initial values, and one or more body forms. In any of these body forms, a call to recur will cause the loop to be called recursively with the provided arguments.
You can use the thrush operator to clean up #3 a bit (depending on who you ask; some people love this style, some hate it; I'm just pointing out it's an option):
(defn fib [n]
(->> [0 1]
(iterate (fn [[a b]] [b (+ a b)]))
(map first)
(take n)))
That said, I'd probably extract the (take n) and just have the fib function be a lazy infinite sequence.
(def fib
(->> [0 1]
(iterate (fn [[a b]] [b (+ a b)]))
(map first)))
;;usage
(take 10 fib)
;;output (0 1 1 2 3 5 8 13 21 34)
(nth fib 9)
;; output 34
A good recursive definition is:
(def fib
(memoize
(fn [x]
(if (< x 2) 1
(+ (fib (dec (dec x))) (fib (dec x)))))))
This will return a specific term. Expanding this to return first n terms is trivial:
(take n (map fib (iterate inc 0)))
Here is the shortest recursive function I've come up with for computing the nth Fibonacci number:
(defn fib-nth [n] (if (< n 2)
n
(+ (fib-nth (- n 1)) (fib-nth (- n 2)))))
However, the solution with loop/recursion should be faster for all but the first few values of 'n' since Clojure does tail-end optimization on loop/recur.
this is my approach
(defn fibonacci-seq [n]
(cond
(= n 0) 0
(= n 1) 1
:else (+ (fibonacci-seq (- n 1)) (fibonacci-seq (- n 2)))
)
)
For latecomers. Accepted answer is a slightly complicated expression of this:
(defn fib
([n]
(fib [0 1] n))
([x, n]
(if (< (count x) n)
(recur (conj x (apply + (take-last 2 x))) n)
x)))
For what it's worth, lo these years hence, here's my solution to 4Closure Problem #26: Fibonacci Sequence
(fn [x]
(loop [i '(1 1)]
(if (= x (count i))
(reverse i)
(recur
(conj i (apply + (take 2 i)))))))
I don't, by any means, think this is the optimal or most idiomatic approach. The whole reason I'm going through the exercises at 4Clojure ... and mulling over code examples from Rosetta Code is to learn clojure.
Incidentally I'm well aware that the Fibonacci sequence formally includes 0 ... that this example should loop [i '(1 0)] ... but that wouldn't match their spec. nor pass their unit tests despite how they've labelled this exercise. It is written as an anonymous recursive function in order to conform to the requirements for the 4Clojure exercises ... where you have to "fill in the blank" within a given expression. (I'm finding the whole notion of anonymous recursion to be a bit of a mind bender; I get that the (loop ... (recur ... special form is constrained to tail-recursion ... but it's still a weird syntax to me).
I'll take #[Arthur Ulfeldt]'s comment, regarding fib3 in the original posting, under consideration as well. I've only used Clojure's iterate once, so far.

Applying the Y-Combinator to a recursive function with two arguments in Clojure?

Doing the Y-Combinator for a single argument function such as factorial or fibonacci in Clojure is well documented:
http://rosettacode.org/wiki/Y_combinator#Clojure
My question is - how do you do it for a two argument function such as this getter for example?
(Assumption here is that I want to solve this problem recursively and this non-idiomatic clojure code is there deliberately for another reason)
[non y-combinator version]
(defn get_ [n lat]
(cond
(empty? lat) ()
(= 0 (- n 1)) (first lat)
true (get_ (- n 1) (rest lat))))
(get_ 3 '(a b c d e f g h i j))
The number of args doesn't change anything since the args are apply'd. You just need to change the structure of get_:
(defn get_ [f]
(fn [n lat]
(cond
(empty? lat) ()
(= 1 n) (first lat)
:else (f (dec n) (next lat)))))
(defn Y [f]
((fn [x] (x x))
(fn [x]
(f (fn [& args]
(apply (x x) args))))))
user=> ((Y getf) 3 '(a b c d e f g h i j))
c
It'd be pretty straight forward.
Say you've got a function H:
(def H
(fn [x]
(fn [x y]
(stuff happens))))
Then you apply the same ol' Y-Combinator:
((Y H) 4 5)
Where 4 and 5 are arguments you want to pass to H.
The combinator is essentially "dealing with" the top-level function in H, not the one that's doing the hard work (the one with arity 2, here).

How to improve this piece of code?

My solution to exercise 1.11 of SICP is:
(define (f n)
(if (< n 3)
n
(+ (f (- n 1)) (* 2 (f (- n 2))) (* 3 (f (- n 3))))
))
As expected, a evaluation such as (f 100) takes a long time. I was wondering if there was a way to improve this code (without foregoing the recursion), and/or take advantage of multi-core box. I am using 'mit-scheme'.
The exercise tells you to write two functions, one that computes f "by means of a recursive process", and another that computes f "by means of an iterative process". You did the recursive one. Since this function is very similar to the fib function given in the examples of the section you linked to, you should be able to figure this out by looking at the recursive and iterative examples of the fib function:
; Recursive
(define (fib n)
(cond ((= n 0) 0)
((= n 1) 1)
(else (+ (fib (- n 1))
(fib (- n 2))))))
; Iterative
(define (fib n)
(fib-iter 1 0 n))
(define (fib-iter a b count)
(if (= count 0)
b
(fib-iter (+ a b) a (- count 1))))
In this case you would define an f-iter function which would take a, b, and c arguments as well as a count argument.
Here is the f-iter function. Notice the similarity to fib-iter:
(define (f-iter a b c count)
(if (= count 0)
c
(f-iter (+ a (* 2 b) (* 3 c)) a b (- count 1))))
And through a little trial and error, I found that a, b, and c should be initialized to 2, 1, and 0 respectively, which also follows the pattern of the fib function initializing a and b to 1 and 0. So f looks like this:
(define (f n)
(f-iter 2 1 0 n))
Note: f-iter is still a recursive function but because of the way Scheme works, it runs as an iterative process and runs in O(n) time and O(1) space, unlike your code which is not only a recursive function but a recursive process. I believe this is what the author of Exercise 1.1 was looking for.
I'm not sure how best to code it in Scheme, but a common technique to improve speed on something like this would be to use memoization. In a nutshell, the idea is to cache the result of f(p) (possibly for every p seen, or possibly the last n values) so that next time you call f(p), the saved result is returned, rather than being recalculated. In general, the cache would be a map from a tuple (representing the input arguments) to the return type.
Well, if you ask me, think like a mathematician. I can't read scheme, but if you're coding a Fibonacci function, instead of defining it recursively, solve the recurrence and define it with a closed form. For the Fibonacci sequence, the closed form can be found here for example. That'll be MUCH faster.
edit: oops, didn't see that you said forgoing getting rid of the recursion. In that case, your options are much more limited.
See this article for a good tutorial on developing a fast Fibonacci function with functional programming. It uses Common LISP, which is slightly different from Scheme in some aspects, but you should be able to get by with it. Your implementation is equivalent to the bogo-fig function near the top of the file.
To put it another way:
To get tail recursion, the recursive call has to be the very last thing the procedure does.
Your recursive calls are embedded within the * and + expressions, so they are not tail calls (since the * and + are evaluated after the recursive call.)
Jeremy Ruten's version of f-iter is tail-recursive rather than iterative (i.e. it looks like a recursive procedure but is as efficient as the iterative equivalent.)
However you can make the iteration explicit:
(define (f n)
(let iter
((a 2) (b 1) (c 0) (count n))
(if (<= count 0)
c
(iter (+ a (* 2 b) (* 3 c)) a b (- count 1)))))
or
(define (f n)
(do
((a 2 (+ a (* 2 b) (* 3 c)))
(b 1 a)
(c 0 b)
(count n (- count 1)))
((<= count 0) c)))
That particular exercise can be solved by using tail recursion - instead of waiting for each recursive call to return (as is the case in the straightforward solution you present), you can accumulate the answer in a parameter, in such a way that the recursion behaves exactly the same as an iteration in terms of the space it consumes. For instance:
(define (f n)
(define (iter a b c count)
(if (zero? count)
c
(iter (+ a (* 2 b) (* 3 c))
a
b
(- count 1))))
(if (< n 3)
n
(iter 2 1 0 n)))

Resources