I'm very new to Clojure, and I was trying to implement from scratch (I don't want to use any module) a function to get some sort of triangular matrix from an original matrix, like so:
((1 2 3) (4 5 6) (7 8 9)) --> ((1 2 3) (5 6) (9))
I could get this to work using recursion but I also wanted to achieve this without using recursion, if possible. Any idea would be much appreciated.
The way I solved this using recursion is:
(defn get-sup-triang [m]
(cond
(empty? (rest (first m))) m
true (cons (first m) (get-sup-triang (rest (map rest m))))))
You can use drop to get rid of the 0-n elements from the front. If
you use it with a map you can feed both a simple range and your matrix.
E.g.
(map drop (range) matrix)
; ((1 2 3) (5 6) (9))
Related
I want to generate the length of the longest sublist. For example, for the list (1 (2 (3 (4 5)) (6 7) 8) 9) , the result would be 4, because of the sublist (2 (3 (4 5)) (6 7) 8), which has 4 as the length.
I have tried to do this:
(defun len(l)
(cond
((null l) 0)
((atom l) 1)
(t (+ (len(cdr l)) 1))
)
)
(defun lun(l)
(cond
((atom l) 1)
(t(apply #'max (mapcar #' len l)))
)
)
For the example above, it returns 4, but the problem is that it analyses just the first level of the sublist. If i try to resolve it for the list (1 (2 (3 (4 5 a a a a)) (6 7) 8) 9) it also returns 4, even though it should be 6 because of the list (4 5 a a a a), it still only takes the list (2 (3 (4 5 a a a a)) (6 7) 8).
Thank you in advance.
Your inputs are list of lists of lists (etc.), also known as trees.
You want to compute the longest length of one of the lists that makes a tree. Roughly speaking, you need to iterate over subtrees, compute their respective longest length, and combine those length into a new, maximal length.
A first sketch of the function is as follows, based on the LOOP macro (you still need a bit of work to convert it to a fully recursive solution):
(defun longest-length (tree)
(loop for subtree in tree maximize (longest-length subtree)))
Just as explained above, you divide your problems into subproblems, solve them recursively by finding
for each subtree their longest length, and combine them by returning the
maximum of each local maximum.
But the above is missing a couple of things. First, you need to take into account that the tree's length itself should be computed:
(defun longest-length (tree)
(max (length tree)
(loop for subtree in tree maximize (longest-length subtree))))
Also, the code fails when it reaches items that are not cons-cells.
You now have to add code for the base case where trees are not cons-cells. In particular, nil is treated as an empty lists and not as a symbol:
(defun longest-length (tree)
(typecase tree
(cons (max (length tree)
(loop
for subtree in tree
maximize (longest-length subtree))))
(null 0)
(t 1)))
Here is a test:
CL-USER> (longest-length '(1 (2 (3 (4 5 a a a a)) (6 7) 8) 9))
6
Consider also using reduce, which unlike apply introduces no restrictions on the number of elements in the list (call-argument-limit):
(reduce #'max (mapcar ... tree) :initial-value (length tree))
I am trying to write a lazy seq to generate the Collatz sequence for a given input int.
I love this function because is so cleanly maps to the mathematical definition:
(defn collatz
"Returns a lazy seq of the Collatz sequence starting at n and ending at 1 (if
ever)."
[n]
(letfn [(next-term [x]
(if (even? x)
(/ x 2)
(inc (* 3 x))))]
(iterate next-term n)))
The problem is that this produces infinite seqs because of how the Collatz sequence behaves:
(take 10 (collatz 5))
=> (5 16 8 4 2 1 4 2 1 4)
I could easily drop the cycle by adding (take-while #(not= 1 %) ...), but the 1 is part of the sequence. All the other ways I've thought to trim the cycle after the one are ugly and obfuscate the mathematical heart of the Collatz sequence.
(I've considered storing the seen values in an atom and using that in a take-while predicate, or just storing a flag in an atom to similar effect. But I feel like there is some better, more beautiful, less intrusive way to do what I want here.)
So my question: What are clean ways to detect and trim cycles in infinite seqs? Or, could I generate my lazy seq in a way (perhaps using for) that automatically trims when it reaches 1 (inclusive)?
The below looks like a more or less literal translation of the definition and gives the result you want:
(defn collatz-iter [x]
(cond (= x 1) nil
(even? x) (/ x 2)
:else (inc (* 3 x))))
(defn collatz [n]
(take-while some? (iterate collatz-iter n)))
(collatz 12) ;; => (12 6 3 10 5 16 8 4 2 1)
Basically, you can use nil as the value to stop the sequence, thus keeping the final 1.
you could also use another approach, which is recursive lazy-seq generation. That is quite common for this class of tasks, doesn't break the lazy sequence abstraction and avoids intermediate sequences' creation:
(defn collatz [n]
(if (== n 1)
(list 1)
(lazy-seq (cons n (collatz (if (even? n)
(/ n 2)
(inc (* 3 n))))))))
user> (collatz 12)
;;=> (12 6 3 10 5 16 8 4 2 1)
i'm trying to find a function that, given S a set of integer and I an integer, return all the subsets of S that sum to I
is there such a function somewhere in clojure-contrib or in another library ?
if no, could anyone please give me some hints to write it the clojure way?
Isn't this the subset sum problem, a classic NP-complete problem?
In which case, I'd just generate every possible distinct subset of S, and see which subsets sums to I.
I think it is the subset sum problem, as #MrBones suggests. Here's a brute force attempt using https://github.com/clojure/math.combinatorics (lein: [org.clojure/math.combinatorics "0.0.7"]):
(require '[clojure.math.combinatorics :as c])
(defn subset-sum [s n]
"Return all the subsets of s that sum to n."
(->> (c/subsets s)
(filter #(pos? (count %))) ; ignore empty set since (+) == 0
(filter #(= n (apply + %)))))
(def s #{1 2 45 -3 0 14 25 3 7 15})
(subset-sum s 13)
; ((1 -3 15) (2 -3 14) (0 1 -3 15) (0 2 -3 14) (1 2 3 7) (0 1 2 3 7))
(subset-sum s 0)
; ((0) (-3 3) (0 -3 3) (1 2 -3) (0 1 2 -3))
These "subsets" are just lists. Could convert back to sets, but I didn't bother.
You can generate the subsets of a set like this:
(defn subsets [s]
(if (seq s)
(let [f (first s), srs (subsets (disj s f))]
(concat srs (map #(conj % f) srs)))
(list #{})))
The idea is to choose an element from the set s: the first, f, will do. Then we recursively find the subsets of everything else, srs. srs comprises all the subsets without f. By adding f to each of them, we get all the subsets with f. And together, that's the lot. Finally, if we can't choose an element because there aren't any, the only subset is the empty one.
All that remains to do is to filter out from all the subsets the ones that sum to n. A function to test this is
(fn [s] (= n (reduce + s)))
It is not worth naming.
Putting this together, the function we want is
(defn subsets-summing-to [s n]
(filter
(fn [xs] (= n (reduce + xs)))
(subsets s)))
Notes
Since the answer is a sequence of sets, we can make it lazier by changing concat into lazy-cat. map is lazy anyway.
We may appear to be generating a lot of sets, but remember that they share storage: the space cost of keeping another set differing by a single element is (almost) constant.
The empty set sums to zero in Clojure arithmetic.
I am still learning about high order functions and going to be quizzed on it soon. I am trying to write a program that takes 2 lists of the same length and subtracts the first from second, item by item, until you get 0 in the first position.
(check-expect (min (list 1 1 1) (list 2 4 6)) (list 2 4))
(check-expect (min (list 1 1) (list 2 3)) (list 1))
I can easily do this without map, but Is there any way I can use map here?
(map - 1 (list ...))
or when I pass it on to the first of a list, or rest.
wont work. I know it takes in a function and passes on to each element of a list. I am confused.
This is not a good example to start learning about map. The map higher-order procedure takes a list as input, and returns another list of the same length as output, where a function was applied to each of the elements in the input. See why this is not such a clear-cut case for using map? the output lists are smaller than the inputs!
Of course, it can be done, but it's not that elegant, and obscures the true purpose of map:
(define (min lst1 lst2)
(if (zero? (first lst2)) ; if the first position in lst2 is zero
(rest lst2) ; then return the rest of it.
(min lst1 ; otherwise advance recursion
(map - lst2 lst1)))) ; ok, here `map` was useful
To understand what's happening in the last line, imagine that the input lists are one on top of the other:
'(2 4 6)
'(1 1 1)
Then, map applies the - function element-wise:
(- 2 1)
(- 4 1)
(- 6 1)
And the result of each operation is collected in a new list:
'(1 3 5)
This is a special case of map: when there's more than one list after the function, it applies the function to the first element of each list before advancing to the next - hence the function must accept as many arguments as there are lists. The usual case with map is that you simply apply the function to each of the elements in a single list, and but the way this is a good place to use lambda:
(map (lambda (x) (* x x))
'(1 2 3 4 5))
=> '(1 4 9 16 25)
Coming from imperative programming languages, I am trying to wrap my head around Clojure in hopes of using it for its multi-threading capability.
One of the problems from 4Clojure is to write a function that generates a list of Fibonacci numbers of length N, for N > 1. I wrote a function, but given my limited background, I would like some input on whether or not this is the best Clojure way of doing things. The code is as follows:
(fn fib [x] (cond
(= x 2) '(1 1)
:else (reverse (conj (reverse (fib (dec x))) (+ (last (fib (dec x))) (-> (fib (dec x)) reverse rest first))))
))
The most idiomatic "functional" way would probably be to create an infinite lazy sequence of fibonacci numbers and then extract the first n values, i.e.:
(take n some-infinite-fibonacci-sequence)
The following link has some very interesting ways of generating fibonnaci sequences along those lines:
http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Lazy_Fibonacci
Finally here is another fun implementation to consider:
(defn fib [n]
(let [next-fib-pair (fn [[a b]] [b (+ a b)])
fib-pairs (iterate next-fib-pair [1 1])
all-fibs (map first fib-pairs)]
(take n all-fibs)))
(fib 6)
=> (1 1 2 3 5 8)
It's not as concise as it could be, but demonstrates quite nicely the use of Clojure's destructuring, lazy sequences and higher order functions to solve the problem.
Here is a version of Fibonacci that I like very much (I took the implementation from the clojure wikibook: http://en.wikibooks.org/wiki/Clojure_Programming)
(def fib-seq (lazy-cat [0 1] (map + (rest fib-seq) fib-seq)))
It works like this: Imagine you already have the infinite sequence of Fibonacci numbers. If you take the tail of the sequence and add it element-wise to the original sequence you get the (tail of the tail of the) Fibonacci sequence
0 1 1 2 3 5 8 ...
1 1 2 3 5 8 ...
-----------------
1 2 3 5 8 13 ...
thus you can use this to calculate the sequence. You need two initial elements [0 1] (or [1 1] depending on where you start the sequence) and then you just map over the two sequences adding the elements. Note that you need lazy sequences here.
I think this is the most elegant and (at least for me) mind stretching implementation.
Edit: The fib function is
(defn fib [n] (nth fib-seq n))
Here's one way of doing it that gives you a bit of exposure to lazy sequences, although it's certainly not really an optimal way of computing the Fibonacci sequence.
Given the definition of the Fibonacci sequence, we can see that it's built up by repeatedly applying the same rule to the base case of '(1 1). The Clojure function iterate sounds like it would be good for this:
user> (doc iterate)
-------------------------
clojure.core/iterate
([f x])
Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects
So for our function we'd want something that takes the values we've computed so far, sums the two most recent, and returns a list of the new value and all the old values.
(fn [[x y & _ :as all]] (cons (+ x y) all))
The argument list here just means that x and y will be bound to the first two values from the list passed as the function's argument, a list containing all arguments after the first two will be bound to _, and the original list passed as an argument to the function can be referred to via all.
Now, iterate will return an infinite sequence of intermediate values, so for our case we'll want to wrap it in something that'll just return the value we're interested in; lazy evaluation will stop the entire infinite sequence being evaluated.
(defn fib [n]
(nth (iterate (fn [[x y & _ :as all]] (cons (+ x y) all)) '(1 1)) (- n 2)))
Note also that this returns the result in the opposite order to your implementation; it's a simple matter to fix this with reverse of course.
Edit: or indeed, as amalloy says, by using vectors:
(defn fib [n]
(nth (iterate (fn [all]
(conj all (->> all (take-last 2) (apply +)))) [1 1])
(- n 2)))
See Christophe Grand's Fibonacci solution in Programming Clojure by Stu Halloway. It is the most elegant solution I have seen.
(defn fibo [] (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))
(take 10 (fibo))
Also see
How can I generate the Fibonacci sequence using Clojure?