I need to make solution for reduce method using only SEQUENCES and Recursion
My solution:
(defn my-reduce
[f acc xs]
(when (seq xs)
(cons (f acc (first xs))
(my-reduce f (f (first xs) acc) (next xs)))))
(my-reduce + 0 '(1 2 3 4 5))
It returns: (1 3 6 10 15)
How to edit my solution, to return only result of this sequence: 15
Worked for me:
(defn my-reduce
[f acc xs]
(if (nil? xs)
acc
(my-reduce f (f (first xs) acc) (next xs))))
(my-reduce + 0 '(1 2 3 4 5))
Related
I'm new to clojure and tried to implement the some function (for some specific tests):
(my-some even? [1 2 3 4]) => true
(my-some #{3 4} [1 2 3 4]) => 3
(my-some zero? [1 2 3 4]) => nil
That's what I came up with so far:
(defn my-some [f x]
(loop [[y & t] x]
(if (empty? t) nil
(if (f y)
(f y)
(recur t)))))
I could imagine there are more idiomatic approaches.
Any suggestions?
Firstly, you have a bug: [[y & t] x] destructures x, but the following empty? check on t means you are ignoring the last element in the sequence. You can see this with
(my-some even? [2])
=> nil
You can replace (if (empty? x) nil (else-form)) with when and seq:
(when (seq x) ...)
you can then use first and next to deconstruct the sequence:
(defn my-some [f x]
(when (seq x)
(if (f (first x))
(f (first x))
(recur f (rest x)))))
the call to recur is then back into my-some so you need to pass the predicate f.
you can replace (if x x (else ....)) with (or x (else ...)):
(defn my-some [f x]
(when (seq x)
(or (f (first x)) (recur f (next x)))))
you can compare this with the implementation of some
I want to be able to sum the squares of the even elements in the list, however my current code only sums the elements, not the squares. Does anyone know of any modifications that can be made to make this to sum the squares of the even-valued elements in the list?
(define (sum elemList)
(if
(null? elemList)
0
(+ (car elemList) (sum (cdr elemList)))
)
)
My input would be:
(sum-evens (list 1 2 3 4))
Output would be:
20
Which is (2*2) + (4*4).
If possible, it would be good to see both a recursive and iterative solution.
Any ideas?
(sidenote, to see this post with emphasis but without syntax highlighting, click here)
With Racket's left fold function,
(define (foldl cons z ls)
(if (null? ls)
z
(foldl cons (cons (car ls) z) ; NB! args order
(cdr ls))))
we can easily implement the summing of a list ((foldl + 0 xs)), or the taking of the squares, or the filtering, separately.
It is also easy to nest them, so that one works with the results of the other (as is shown in the other answers), but that means three separate list traversals are performed and two interim lists are built in addition to the results list,
(define (sqr x) (* x x))
(define (foo-3 xs)
(foldl + 0
-- ^^^ -- vvvv
(foldl (lambda (x acc) (cons (sqr x) acc)) '()
(foldl (lambda (x acc) (if (even? x) (cons x acc) acc)) '()
xs))))
But actually, folding (or, "reducing") a list with a reducer function (like +) replaces the list's cons with that reducer function's application anyway, so why not just go ahead and use that reducer in place of that cons in the inner fold, in the first place? This means that the nested folds can be fused together as
(define (foo-2 xs)
(foldl (lambda (x acc) (+ (sqr x) acc)) 0
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ vvvv
(foldl (lambda (x acc) (if (even? x) (cons x acc) acc)) '()
xs)))
and, further, as
(define (foo-1 xs) ; one traversal, tail-recursive, iterative!
(foldl (lambda (x acc)
(if (even? x) (+ (sqr x) acc) acc)) 0
xs))
thus deriving the iterative one-traversal function that doesn't create any superfluous interim data at all, which could otherwise be hand-coded relatively easily, perhaps as a recursive variant seen in the other answers, but in any case hand coding is in general harder and prone to errors. Ideally, we would like to be able to easily write code which is self-evidently correct -- and efficient. This could be achieved by a framework to compose / fuse those separate folds semi-automatically.
Thus the need to abstract the cons can be seen here, so that it can be easily manipulated, replaced. In other words, we want
(lambda (x acc) (cons (sqr x) acc)) ==: ((mapping sqr) cons)
(lambda (x acc) (if (even? x) (cons x acc) acc)) ==: ((filtering even?) cons)
thus arriving at what's known as "transducers", i.e. reducer functions' transformers:
(define (((mapping f) kons) x acc) (kons (f x) acc)) ; "mapping" transducer
(define (((filtering p) kons) x acc) (if (p x) (kons x acc) acc)) ; "filtering" one
(define (foo xs)
(foldl + 0
(foldl ((mapping sqr) cons) '()
(foldl ((filtering even?) cons) '()
xs)))
=
(foldl ((mapping sqr) +) 0 ; replace the constructor!
(foldl ((filtering even?) cons) '() ; and the sentinel value
xs))
=
(foldl ((filtering even?) ((mapping sqr) +)) 0 ; and again!
; (lambda (x acc) ; look ma, no cons!
; (if (even? x) (+ (sqr x) acc) acc))
xs)
)
The (f (g x)) pattern is abstracted as the functional composition,
(define ((compose1 f g) x)
(f (g x)))
so that (f (g x)) is ((compose1 f g) x). With it, we can compose however many transducers we might need into one combined transducer, expecting of one argument which is a reducer function.
(define (transduce-list tducr r z xs)
(foldl ; lists are reduced with foldl
(tducr r) ; the full reducer is created by applying
z xs)) ; the transducer to the final reducer
(define (foo xs) ; sum the squares of evens in a list
(transduce-list ; by transducing the list
(compose1 ; with the transducer composed from
(filtering even?) ; a filtering step and
(mapping sqr)) ; a mapping step
+ 0 xs)) ; with + as the final reducer
and that's that!
So we have
(define (sqr1 x) (+ 1 (* x x))) ; for clearer testing results
> (foldl ((mapping sqr1) cons) '() '(1 2 3 4))
'(17 10 5 2)
> (foldl ((mapping sqr1) +) 0 '(1 2 3 4))
> 34
((mapping sqr1) cons), just like cons itself, is a function of two arguments, so can be used as the reducer function argument to foldl.
Having (define g ((mapping sqr1) cons)) is the same as
(define (g x acc)
(cons (sqr1 x) acc))
And with filtering we have
> (foldl ((filtering even?) +) 0 '(1 2 3 4))
> 6
> (foldl ((mapping sqr1) ((filtering even?) cons)) '() '(1 2 3 4))
> '(10 2)
> (foldl ((filtering even?) ((mapping sqr1) cons)) 0 '(1 2 3 4))
> '(17 5 . 0)
So, ((mapping sqr1) ((filtering even?) cons)) is a reducer, where (mapping sqr1) uses ((filtering even?) cons) as its reducer. And that is (filtering even?) using cons as its – final in the chain – reducer function:
(define g
((mapping sqr1) ((filtering even?) cons)))
=
(define (g x acc)
(let ((f ((filtering even?) cons)))
(f (sqr1 x) acc))) ; by definition of mapping
=
(define (g x acc)
(define (f y acc)
(if (even? y) (cons y acc) acc)) ; by definition of filtering
(f (sqr1 x) acc))
=
(define (g x acc)
(let ((y (sqr1 x)))
(if (even? y) (cons y acc) acc))) ; by application rule
Mmm, mapping, filtering, and consing are all automagically rolled up into one reducer function for us as if we've written it ourselves! Better yet, foldl being tail-recursive, the overall function is iterative and performs just one list traversal – because the three reducer functions were combined into one.
Some more testing:
(define (bar xs)
(foldl ((compose
(filtering even?) ; filtering is done first
(mapping sqr1))
cons)
0 xs))
(define (baz xs)
(foldl ((compose
(mapping sqr1) ; mapping is done first
(filtering even?))
cons)
'() xs))
so that
> (bar '(1 2 3 4 5))
'(17 5 . 0)
> (baz '(1 2 3 4 5))
'(26 10 2)
There are two possibilities, either we implement the recursion from scratch:
(define (sum elemList)
(cond ((null? elemList) 0)
((even? (car elemList))
(+ (* (car elemList) (car elemList))
(sum (cdr elemList))))
(else (sum (cdr elemList)))))
Or we use built-in procedures, defining helpers as needed. This strategy is known as using "sequences as conventional interfaces":
(define (square x)
(* x x))
(define (sum elemList)
(apply +
(map square
(filter even? elemList))))
In Scheme, the preferred way is the second one, because we must not reinvent the wheel when we have procedures that already do the job for us. Either way, it works as expected:
(sum '(1 2 3 4 5 6 7 8 9 10))
=> 220
(define (sum ls)
(if (null? ls)
0
(if (even? (car ls))
(+ (square (car ls)) (sum (cdr ls)))
(sum (cdr ls)))))
where
(define (square x)
(* x x))
sum the squares of the even elements. If you sum the elements of the list without doing anything, of course the answer cannot be the answer to your question.
What's more, one may implement this procedure in this way:
(define (sum ls)
(reduce +
0
(map square
(filter even?
ls))))
where map, filter and reduce are the common meanings(you can try it in mit-scheme). This do the same thing, however this is more readable, and things like cdr recursion are optimized. The second chapter in SICP(Structure and Interpretation
of Computer Programs) introduced this methodology of programming.
or with SICP style streams !
if this interests you, see section 3.5 of Structure and Interpretation of Computer Programs (Sussman, Abelson)
the stream functions here work much like the transducers described in #WillNess's answer – ie, streams do not require multiple iterations thru the data
all stream procedures here are recursive but evolve a linear iterative process
it's worth noting that cons-stream is a special form that does not immediately evaluate it's second argument
#lang sicp
(define (square x)
(* x x))
(define stream-car car)
(define (stream-cdr s)
(force (cdr s)))
(define (integers x)
(cons-stream x (integers (inc x))))
(define (stream-filter f s)
(cond ((stream-null? s) the-empty-stream)
((f (stream-car s)) (cons-stream (stream-car s) (stream-filter f (stream-cdr s))))
(else (stream-filter f (stream-cdr s)))))
(define (stream-map f s)
(if (stream-null? s)
the-empty-stream
(cons-stream (f (stream-car s)) (stream-map f (stream-cdr s)))))
(define (stream-take n s)
(cond ((stream-null? s) the-empty-stream)
((> n 0) (cons-stream (stream-car s) (stream-take (dec n) (stream-cdr s))))
(else the-empty-stream)))
(define (stream-reduce f acc s)
(if (stream-null? s)
acc
(stream-reduce f (f acc (stream-car s)) (stream-cdr s))))
(stream-reduce + 0
(stream-map square
(stream-filter even?
(stream-take 10
(integers 1)))))
;; => 220
transducers
it is with immense affection i present this portion of the answer for #WillNess
i was introduced to transducers thru a person who has a knack for distilling the overwhelmingly complex down to the miraculously simple – as a labour of love, i've adapted some of the code/ideas presented (originally in javascript) to scheme
each ;; [section] defines an abstraction barrier
edit: removed special forms for cons-cont and cons-trans – macro didn't critically improve code readability
#lang sicp
;; [procedure]
(define (compose f g)
(lambda (x) (f (g x))))
;; [list]
(define (foldl f acc xs)
(if (null? xs)
acc
(foldl f (f acc (car xs)) (cdr xs))))
;; [continuation]
(define cons-cont
identity)
(define the-empty-cont
identity)
(define cont-concat
compose)
(define (cont-concat-all cs)
(foldl cont-concat the-empty-cont cs))
;; [trans]
(define (cons-trans f)
(cons-cont (lambda (cont) (lambda (acc x) (f cont acc x)))))
(define the-empty-trans
the-empty-cont) ;; unused in this program, but completes implementation
(define trans-concat
cont-concat) ;; unused in this program, but completes implementation
(define trans-concat-all
cont-concat-all)
;; [transducer]
(define (cons-transducer . ts)
(lambda (f acc xs)
(foldl ((trans-concat-all ts) f) acc xs)))
(define (mapper f)
(cons-trans (lambda (next acc x) (next acc (f x)))))
(define (filterer f)
(cons-trans (lambda (next acc x) (if (f x) (next acc x) acc))))
(define (effector f)
(cons-trans (lambda (next acc x) (f x) (next acc x))))
(define (logger s)
(effector (lambda (x) (display s) (display " ") (display x) (display "\n"))))
;; [main]
(define (square x)
(* x x))
(define (main xs)
((cons-transducer (logger "input")
(filterer even?)
(logger "filtered")
(mapper square)
(logger "squared"))
+ 0 xs))
(main '(1 2 3 4 5 6 7 8 9 10))
output
input 1
input 2
filtered 2
squared 4
input 3
input 4
filtered 4
squared 16
input 5
input 6
filtered 6
squared 36
input 7
input 8
filtered 8
squared 64
input 9
input 10
filtered 10
squared 100
=> 220
So currently, I wrote a Clojure code to do Trapezoidal integration of a polynomial function in HackerRank.com:
https://www.hackerrank.com/challenges/area-under-curves-and-volume-of-revolving-a-curv
(defn abs[x]
(max x (- 0 x))
)
(defn exp[x n]
(if (> n 0)
(* x (exp x (- n 1)))
1
)
)
(defn fact[x]
(if (> x 0)
(* x (fact (- x 1)))
1)
)
(defn func[x lst1 lst2]
((fn step [sum lst1 lst2]
(if (> (.size lst1) 0)
(step (+ sum (* (last lst1) (exp x (last lst2)))) (drop-last lst1) (drop-last lst2))
sum
)
)
0 lst1 lst2
)
)
(defn integrate[f a b]
(def h 0.001)
(def n (/ (abs (- b a)) h))
((fn step[i sum]
(if (< i n)
(step (+ i 1) (+ sum (f (+ (* i h) a))))
(* h (+ (/(+ (f a) (f b)) 2) sum))
)
) 0 0)
)
(defn volumeIntegral[f a b]
(defn area[r]
(* 3.14159265359 (* r r)))
(def h 0.001)
(def n (/ (abs (- b a)) h))
((fn step[i sum]
(if (< i n)
(step (+ i 1) (+ sum (area (f (+ (* i h) a)))))
(* h (+ (/ (+ (f a) (f b)) 2) sum))
)
) 0 0)
)
(defn lineToVec[line_str] (clojure.string/split line_str #"\s+"))
(defn strToDouble [x] (Double/parseDouble (apply str (filter #(Character/isDigit %) x))))
(defn readline[vec]
((fn step[list vec]
(if (> (.size vec) 0)
(step (conj list (last vec)) (drop-last vec))
list
)
) '() vec)
)
(integrate (fn [x] (func x '(1 2 3 4 5 6 7 8) '(-1 -2 -3 -4 1 2 3 4))) 1 2)
(volumeIntegral (fn [x] (func x '(1 2 3 4 5 6 7 8) '(-1 -2 -3 -4 1 2 3 4))) 1 2)
However, the output I have is:
107.38602491666647
45611.95754801859
While is supposed to be around:
101.4
41193.0
My code passed the first two test cases, but didn't manage to pass the rest. I assume is because of the issue accuracy. I looked through my code several times but couldn't seem to make it better. What am I doing wrong here ? Thank you.
Your exp function isn't quite right -- it doesn't handle negative exponents correctly. Probably best just to use Math/pow.
The other thing you could do is adjust your h value in volumeIntegral but to avoid stack issues, use recur (which gives you tail recursion), e.g. here's a slightly modified version:
(defn volume-integral [f a b]
(defn area[r]
(* Math/PI (* r r)))
(def h 0.000001)
(def n (/ (abs (- b a)) h))
((fn [i sum]
(if (not (< i n))
(* h (+ (/ (+ (f a) (f b)) 2) sum))
(recur (+ i 1) (+ sum (area (f (+ (* i h) a)))))))
0 0))
(I did the something similar with integral.) All in all, I wasn't able to quite hit the second figure, but this should get you on the right track:
101.33517384995224
41119.11576557253
I have a function that receives a vector and sum all the elements.
(def rec
(fn [numbers acc]
(if (empty? numbers)
acc
(recur (rest numbers) (+ acc (first numbers))))))
(prn (rec [1 2 3] 0))
But instead of calling the function "+" I want to pass the operation as parameter, it means, I want to pass a function as parameter and then call the function.
I tried:
(def rec
(fn [f numbers acc]
(if (empty? numbers)
acc
(recur (rest numbers) (f acc (first numbers))))))
(prn (rec + [4 2 1] 0))
But it does not work, I know there are better ways to sum numbers in a vector, but I'm starting with functional, so it is important to do this kind of exercise.
Thanks in advance.
You need to recur with the same arguments as the parameter vector, in this case:
(recur f (rest numbers) (f acc (first numbers))))))
(btw, it's standard to use defn for defining functions, (defn f[x] ... ) is more concise than (def f (fn [x] ...)))
More ideomatic Clojure would be using reduce here, I think
(defn rec [f numbers acc]
(reduce f acc numbers))
(rec + [1 2 3] 0)
# 6
Factoring
In your
(def rec
(fn [numbers acc]
(if (empty? numbers)
acc
(recur (rest numbers) (+ acc (first numbers))))))
... you can push the accumulator acc beneath the surface of rec:
(defn rec [numbers]
(loop [ns numbers, acc 0]
(if (empty? ns)
acc
(recur (rest ns) (+ acc (first ns))))))
For example,
(rec + [1 3])
; 4
If you want to pass the operation as a parameter, the convention is that calling it with no arguments gives its identity: the value which returns the other argument when it is applied to two.
Thus
(+) ; => 0
(*) ; => 1
So we can write your parameterized rec as
(defn rec [op numbers]
(loop [ns numbers, acc (op)]
(if (empty? ns)
acc
(recur (rest ns) (op acc (first ns))))))
This is almost how reduce works, though not quite as elegantly, IMO.
I have sequence in clojure of theem
(1 2 3 4)
how can I get all the tails of sequence like
((1 2 3 4) (2 3 4) (3 4) (4) ())
Another way to get all tails is by using the reductions function.
user=> (def x '(1 2 3 4))
#'user/x
user=> (reductions (fn [s _] (rest s)) x x)
((1 2 3 4) (2 3 4) (3 4) (4) ())
user=>
If you want to do this with higher-level functions, I think iterate would work well here:
(defn tails [xs]
(concat (take-while seq (iterate rest xs)) '(()))
However, I think in this case it would be cleaner to just write it with lazy-seq:
(defn tails [xs]
(if-not (seq xs) '(())
(cons xs (lazy-seq (tails (rest xs))))))
Here is one way.
user=> (def x [1 2 3 4])
#'user/x
user=> (map #(drop % x) (range (inc (count x))))
((1 2 3 4) (2 3 4) (3 4) (4) ())
One way you can do that is by
(defn tails [coll]
(take (inc (count coll)) (iterate rest coll)))
(defn tails
[s]
(cons s (if-some [r (next s)]
(lazy-seq (tails r))
'(()))))
Yippee! Another one:
(defn tails [coll]
(if-let [s (seq coll)]
(cons coll (lazy-seq (tails (rest coll))))
'(())))
This is really just what reductions does under the hood. The best answer, by the way, is ez121sl's.