I'm probably getting ahead of myself, I'm barely into functions on my first day of learning Clojure, but I thought I would be ambitious and make a recursive function to convert floating values to ternary. If I call the function by name instead of using recur it works great. I understand the problem is that I am just recuring the 1-arity version of the function, is there a standard way to handle recursion in multi-arity functions? The book I'm reading doesn't seem to cover it.
(defn float-to-ternary
([x k s]
(def a (int x))
(def r (- x a))
(def carry-string (str s (. Integer toString a 3)))
(cond
(== r 0) carry-string
(> k 20) carry-string
:default (recur (* 3 r) (inc k) carry-string)
)
)
([x]
(def a (int x))
(def r (- x a))
(def carry-string (str (. Integer toString a 3) "."))
(cond
(== r 0) (str (. Integer toString a 3))
:default (recur (* 3 r) 1 carry-string)
)
)
)
If you want to "recur into a different arity", just explicitly call the function instead of using recur:
(defn float-to-ternary
([x k s]
(def a (int x))
(def r (- x a))
(def carry-string (str s (. Integer toString a 3)))
(cond
(== r 0) carry-string
(> k 20) carry-string
:default (recur (* 3 r) (inc k) carry-string)))
([x]
(def a (int x))
(def r (- x a))
(def carry-string (str (. Integer toString a 3) "."))
(cond
(== r 0) (str (. Integer toString a 3))
:default (float-to-ternary (* 3 r) 1 carry-string))))
This is safe. You "spend" one stack frame when you don't use recur, but the rest of the recursions use recur, so it's fine.
I have some obligatory suggestions too though:
Don't use def inside of functions unless you really have a good reason. def creates global variables that don't go out of scope when the function returns!
Your uses of cond are unnecessary.
In the first body, you want to return carry-string for the first two conditions. You could just make that one condition, connecting the two with an or, which lets you simply use if.
Since the second use only has two outcomes, if again makes more sense.
Taking this into consideration, your code would look more like:
(defn float-to-ternary
([x k s]
(let [a (int x)
r (- x a)
carry-string (str s (. Integer toString a 3))]
(if (or (> k 20) (== r 0))
carry-string
(recur (* 3 r) (inc k) carry-string))))
([x]
(let [a (int x)
r (- x a)
carry-string (str (. Integer toString a 3) ".")]
(if (== r 0)
(str (. Integer toString a 3))
(float-to-ternary (* 3 r) 1 carry-string)))))
Related
I am trying to implement a function called funPower, which takes a function f, an integer n and returns the function f^n. For example ((funPower sqrt 2) 16) should return 2, which is (sqrt (sqrt 16)).
This is what I have so far but it is not giving me correct output
(define (funPower f n)
(lambda(x) (if (<= n 1)
(f x)
(f (funPower f (- n 1)) x))))
First, you're missing one more pair of parens.
(define (funPower1 f n)
(lambda (x) (if (<= n 1)
(f x)
;; (f ( funPower1 f (- n 1)) x))))
(f ( ( funPower1 f (- n 1)) x)))) )
;; ^^^ ^^^
because (funPower1 f (- n 1)) returns a function to be called on x, the future argument value, as you show with the example, ((funPower sqrt 2) 16).
Second, it's <= 0, not <= 1, and the function f shouldn't be called at all in such a case:
(define (funPower2 f n)
(lambda (x) (if (<= n 0)
;; (f x) ^^^
x
(f ( ( funPower2 f (- n 1)) x)))) )
Now that it's working, we see that it defers the decisions to the final call time, of ((funPower f n) x). But it really could do all the decisions upfront -- the n is already known.
To achieve that, we need to swap the (lambda and the (funPower, to push the lambda "in". When we do, it'll become an additional argument to such augmented funPower:
(define (funPower3 f n)
(if (<= n 0) (lambda (x)
x )
(funPower3 f (- n 1) (lambda (x) (f x)))) )
Now this is completely out of sync. Where's that third argument?
(define (funPower4 f n fun)
(if (<= n 0) fun
(funPower4 f (- n 1) (lambda (x) (fun (f x)))) ))
That's a little bit better, but what's the fun, originally? Where does it come from? It must always be (lambda (x) x) at first or else it won't be right. The solution is to make it an internal definition and use that, supplying it the correct argument the first time we call it:
(define (funPower5 f n)
(define (loop n fun)
(if (<= n 0) fun
(loop (- n 1)
(lambda (x) (fun (f x))))))
(loop n (lambda (x) x)))
This kind of thing would normally be coded as a named let,
(define (funPower5 f n)
(let loop ((n n)
(fun (lambda (x) x)))
(if (<= n 0) fun
(loop (- n 1)
(lambda (x) (fun (f x)))))))
We could also try creating simpler functions in the simpler cases. For instance, we could return f itself if n is 1:
(define (funPower6 f n)
(cond
((zero? n) .....)
((= n 1) .....)
((< n 0) .....)
(else
(let loop ((n n)
(fun .....))
(if (= n .....) fun
(loop (- n 1)
(lambda (x) (fun (f x)))))))))
Complete it by filling in the blanks.
More substantive further improvement is to use exponentiation by repeated squaring -- both in constructing the resulting function, and to have it used by the function we construct!
try this:
(define funpow
(lambda (f n)
((lambda (s) (s s n (lambda (x) x)))
(lambda (s n o)
(if (zero? n)
o
(s s (- n 1)
(lambda (x)
(o (f x)))))))))
(define sqrt_2 (funpow sqrt 2))
(define pow2_2 (funpow (lambda (x) (* x x)) 2))
(sqrt_2 16)
(pow2_2 2)
given,
(define (reduce f id lis)
(if (null? lis) id
(f (car lis) (reduce f id (cdr lis)))))
The length of a list can be defined in terms of reduce (as opposed to
using a recursive definition from scratch) as
(define (mylength lis) (reduce (lambda (x n) (+ 1 n)) 0 lis)).
Define the list function mymap (similar to map) that takes a unary function uf and a list lis in terms of reduce, that is, by determining the corresponding f and id in
(mymap uf lis) = (reduce f id lis),
Recall that mymap returns a list resulting from calling the function on every element in the input list such as (mymap (lambda(x) (* 2 x)) '(1 2 3)) = (2 4 6).
A little Explanation to how this has been done would be helpful, rather than a blatant answer. Thank You.
we have
(mymap uf lis) = (reduce f id lis) =
= (if (null? lis) id
(f (car lis) (reduce f id (cdr lis))))
which must be equal to
= (if null? lis) '()
(cons (uf (car lis)) (mymap uf (cdr lis))))
matching the corresponding entities, we get
id == '()
and, since (mymap uf lis) = (reduce f id lis), it is also (mymap uf (cdr lis)) = (reduce f id (cdr lis)), so we have
(f x y) = (cons (uf x) y)
Thus, we define
(define (mymap uf xs) ; multiple `x`-es :)
(reduce (lambda (x r)
(cons .... r))
'()
xs ))
your reduce is a right fold: its combining function receives an element x of the argument list xs, and the recursive result of working on the rest of list, as r.
r has all the elements of the rest of xs, which were already mapped through uf. All that's left to do to combine the given element x with this recursive result r, is to cons the (uf x) onto r.
It should pose no problem now to complete the definition by writing the actual code in place of the dots .... there.
I'm a newbie and I didn't understand very well the language. Could anyone please explain to me what this functions do?
First function:
(define (x l)
(cond
((null? l) 0)
((list? (car l))
(+ (x (car l)) (x (cdr l))))
(else (+ 1 (x (cdr l))))
))
Second function:
(define (x l)
(cond
((null? l) 0)
((list? (car l))
(+ (x (car l)) (x (cdr l))))
(else (+ (car l) (x (cdr l)))
))
I do understand the begining but the conditions I didn't understand. Any help?
I will call your second function y.
Writing in pseudocode,
x [] -> 0
x [a . b] -> x a + x b , if list a
x [a . b] -> 1 + x b , else, i.e. if not (list a)
y [] -> 0
y [a . b] -> y a + y b , if list a
y [a . b] -> a + y b , else, i.e. if not (list a)
So for example,
x [2,3] = x [2 . [3]]
= 1 + x [3]
= 1 + x [3 . []]
= 1 + (1 + x [])
= 1 + (1 + 0 )
and
y [2,3] = y [2 . [3]]
= 2 + y [3]
= 2 + y [3 . []]
= 2 + ( 3 + y [])
= 2 + ( 3 + 0 )
See? The first counts something in the argument list, the second sums them up.
Of course both functions could be called with some non-list, but then both would just cause an error trying to get (car l) in the second clause, (list? (car l)).
You might have noticed that the two are almost identical. They both accumulates (fold) over a tree. Both of them will evaluate to 0 on the empty tree and both of them will sum the result of the same procedure on the car and cdr when the car is a list?. The two differ when the car is not a list and in the first it adds 1 for each element in the other it uses the element itself in the addition. It's possible to write the same a little more compact like this:
(define (sum l)
(cond
((null? l) 0) ; null-value
((not (pair? l)) l) ; term
(else (+ (sum (car l)) (sum (cdr l)))))) ; combine
Here is a generalisation:
(define (accumulate-tree tree term combiner null-value)
(let rec ((tree tree))
(cond ((null? tree) null-value)
((not (pair? tree)) (term tree))
(else (combiner (rec (car tree))
(rec (cdr tree)))))))
You can make both of your procedures in terms of accumulate-tree:
(define (count tree)
(accumulate-tree tree (lambda (x) 1) + 0))
(define (sum tree)
(accumulate-tree tree (lambda (x) x) + 0))
Of course you can make a lot more than this with accumulate-tree. It doesn't have to turn into an atomic value.
(define (double tree)
(accumulate-tree tree (lambda (x) (* 2 x)) cons '()))
(double '(1 2 ((3 4) 2 3) 4 5)) ; ==> (2 4 ((6 8) 4 6) 8 10)
Is there way to change - (minus) function to + (plus) function?
My homework is to implement sin calculation on Macluaurin series
sin(x) = x-(x^3/3!)+(x^5/5!) -(x^7/7!)+(x^9/9!)-...
Each article has different sign. This is my Lisp code
(defun sinMac (x series n plusminus)
(cond ((= series 0) 0)
(t (funcall plusminus
(/ (power x n) (factorial n))
(sinMac x (- series 1) (+ n 2) plusminus)))))
Is it possible to change plusminus to exchange sign? if I get '+ function send '- to next recursive call. From that call (got '-) I call '+ and so on...
You could do it with a circular list. Like so:
(defun sin-mac (x series n plus-minus)
(cond ((zerop series) 0)
(t (funcall (car plus-minus)
(/ (power x n) (factorial n))
(sin-mac x (1- series) (+ n 2) (cdr plus-minus))))))
(sin-mac x series 1 '#0=(+ - . #0#))
Or even better, wrap up the initial arguments using labels:
(defun sin-mac (x series)
(labels ((recur (series n plus-minus)
(cond ((zerop series) 0)
(t (funcall (car plus-minus)
(/ (power x n) (factorial n))
(recur (1- series) (+ n 2) (cdr plus-minus)))))))
(recur series 1 '#0=(+ - . #0#))))
If the function is a symbol, this is easy:
(defun next-function (function)
(ecase function
(+ '-)
(- '+)))
(defun sinMac (x series n plusminus)
(cond ((= series 0) 0)
(t (funcall plusminus
(/ (power x n) (factorial n))
(sinMac x
(- series 1)
(+ n 2)
(next-function plusminus))))))
I would not swap the function but just the sign. Using a loop for this also seems clearer to me (and is most likely more efficient, although there is still plenty of opportunity for optimization):
(defun maclaurin-sinus (x n)
"Calculates the sinus of x by the Maclaurin series of n elements."
(loop :for i :below n
:for sign := 1 :then (- sign)
:sum (let ((f (1+ (* 2 i))))
(* sign
(/ (expt x f)
(factorial f))))))
A few optimizations make this about 10 times faster (tested with n = 5):
(defun maclaurin-sinus-optimized (x n)
"Calculates the sinus of x by the Maclaurin series of n elements."
(declare (integer n))
(loop :repeat n
:for j :from 0 :by 2
:for k :from 1 :by 2
:for sign := 1 :then (- sign)
:for e := x :then (* e x x)
:for f := 1 :then (* f j k)
:sum (/ e f sign)))
How can I write a function max-list-function that consumes a list of functions, then produces a function f such that for every x, (f x) produces the maximum value of all the functions g in the list of functions?
For example (max-list-function (lambda (n) (+ n 4)) (lambda (n) (- 15 n))))
produces a function such that (f 2) returns 13 and (f 10) returns 14.
This is to be done with abstract list functions (filter, foldr, map, ...) without recursion.
Try this:
(define (max-list-function flist)
(lambda (n)
(foldr max -inf.0
(map (lambda (f) (f n))
flist))))
Use it like this:
(define f (max-list-function
(list (lambda (n) (+ n 4)) (lambda (n) (- 15 n)))))
(f 2)
> 13.0
(f 10)
> 14.0