How to evaluate a function giving a value in scheme - functional-programming

(F n m l f g): n and m are natural numbers, l a list of numbers, f and g functions that take a numeric parameter and return a number. The F function should return:
I need to program this function in scheme. And I have developed a function for the product but not how to perform the evaluation of the role, I tried with the eval command but not worked yet
Any help on how to do?

Here's a straightforward translation of your formula to Racket:
(define (F n m l f g)
(for/sum ([i (in-range 1 (add1 n))])
(- (f (expt m i))
(g (for/product ([j (in-list l)])
(expt j i))))))

Related

How to write this as a recursive Clojure function?

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)))

Is there a tco pattern with two accumulating variables?

Just for fun (Project Euler #65) I want to implement the formula
n_k = a_k*n_k-1 + n_k-2
in an efficient way. a_k is either 1 or (* 2 (/ k 3)), depending on k.
I started with a recursive solution:
(defun numerator-of-convergence-for-e-rec (k)
"Returns the Nth numerator of convergence for Euler's number e."
(cond ((or (minusp k)) (zerop k) 0)
((= 1 k) 2)
((= 2 k) 3)
((zerop (mod k 3)) (+ (* 2 (/ k 3) (numerator-of-convergence-for-e-rec (1- k)))
(numerator-of-convergence-for-e-rec (- k 2))))
(t (+ (numerator-of-convergence-for-e-rec (1- k))
(numerator-of-convergence-for-e-rec (- k 2))))))
which works for small k but gets pretty slow for k = 100, obviously.
I have no real idea how to transform this function to a version with could be tail-call optimized. I have seen a pattern using two accumulating variables for fibonacci numbers but fail to transform this pattern to my function.
Is there a general guideline how to transform complex recursions to tco versions or should I implement an iterative solution directly.?
First, note that memoization is probably the simplest way optimize your code: it does not reverse the flow of operations; you call your function with a given k and it goes back to zero to compute the previous values, but with a cache. If however you want to turn your function from recursive to iterative with TCO, you'll have to compute things from zero up to k and pretend you have a constant-sized stack / memory.
Step function
First, write a function which computes current n given k, n-1 and n-2:
(defun n (k n1 n2)
(if (plusp k)
(case k
(1 2)
(2 3)
(t (multiple-value-bind (quotient remainder) (floor k 3)
(if (zerop remainder)
(+ (* 2 quotient n1) n2)
(+ n1 n2)))))
0))
This step should be easy; here, I rewrote your function a little bit but I actually only extracted the part that computes n given the previous n and k.
Modified function with recursive (iterative) calls
Now, you need to call n from k starting from 0 to the maximal value you want to be computed, named m hereafter. Thus, I am going to add a parameter m, which controls when the recursive call stops, and call n recursively with the modified arguments. You can see the arguments are shifted, current n1 is the next n2, etc.
(defun f (m k n1 n2)
(if (< m k)
n1
(if (plusp k)
(case k
(1 (f m (1+ k) 2 n1))
(2 (f m (1+ k) 3 n1))
(t (multiple-value-bind (quotient remainder) (floor k 3)
(if (zerop remainder)
(f m (1+ k) (+ (* 2 quotient n1) n2) n1)
(f m (1+ k) (+ n1 n2) n1)))))
(f m (1+ k) 0 n1))))
That's all, except that you don't want to show this interface to your user. The actual function g properly bootstraps the initial call to f:
(defun g (m)
(f m 0 0 0))
The trace for this function exhibits an arrow ">" shape, which is the case with tail-recursive functions (tracing is likely to inhibit tail-call optimization):
0: (G 5)
1: (F 5 0 0 0)
2: (F 5 1 0 0)
3: (F 5 2 2 0)
4: (F 5 3 3 2)
5: (F 5 4 8 3)
6: (F 5 5 11 8)
7: (F 5 6 19 11)
7: F returned 19
6: F returned 19
5: F returned 19
4: F returned 19
3: F returned 19
2: F returned 19
1: F returned 19
0: G returned 19
19
Driver function with a loop
The part that can be slightly difficult, or make your code hard to read, is when we inject tail-recursive calls inside the original function n. I think it is better to use a loop instead, because:
unlike with the tail-recursive call, you can guarantee that the code will behave as you wish, without worrying whether your implementation will actually optimize tail-calls or not.
the code for the step function n is simpler and only expresses what is happening, instead of detailing how (tail-recursive calls are just an implementation detail here).
With the above function n, you can change g to:
(defun g (m)
(loop
for k from 0 to m
for n2 = 0 then n1
for n1 = 0 then n
for n = (n k n1 n2)
finally (return n)))
Is there a general guideline how to transform complex recursions to
tco versions or should I implement an iterative solution directly?
Find a step function which advances the computation from the base case to the general case, and put intermediate variables as parameters, in particular results from past calls. This function can call itself (in which case it will be tail-recursive, because you have to compute all the arguments first), or simply called in a loop. You have to be careful when computing the initial values, you might have more corner cases than with a simple recursive function.
 See also
Scheme's named let, the RECUR macro in Common Lisp and the recur special form in Clojure.

How to use tail-recursive to implement a recursive function

(replicate-to-length '(a b c) 8)
(a b c a b c a b)
(replicate-to-length '(a b c) 2)
(a b)
Well. you define a local procedure and make sure you don't shadow the original argument so that you can us it instead of the empty list.
(define (replicate-to-length x i)
(define (replicate-to-length-aux cx i)
...)
;; call helper
(replicate-to-length-aux x i))
Or you can lambda lift it:
(define (replicate-to-length-aux x cx i)
...)
(define (replicate-to-length x i)
(replicate-to-length-aux x x i))
Of course I guess this is just to learn. I would have done something like this:
#!r6rs
(import (rnrs base)
(only (srfi :1) circular-list take))
(define (replicate-to-length x i)
(take (apply circular-list x) i))

How to map a function in Common Lisp?

I made this function in Common Lisp
(defun f (&key n p x)
(* (combinacion n x) (expt p x) (expt (- 1 p) (- n x))))
and it works fine. The thing is that I want to make a function in Common Lisp lake the following Haskell function
ff n p x = sum . map (f n p) $ [0 .. x]
namley, map the function f partially applied to a list.
I made the following function to create the lists
(defun range (&key max (min 0) (step 1))
(loop for n from min to max by step
collect n))
and works fine too, I only need to know how to make the mapping.
Common Lisp doesn't have partial applications built in, you just have to write a lambda expression to do what you want.
(defun map-f (n p limit)
(let ((x-list (range :max limit)))
(mapcar #'(lambda (x) (f :n n :p p :x x)) x-list)))

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.

Resources