Convert list of lists into string in Clojure - clojure

How do I convert a LazySeq which is a list of lists into a string that has the exact same structure and parantheses?
(def my-list (lazy-seq '((a b 0 1 x y) (a b 0 4 x y) (a b 0 3 x y) )))
(def string-list (print-to-string my-list ))
string-list
;; should return "((a b 0 1 x y) (a b 0 4 x y) (a b 0 3 x y) ))"
;; but returns "clojure.lang.LazySeq#72251662"

If you want to keep the data as they are (or at least do your best with it), don't use str, but use pr-str. It might make no difference for simple things, but it will for more complex data structures.
E.g
user=> (pr-str (lazy-seq '((a b 0 1 x y) (a b 0 4 x y) (a b 0 3 x y) )))
"((a b 0 1 x y) (a b 0 4 x y) (a b 0 3 x y))"

for lazy sequences you can use print-str, which is alike simple print but writes the result to string.
user> (print-str my-list)
;;=> "((a b 0 1 x y) (a b 0 4 x y) (a b 0 3 x y))"
but beware, it obviously realizes the collection, and in case of infinite seq it would hang forever.
also you can override the print behaviour for any data type you want:
(defmethod print-method clojure.lang.LazySeq [data ^java.io.Writer w]
(let [[firsts] (split-at 10 data)]
(if (= 10 (count firsts))
(.write w (str (seq firsts) " :: more"))
(.write w (str (seq firsts))))))
user> (print-str (lazy-seq (range 1000)))
;;=> "(0 1 2 3 4 5 6 7 8 9) :: more"

Related

Clojure Fibonacci series using while in atom

How to achieve this using Clojure atom on the Fibonacci series.
(def x 0)
(def y 0)
(def z 1)
(defn problem []
(def a (atom 0))
(while (< #a 10 )
(do
;logic code need to write to achieve the output
; how can I add b,c == c,b???????.)
(swap! a inc)))
(problem)
output should be 0 1 1 2 3 5 8 13 21 34 55
As mentioned in the comments, defining and using an atom in a function is a totally non-clojure way of solving the question which makes it all the more difficult to solve. You should get familiar with the concept of immutability and higher order functions like map, filter, reduce, etc.
The code below gives you what you want.
(def fib1
(fn [n]
(cond
(= n 0) 1
(= n 1) 1
:else (+ (fib1 (dec n)) (fib1 (- n 2))))))
since this gives you just nth Fibonacci number, you should take + map with it if you want to get what you want.
(take 10 (map fib1 (range))) => (1 1 2 3 5 8 13 21 34 55)
take a look at this beautiful solution I found on internet.
(def fib-seq-iterate (map first (iterate (fn [[n m]] [m (+ n m)]) [0 1])))
This returns a lazy sequence, which can be called with
(take 5 fib-seq-iterate) => (0 1 1 2 3)
(def x 0)
(def y 0)
(def z 1)
(defn problem []
(def a (atom 0))
(while (< #a 10 )
(do
(println x)
(def x (+ y z))
(def y z)
(def z x)
(swap! a inc))))
(problem)
Output:
0 1 2 3 5 8 13 21 34 55

Clojure function for first differences, second differences,...,nth differences

Inputting a vector I'd like to write a function that gives successive differences between elements. Ideally the function should input a vector x and parameter n that designates nth difference.
Sample in the form [x n]
Input 1: [16 10 8 6 4 2] 1 (1 for first difference)
Output 1: [-6 -2 -2 -2 -2]
Input 2: [16 10 8 6 4 2] 2
Output 2: [4 0 0 0 nil nil]
Symbolically here's what is going on for sample 2 (meant as illustration of idea, not Clojure code)
[a b c d e f] 2
[a-2b+c, b-2c+d, c-2d+e, d-2e+f]
Here you go:
(def a [16 10 8 6 4 2])
(defn diff [a]
(map - (rest a) a))
(defn diff-n [a n]
(nth (iterate diff a) n))
(diff-n a 1) ; => (-6 -2 -2 -2 -2)
(diff-n a 2) ; => (4 0 0 0)
Same as #Shlomi 's answer but with an optional step size parameter:
(defn diff
([a]
(map - (next a) a))
([a step]
(map - (nthnext a step) a)))
(defn nthdiff
([a n]
(nth (iterate diff a) n))
([a n step]
(nth (iterate #(diff % step) a) n)))

How to (elegantly) iterate two lists at once?

I want to find better looking alternative to this code:
(def x (range 1 10))
(def y '(0 4 3 5 1 2 7 3 11))
(for [i (range 0 (count y))] [(nth x i) (nth y i)])
If I already have the result of previous I can simply
(def z (for [i (range 0 (count y))] [(nth x i) (nth y i)]))
(for [[x y] z] [x y])
Can you find some better looking alternative?
Example is made to be short and easilly to read. If you modify it to do something more complicated the first example can stop being readable.
You can use map:
(map vector x y)

Can clojure evaluate a chain of mixed arity functions and return a partial function if needed?

Suppose you have three functions of arity 1, 2 and 3 as below:
(defn I [x] x)
(defn K [x y] x)
(defn S [x y z] (x z (y z)))
Does clojure have an evaluation function or idiom for evaluating:
(I K S I I) as (I (K (S (I (I)))))
returning a parital function of arity 2?
I am considering creating a macro that can take the simple function definitions above and expand them to multi-arity functions that can return partial results. I would not want to create the macro if there is already a built in or idiomatic way to accomplish this.
Here is what the expanded macros would like for the above functions:
(defn I
([x] I x)
([x & more] (apply (I x) more)))
(defn K
([x] (partial K x))
([x y] x)
([x y & more] (apply (K x y) more)))
(defn S
([x] (partial S x))
([x y] (partial S x y))
([x y z] (x z (y z)))
([x y z & more] (apply (S x y z) more)))
I'm not sure I fully understand what you are trying to do, but the comp function is useful for doing this kind of "function chaining" you seem to be talking about. For example:
user> ((comp vec rest list) 1 2 3 4 5)
=> [2 3 4 5]
Which is equivalent to:
user> (vec (rest (list 1 2 3 4 5)))
=> [2 3 4 5]
In your case, if you have the list (I K S I I), and you want to evaluate it as (I (K (S (I (I))))), I would use (reduce comp ...), but you could also use (apply comp ...).
user> ((reduce comp [vec rest list]) 1 2 3 4 5)
=> [2 3 4 5]
user> ((apply comp [vec rest list]) 1 2 3 4 5)
=> [2 3 4 5]
You may also be interested in the -> or ->> macros. These macros nest their arguments sequentially into the next arguments. The -> macro will nest into the first position of the next expression, whereas the ->> macro will nest into the last position of the next expression. If the "next thing" is a function, both will behave the same, and form an expression of (function nested-things-so-far), and continue along.
Really, examples are best:
(-> 1 (+ 10) (- 100) inc)
;//Expands to...
(inc (- (+ 1 10) 100))
;//Evaluating in the REPL...
user> (-> 1 (+ 10) (- 100) inc)
=> -88
(->> 1 (+ 10) (- 100) inc)
;//Expands to...
(inc (- 100 (+ 10 1)))
;//Evaluating in the REPL...
user> (-> 1 (+ 10) (- 100) inc)
=> 90
However, it seems more like you want to do something involving auto-currying (although, again, I don't think I fully understand), and for that I don't know of anything pre-existing built-in way.

Unexpected result from reduce function

I would like to get the smallest element from a vector. For this I use combine the reduce and min functions. However, when providing my own implementation of min I get unexpected results:
user=> (reduce (fn [x y] (< x y) x y) [1 2 3 2 1 0 1 2])
2
user=> (reduce min [1 2 3 2 1 0 1 2 3])
0
The reduce with standard min returns 0 as expected. However, when I provide my own implementation it returns 2. What am I doing wrong?
You're missing an if:
(reduce (fn [x y] (if (< x y) x y)) ...)
^-- note the if
works fine. :-)
You are missing if around the function's body. What happens now is:
user> (use 'clojure.contrib.trace)
nil
user> (defn foo [x y] (< x y) x y)
#'user/foo
user> (dotrace [foo] (reduce foo [1 2 3 2 1 0 1 2]))
TRACE t2229: (foo 1 2)
TRACE t2229: => 2
TRACE t2230: (foo 2 3)
TRACE t2230: => 3
TRACE t2231: (foo 3 2)
TRACE t2231: => 2
TRACE t2232: (foo 2 1)
TRACE t2232: => 1
TRACE t2233: (foo 1 0)
TRACE t2233: => 0
TRACE t2234: (foo 0 1)
TRACE t2234: => 1
TRACE t2235: (foo 1 2)
TRACE t2235: => 2
2
In other words the function you pass in always returns y, so in the last iteration 2 is returned, since 2 is the last number of the sequence you reduced.
Also note that min already is based on reduce:
(defn min
"Returns the least of the nums."
([x] x)
([x y] (if (< x y) x y))
([x y & more]
(reduce min (min x y) more)))
A fn used with reduce probably needs to handle 3 arities - 0, 1, and 2 arguments.