Creating a sequence of all values in Clojure - clojure

I'm currently working on a kata code challenge and it comes with a few requirements:
The number u(0) = 1 is the first one in u.
For each x in u, then y = 2 * x + 1 and z = 3 * x + 1 must be in u too.
There are no other numbers in u.
I have constructed a few functions:
(defn test2 [x n orgN] ;;x is a counter, n is what I want returned as a list
(println n)
(println "this is x: " x)
(cons n (if (not= x (- orgN 1 ))
(do (test2 (+ x 1) (+ 1 (* n 2)) orgN)
(test2 (+ x 1) (+ 1 (* n 3)) orgN))
nil)
))
(defn test2helper [n]
(def x 1)
(test2 x x n)
)
(test2helper 5)
However this only returns (1 4 13 40) and misses a whole bunch of values in between. Cons is only constructing a list based on the last 3n+1 algorithm and not picking up any other values when I want instead a sequence of the two values generated from each n value repeated. My question is is there a way to construct a sequence of all the values instead of just 4 of them?
https://www.codewars.com/kata/twice-linear/train/clojure

This solution is pretty close to being correct. But remember that do is for performing side effects, not for producing values. Specifically, (do x y) returns y after performing the side effects in x. But test2 does not have any side effects: it just returns a list. What you are looking for is instead (concat x y), a function which concatenates two lists together into a larger list.

Although Alan Malloy's solution answers your question, it does not solve the problem you refer to, which requires that the sequence is generated in increasing order.
My approach would be to generate the sequence lazily, according to the following pattern:
(defn recurrence [f inits]
(map first (iterate f inits)))
For example, you can define the Fibonacci sequence like this:
(defn fibonacci []
(recurrence (fn [[a b]] [b (+ a b)]) [1 1]))
=> (take 10 (fibonacci))
(1 1 2 3 5 8 13 21 34 55)
The sequence you need is harder to generate. Good hunting!

Related

Using partial over a collection, reduce -vs- apply

