I am trying to obtain the first 10 Fibonacci numbers as follows:
(take 10 (fn fibgen [a b] (cons a (fibgen b (+ a b))) 0 1))
The idea is that fibgen creates a lazy sequence (an infinite stream). Unfortunately this gives the following error:
IllegalArgumentException Don't know how to create ISeq from:user$eval10144$fibgen__10145 clojure.lang.RT.seqFrom (RT.java:528)
How can this be fixed?
I think you just made a typo. Here's what your fibgen function looks like reformatted:
(fn fibgen [a b]
(cons a (fibgen b (+ a b)))
0
1)
This function realizes the entire Fibonacci sequence starting with a and b, then returns 1. What you meant to do was define a function that returns the sequence, call it with 0 and 1, and then take the first ten items from that sequence:
(take 10 ((fn fibgen [a b] (cons a (fibgen b (+ a b)))) 0 1))
If you run this, you'll get an ArithmeticException for integer overflow, because numbers in the Fibonacci sequence quickly leave the range of a 64-bit integer. You can fix this using +':
(take 10 ((fn fibgen [a b] (cons a (fibgen b (+' a b)))) 0 1))
Since Clojure isn't lazy, this will try to realize the entire Fibonacci sequence, which will cause a StackOverflowError. Even though Clojure itself isn't lazy, though, you can create a lazy sequence, which will have basically the same effect in this case:
(take 10 ((fn fibgen [a b] (lazy-seq (cons a (fibgen b (+' a b))))) 0 1))
;;=> (0 1 1 2 3 5 8 13 21 34)
Related
I need a function that maps a function only on every other element, e.g.
(f inc '(1 2 3 4))
=> '(2 2 4 4)
I came up with:
(defn flipflop [f l]
(loop [k l, b true, r '()]
(if (empty? k)
(reverse r)
(recur (rest k)
(not b)
(conj r (if b
(f (first k))
(first k)))))))
Is there a prettier way to achieve this ?
(map #(% %2)
(cycle [f identity])
coll)
It's a good idea to look at Clojure's higher level functions before using loop and recur.
user=> (defn flipflop
[f coll]
(mapcat #(apply (fn ([a b] [(f a) b])
([a] [(f a)]))
%)
(partition-all 2 coll)))
#'user/flipflop
user=> (flipflop inc [1 2 3 4])
(2 2 4 4)
user=> (flipflop inc [1 2 3 4 5])
(2 2 4 4 6)
user=> (take 11 (flipflop inc (range))) ; demonstrating laziness
(1 1 3 3 5 5 7 7 9 9 11)
this flipflop doesn't need to reverse the output, it is lazy, and I find it much easier to read.
The function uses partition-all to split the list into pairs of two items, and mapcat to join a series of two element sequences from the calls back into a single sequence.
The function uses apply, plus multiple arities, in order to handle the case where the final element of the partitioned collection is a singleton (the input was odd in length).
also, since you want to apply the function to some specific indiced items in the collection (even indices in this case) you could use map-indexed, like this:
(defn flipflop [f coll]
(map-indexed #(if (even? %1) (f %2) %2) coll))
Whereas amalloy's solution is the one, you could simplify your loop - recur solution a bit:
(defn flipflop [f l]
(loop [k l, b true, r []]
(if (empty? k)
r
(recur (rest k)
(not b)
(conj r ((if b f identity) (first k)))))))
This uses couple of common tricks:
If an accumulated list comes out in the wrong order, use a vector
instead.
Where possible, factor out common elements in a conditional.
I was wondering if someone would be able to help me create a function that would given a number would return the tribonacci number that corresponds to that number for example
10 would return 44
15 would return 927
Generally, you should show what you have already tried and then let us know what problem you are having, so we can point you to a fix. Asking Stack Overflow to do this for you from scratch is poor manners.
But, I love Clojure and these problems are fun. First of all, there are so many ways to do this, and just googling Clojure fibonacci will get you started in many many different directions for this.
Here is a quick example using reduce:
(defn tri [x]
(last (reduce
(fn [[a b c] n]
(conj [b c] (+ a b c))) [0 0 1] (range (- x 3)))))
You could also use iterate:
(nth (iterate (fn [[a b c]] [b c (+ a b c)]) [0 0 1]) 5)
This returns the 5th from the first set of tribonacci numbers, where [0 0 1] is the initial set.
To get an exact result from X'th index, also wrap it in a function as above, like so:
(defn tri-iterate [x]
(last
(nth (iterate (fn [[a b c]] [b c (+ a b c)]) [0 0 1]) (- x 3))))
You can do this in many other ways as well.
I did a very simple solution to fibonacci:
(defn fib [n]
(if (or (zero? n) (= n 1))
1
(+ (fib (dec n)) (fib (- n 2)))))
but instead of returning the value, for example
(fib 6) ; 13
I would return the sequence 0, 1, 1, 2, 3, 5, 8, 13... I was thinking about store the values in a sequence, but where should I return the sequence? I mean, verifying if I'm at the last call of fib does not sound much nice.
ps: I'm trying to solve this exercise: https://www.4clojure.com/problem/26
Clojure functions return the result of the last evaluated form. You could accumulate your Fibonacci numbers in a vector.
A nice lazy version of fibonacci is:
(def lazy-fib
"Lazy sequence of fibonacci numbers"
((fn rfib [a b]
(lazy-seq (cons a (rfib b (+' a b)))))
0 1))
Then you can use it with:
(fn [n] (take n lazy-fib))
Which gives, after some formatting for this problem:
(fn[n]
(drop 1 (take (inc n) ((fn rfib [a b]
(lazy-seq (cons a (rfib b (+' a b)))))
0 1))))
Consider a query function q that returns, with a delay, some (let say ten) results.
Delay function:
(defn dlay [x]
(do
(Thread/sleep 1500)
x))
Query function:
(defn q [pg]
(lazy-seq
(let [a [0 1 2 3 4 5 6 7 8 9 ]]
(println "q")
(map #(+ (* pg 10) %) (dlay a)))))
Wanted behaviour:
I would like to produce an infinite lazy sequence such that when I take a value only needed computations are evaluated
Wrong but explicative example:
(drop 29 (take 30 (mapcat q (range))))
If I'm not wrong, it needs to evaluate every sequence because it really doesn't now how long the sequences will be.
How would you obtain the correct behaviour?
My attempt to correct this behaviour:
(defn getq [coll n]
(nth
(nth coll (quot n 10))
(mod n 10)))
(defn results-seq []
(let [a (map q (range))]
(map (partial getq a)
(iterate inc 0)))) ; using iterate instead of range, this way i don't have a chunked sequence
But
(drop 43 (take 44 (results-seq)))
still realizes the "unneeded" q sequences.
Now, I verified that a is lazy, iterate and map should produce lazy sequences, so the problem must be with getq. But I can't understand really how it breaks my laziness...perhaps does nth realize things while walking through a sequence? If this would be true, is there a viable alternative in this case or my solution suffers from bad design?
In a Clojure program, I have a sequence of numbers:
(2 3 4 6 8 1)
I want to find the longest sub-sequence where the items are sequential:
(2 3 4)
I am assuming that it will involve (take-while ...) or (reduce ...).
Any ideas?
Clarification: I need the longest initial list of sequential items. Much easier, I'm sure. Thanks for the solutions to the more difficult problem I initially posed.
If you are only interested in the longest initial sequence, it's a 1-liner:
(defn longest-initial-sequence [[x :as s]]
(take-while identity (map #(#{%1} %2) s (iterate inc x))))
Taking into account the OP's comment on the question -- which completely changes the game! -- this can be written very simply:
(let [doubletons (partition 2 1 [1 2 3 5 6])
increment? (fn increment? [[x y]]
(== (inc x) y))]
(cons (ffirst doubletons)
(map second (take-while increment? doubletons))))
;; returns (1 2 3)
Note that this is actually lazy. I expect it not to hold onto the head of doubletons thanks to locals clearing. Another version:
(cons (first [1 2 3 5 6])
(map second (take-while increment? (partition 2 1 [1 2 3 5 6]))))
The original version of the question is more fun, though! :-) A super-simple solution to that could be built using the above, but of course that would be significantly less performant than using reduce. I'll see if I have anything substantially different from zmila's and dnolen's solutions -- and yet still reasonably performant -- to add to that part of this thread later. (Not very likely, I guess.)
Answer to original:
(defn conj-if-sequential
([] [])
([a] a)
([a b] (let [a (if (vector? a) a [a])]
(if (= (inc (last a)) b)
(conj a b)
a))))
(reduce conj-if-sequential [2 3 4 6 8 1])
A more generic solution for those interested:
(defn sequential-seqs
([] [])
([a] a)
([a b] (let [n (last (last a))]
(if (and n (= (inc n) b))
(update-in a [(dec (count a))] conj b)
(conj a [b])))))
(defn largest
([] nil)
([a] a)
([a b] (if (> (count b) (count a)) b a)))
(reduce largest (reduce sequential-seqs [] [2 3 4 6 8 1 4 5 6 7 8 9 13]))
I think this is much better.
(defn find-max-seq [lst]
(let [[f & r] lst,
longest-seq (fn [a b] (if (> (count a) (count b)) a b)),
[last-seq max-seq] (reduce
(fn [ [[prev-num & _ :as cur-seq] max-seq] cur-num ]
(if (== (inc prev-num) cur-num)
[(conj cur-seq cur-num) max-seq]
[(list cur-num) (longest-seq cur-seq max-seq)]
))
[(list f) ()]
r)]
(reverse (longest-seq last-seq max-seq))))
(find-max-seq '(2 3 4 6 8 1)) ; ==> (2 3 4)
(find-max-seq '(3 2 3 4 6 8 9 10 11)) ; ==> (8 9 10 11)