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)
Related
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
in clojure I'm using the following function to initialize a 2d vector:
(defn vec2d [x y init]
(vec (map
#(vec (map init (range x))) (range y))))
usage:
(def grid (vec2d 40 30 (fn [] "x")))
Since I'm new to the language, I ask myself if this is the most straight-forward way to do so. Has anyone an idea to optimize this?
Under the assumption that you'll always want to initialize the entries of the vector to a constant, here's how I'd do this:
(defn vec2d
"Return an x by y vector with all entries equal to val."
[x y val]
(vec (repeat y (vec (repeat x val)))))
if you want to be able to initialize according to the coordinate, you could do this
(defn vec2d [sx sy f]
(mapv (fn[x](mapv (fn[y] (f x y)) (range sx))) (range sy)))
This allows you to have a constant value if you do
(vec2d 4 3 (constantly 2))
;; [[2 2 2 2] [2 2 2 2] [2 2 2 2]]
or initialize according to the coordinates, say:
(vec2d 4 3 (fn[x y] (+ x y)))
(vec2d 4 3 +) ;; or more concisely
;;[[0 1 2 3] [1 2 3 4] [2 3 4 5]]
Use mapv and you're set
(defn vec2d [x y init]
(mapv #(mapv init (range x)) (range y)))
If you want the coordinates for initialization:
(defn vec2d [x y init]
(mapv (fn [y] (mapv #(init % y) (range x))) (range y))
A nested for it's also very readable for boards generation if you just want all cells:
(defn vec2d [cols rows init]
(for [x (range rows) y (range cols)]
(init x y)))
Or if you don't mind seqs:
(defn vec2d [cols rows init]
(for [x (range rows)]
(for [y (range cols)]
(init x y))))
Using a threading macro:
(defn vec-2d [r c v] (->> (repeat c v) vec (repeat r) vec))
I wonder what is the sense of a :let modifier when using the for loop in Clojure?
:let lets you define named values, in the same sense that the let special form lets you do it:
(for [i (range 10)
:let [x (* i 2)]]
x) ;;=> (0 2 4 6 8 10 12 14 16 18)
is equivalent to:
(for [i (range 10)]
(let [x (* i 2)]
x)) ;;=> (0 2 4 6 8 10 12 14 16 18)
except when used in combination with :when (or :while):
(for [i (range 10)
:let [x (* i 2)]
:when (> i 5)]
x) ;;=> (12 14 16 18)
(for [i (range 10)]
(let [x (* i 2)]
(when (> i 5) x))) ;;=> (nil nil nil nil nil nil 12 14 16 18)
You can use :let to create bindings inside a list comprehension like let.
To quote an example of the clojure documentation:
user=> (for [x [0 1 2 3 4 5]
:let [y (* x 3)]
:when (even? y)]
y)
(0 6 12)
The trick is that you can now use y in the :while and :when modifiers, instead of writing something like
user=> (for [x [0 1 2 3 4 5]
:when (even? (* x 3))]
(* x 3))
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.
Here is a problem Statement :
Define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers.
The solution is long,
(defn large [x y]
(if (> x y) x y))
(defn large-3 [x y z]
(if(> (large x y) z) (large x y) z))
(defn small [x y]
(if (< x y) x y))
(defn small-3 [x y z]
(if (< (small x y) z ) (small x y) z))
(defn second-largest [x y z]
(let [greatest (large-3 x y z)
smallest (small-3 x y z)]
(first (filter #(and (> greatest %) (< smallest %)) [x y z]))))
(defn square [a]
(* a a)
)
(defn sum-of-square [x y z]
(+ (square (large-3 x y z)) (square (second-largest x y z))))
Just wanted to know what different/succinct ways this problem can be solved in Clojure.
(defn foo [& xs]
(let [big-xs (take 2 (sort-by - xs))]
(reduce + (map * big-xs big-xs))))
; why only 3? how about N
(defn sum-of-squares [& nums]
(reduce + (map #(* % %) (drop 1 (sort nums)))))
or if you want "the sum of the greatest two numbers:
(defn sum-of-squares [& nums]
(reduce + (map #(* % %) (take 2 (reverse (sort nums))))))
(take 2 (reverse (sort nums))) fromMichał Marczyk's answer.
(See a sequence version of the problem together with a lazy solution in my second update to this answer below.)
(defn square [n]
(* n n))
;; generalises easily to larger numbers of arguments
(defn sum-of-larger-squares [x y z]
(apply + (map square (take 2 (reverse (sort [x y z]))))))
;; shorter; generalises easily if you want
;; 'the sum of the squares of all numbers but n smallest'
(defn sum-of-larger-squares [x y z]
(apply + (map square (drop 1 (sort [x y z])))))
Update:
To expand on the comments from the above, the first version's straighforward generalisation is to this:
(defn sum-of-larger-squares [n & xs]
(apply + (map square (take n (reverse (sort xs))))))
The second version straightforwardly generalises to the version Arthur posted in the meantime:
(defn sum-of-larger-squares [n & xs]
(apply + (map square (drop n (sort xs)))))
Also, I've seen exactly the same problem being solved in Scheme, possibly even on SO... It included some fun solutions, like one which calculated the some of all three squares, then subtracted the smallest square (that's very straightforward to express with Scheme primitives). That's 'unefficient' in that it calculates the one extra square, but it's certainly very readable. Can't seem to find the link now, unfortunately.
Update 2:
In response to Arthur Ulfeldt's comment on the question, a lazy solution to a (hopefully fun) different version of the problem. Code first, explanation below:
(use 'clojure.contrib.seq-utils) ; recently renamed to clojure.contrib.seq
(defn moving-sum-of-smaller-squares [pred n nums]
(map first
(reductions (fn [[current-sum [x :as current-xs]] y]
(if (pred y x)
(let [z (peek current-xs)]
[(+ current-sum (- (* z z)) (* y y))
(vec (sort-by identity pred (conj (pop current-xs) y)))])
[current-sum
current-xs]))
(let [initial-xs (vec (sort-by identity pred (take n nums)))
initial-sum (reduce + (map #(* % %) initial-xs))]
[initial-sum initial-xs])
(drop n nums))))
The clojure.contrib.seq-utils (or c.c.seq) lib is there for the reductions function. iterate could be used instead, but not without some added complexity (unless one would be willing to calculate the length of the seq of numbers to be processed at the start, which would be at odds with the goal of remaining as lazy as possible).
Explanation with example of use:
user> (moving-sum-of-smaller-squares < 2 [9 3 2 1 0 5 3])
(90 13 5 1 1 1)
;; and to prove laziness...
user> (take 2 (moving-sum-of-smaller-squares < 2 (iterate inc 0)))
(1 1)
;; also, 'smaller' means pred-smaller here -- with
;; a different ordering, a different result is obtained
user> (take 10 (moving-sum-of-smaller-squares > 2 (iterate inc 0)))
(1 5 13 25 41 61 85 113 145 181)
Generally, (moving-sum-of-smaller-squares pred n & nums) generates a lazy seq of sums of squares of the n pred-smallest numbers in increasingly long initial fragments of the original seq of numbers, where 'pred-smallest' means smallest with regard to the ordering induced by the predicate pred. With pred = >, the sum of n greatest squares is calculated.
This function uses the trick I mentioned above when describing the Scheme solution which summed three squares, then subtracted the smallest one, and so is able to adjust the running sum by the correct amount without recalculating it at each step.
On the other hand, it does perform a lot of sorting; I find it's not really worthwhile to try and optimise this part, as the seqs being sorted are always n elements long and there's a maximum of one sorting operation at each step (none if the sum doesn't require adjustment).