I have this curious demonstration of partials. Here is the code:
Start by declaring a vector and a partial. As expected, reduce and apply sums the integers on vector a:
> (def a [1 2 3 4 5])
> (def p (partial + 10))
> (apply + a)
15
> (reduce + a)
15
Now, using apply on the partial p and vector a, I'm getting the sum of a and the +10 from the partial, which makes sense:
> (apply p a)
25
Now, using (reduce) makes no sense to me. Where is 55 coming from?
> (reduce p a)
55
The closest I can come up with is, (reduce) version is adding 10 from the 1 index and ignoring the zero index before adding everything together:
> (+ (first a) (reduce + (map #(+ % 10) (rest a))))
55
I'm just curious if anyone knows what is happening here, exactly? I don't really know what answer I'm expecting with this, but I also don't understand what is happening either. I have no idea why I would get 55 as an answer.
The first thing to note is that + is variadic: it can be called with zero, one, two, or more arguments. When you do (apply + a) you are essentially calling + with five arguments and getting the sum back (15).
However, reduce treats the function as strictly binary and calls it repeatedly, with the result of the previous call as the first argument of the next call. (reduce + a) is (+ (+ (+ (+ 1 2) 3) 4) 5) which also happens to be 15.
So your partial is also variadic and can be called with five arguments, as in the apply call: (apply p a) = (p 1 2 3 4 5) = (+ 10 1 2 3 4 5) so you get 25.
The reduce on p is going to call it repeatedly as shown above, but this time the function adds 10 in each time: (reduce p a) = (p (p (p (p 1 2) 3) 4) 5) = (+ 10 (+ 10 (+ 10 (+ 10 1 2) 3) 4) 5) so you get four 10s and the 15 making 55.
Another way of looking at Sean Corfield's fine answer:
Given
(def p (partial + 10))
then (p x y) means (+ 10 x y), for any x and y.
So
(reduce p a)
means
(reduce (fn [x y] (+ 10 x y)) a)
... since the first argument to reduce is a function of two arguments.
No initial value is supplied, so (first a) is used as such, and the reduction is applied to (rest a), which has four elements.
All the elements of a get added in: the first as the initial value;
the others by reduction.
The 10 gets added on in every cycle of the reduction: four times.
So the final result is the same as
(+ (* 10 (dec (count a))) (reduce + a))
In this case, 55.

Evaluate Vector of Forms with Parameters

I've been working to figure out a was to evaluate collections of forms with arguments.
An example function:
(defn x
[a b c]
(+ a b c))
I would like to evaluate collections of the function x, where only some parameters are defined and others are passed in to end up with a list of the products of the evaluations of the x functions in the collection:
(defn y
[z]
(map #(eval %) [(x z 1 1) (x z 2 2) (x z 8 64)]))
The question is: how do I introduce z as a parameter to each of the functions in the collection when I map eval to each? Is this possible?
I am trying to avoid typing them all out because I have many inputs (hundreds) that I want to pass to x where I only have a small set of the second and third parameters (five or so) that I care about.
Is there a better way to accomplish this?
Thanks!
First, let's use some more explanatory names, simplify the definition of x, and not use eval:
(defn sum [& xs]
(apply + xs)) ;; could be inlined instead of a function
(defn sum-with [z]
(map (partial apply sum)
[[z 1 1]
[z 2 2]
[z 8 64]]))
(sum-with 3)
=> (5 7 75)
But I assume your real world problem is something more complex than summing numbers, so I'll assume your x function is doing something else and requires some positional arguments i.e. the order of arguments matters:
(defn transmogrify [this n1 n2 that]
(+ n1 n2 (* this that)))
(defn evaluate-sums [a b]
(map (partial apply transmogrify)
[[a 1 1 b]
[a 2 2 b]
[a 8 64 b]]))
(evaluate-sums 3 9)
=> (29 31 99)
So if I understand correctly, you can accomplish your goal just by applying sequences of arguments to your function. Or to be more explicit with args/not use apply, just use a more specific anonymous function with map:
(defn evaluate-sums [z]
(map (fn [[this n1 n2 that]]
(transmogrify this n1 n2 that))
[[z 1 1 99]
[z 2 2 360]
[z 8 64 -1]]))
I am trying to avoid typing them all out because I have many inputs (hundreds) that I want to pass to x where I only have a small set of the second and third parameters (five or so) that I care about.
If your "fixed" arguments are always the same arity, then you can use variadic arity for the rest of the arguments:
(defn sum [a b & cs]
(apply + a b cs))
(defn evaluate-sums [zs]
(map (fn [[a b & cs]]
(apply sum a b cs))
[[1 1 zs]
[2 2 zs]
[8 64 zs]]))
Where zs is a collection/sequence of your extra arguments.

find all subsets of an integer collection that sums to n

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.

Processing a seq by accessing its prior elements

I want to create a sequence, however to create its every element I need access to the two previous elements. What is the generic way to do such things in clojure ?
So two slightly diff cases -
a) seq is (a b c) when I am processing c I want to have access to a and b ....
b) and having such ability to create the sequence itself by always being able to access th two previous elements.
Thanks,
Murtaza
partition gives you this nearly for free:
(partition-all 3 1 (range 100))
((0 1 2) (1 2 3) (2 3 4) (3 4 5) (4 5 6) (5 6 7) (6 7 8) ... )
then you can map your function over the sequence of partitions:
(map my-func (partition-all 3 1 (range 100)))
you just need to make your function aware of the fact that the last segment may have less than three elements if your seq is not a multiple of three. if you want to just drop any extras use partition instead of partition-all
Well, here is one way to do it. Assume you have a function g that takes the last two values as input and produces the next value.
(defn f [g x0 x1]
(let [s (g x0 x1)]
[s (fn [] (f g x1 s))]))
Given g and two consecutive values in the sequence, f returns a pair consisting of the next value and a function that will return the value after that. You can use f as follows to generate an infinite sequence of such pairs:
(iterate (fn [[v h]] (h)) (f g x0 x1))
To extract just the sequence values, do this:
(map first (iterate (fn [[v h]] (h)) (f g x0 x1)))
For example:
user=> (take 10 (map first (iterate (fn [[v h]] (h)) (f + 0 1))))
(1 2 3 5 8 13 21 34 55 89)
You can iterate using a vector of two elements and then take the first of the resulting sequence.
For example, to create the fibonacci series:
user=> (def fib (map first (iterate (fn [[a b]] [b (+ a b)]) [1 1])))
#'user/fib
user=> (take 10 fib)
(1 1 2 3 5 8 13 21 34 55)

Cleaning up Clojure function

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?