Trying to understand clojure Fibonacci recursion - recursion

I am trying to understand the below program to find the Fibonacci series using recursion in Clojure.
(defn fib
[x]
(loop [i '(1 0)]
(println i)
(if (= x (count i))
(reverse i)
(recur
(conj i (apply + (take 2 i))))))) // This line is not clear
For ex for a call fib(4) I get the below output,
(1 0)
(1 1 0)
(2 1 1 0)
(0 1 1 2)
Which as per my inference the conj seems to add the value of (apply + (take 2 i)) to the start of the i. But that is not the behaviour of conj. Can someone help me understand how exactly this works?

That is the behavior of conj, for lists. conj doesn't always add to the end:
(conj '(1) 2) ; '(2 1)
(conj [1] 2) ; [1 2]
The placement of the added element depends on the type of the collection. Since adding to the end of a list is expensive, conj adds to to front instead. It's the same operation (adding to a list), but optimized for the collection being used.

Per Clojure documentation:
The 'addition' may happen at different 'places' depending on the concrete type.
Appending to list happens to beginning of list, appending to vector happens to the end...
See more examples at https://clojuredocs.org/clojure.core/conj

Related

How to get the lowest integer out of a vector in Racket

I'm trying to get the lowest integer out of a vector only containing numbers. I know how to do it with lists. You compare the first two values of the list and depending on which is larger you either save your value to output it later or call the function again with the rest of the list (all elements except the first) using the cdr procedure.
But with vectors I'm completely lost. My guess would be that the way of thinking about the solution would be the same for lists and vectors. I've been reading on the racket-lang website but haven't been able to come up with a solution to the problem. The procedures I've been experimenting most with are vector-ref and vector-length as they seem to be the most useful in this problem (but this is my first time working with vectors so what do I know).
So my two questions are:
How can we get all values except the first from a vector? Is there a procedure like cdr but for vectors?
If you were working with lists you would use cons to save the values you would want to output. But is there a similar way of doing it when working with vectors?
Thanks!
The simplest solution is to use a variant of for called for/fold.
I thought there were an for/min but alas.
#lang racket
(define v (vector 11 12 13 4 15 16))
(for/fold ([m +inf.0]) ([x (in-vector v)])
(min m x))
If you like a more explicit approach:
(define (vector-min xs)
(define n (vector-length xs))
(let loop ([i 0] ; running index
[m +inf.0]) ; minimum value so far
(cond
[(= i n) ; if the end is reached
m] ; return the minimum
[else ; else
(define x (vector-ref v i)) ; get new element in vector
(loop (+ i 1) ; increment index
(min m x))]))) ; new minimum
UPDATE
(let loop ([x 1] [y 10])
(loop (+ x 1) (- y 1))
is the same as:
(let ()
(define (loop (x y)
(loop (+ x 1) (- y 1)))
(loop 1 10))
Vectors are O(1) access and indexed so it is a completely different data structure, however you have SEFI-43 which is like the SRFI-1 List library, but for vectors.
#lang racket
(require srfi/43)
(define (min-element lst)
(vector-fold min (vector-ref lst 0) lst))
(max-element #(7 8 1 2 3 4 5 12))
; ==> 1
The racket/vector module has vector-argmin for finding the minimum element of a vector (Well, the minimum after feeding the elements through a transformation function). Combine that with a function like identity from racket/function and it's trivial:
(vector-argmin identity '#(5 4 3 2 1 6))

function recursion in clojure

Im dealing with recursion in clojure, which i dont really understand.
I made a small program taked from here that tries to find the smalles number that can be divided by all the numbers from 1 to 20. This is the code i wrotte, but there must be something im missing because it does not work.
Could you give me a hand? thanks!
(defn smallest [nume index]
(while(not ( = index 0))
(do
(cond
(zero?(mod nume index))(let [dec' index] (smallest nume index))
:else (let [inc' nume] (smallest nume index))))))
EDIT:
Looks like is better loop/recur so i tried it:
(loop [nume 20
index 20]
(if (= index 0)
(println nume)
(if (zero?(mod nume index))
(recur nume (dec index))
(recur (inc nume) 20)))))
Working. If you are curious about result--> 232792560
while does not do what you think it does.
In clojure, everything (well, almost) is immutable, meaning that if index is 0, it will always be 0 in the same context. Thus looping until it is 1 makes little sense.
There are a number of ways to achieve what you are trying to do, the first, and most trivial (I think!) to newcomers, is to understand loop/recur. So for example:
(loop [counter 0]
(when (< counter 10)
(println counter)
(recur (inc counter))))
In here, counter is defined to be 0, and it never changes in the usual way. When you hit recur, you submit a new value, in this case the increment of the previous counter, into a brand new iteration starting at loop, only now counter will be bound to 1.
Edit: Notice however, that this example will always return nil. It is only used for the side effect of println. Why does it return nil? Because in the last iteration, the when clause will return nil. If you want to return something else, you should perhaps use if and specify what would you like to be returned at the last iteration.
You should read a little more about this paradigm, and perhaps do exercises like 4clojure to get a better grasp at this. Once you do, it will become MUCH simpler for you to think in this way, and the tremendous benefits of this style will begin to emerge.
Good luck!
Here's a brute force implementation testing all numbers on the condition if they can be divided by all numbers from 1 to 10 (please note (range 1 11)) in the code:
(first
(filter #(second %)
(map (fn[x] [x (every? identity
(map #(= 0 (mod x %))
(range 2 11)))])
(range 1 Integer/MAX_VALUE))))
It's output is
[2520 true]
Unfortunately, this is not a good approach for bigger numbers. With (range 1 21) it doesn't finish after few minutes of waiting on my Macbook. Let's try this:
user=> (defn gcd [a b] (if (zero? b) a (recur b (mod a b))))
#'user/gcd
user=> (reduce (fn[acc n] (if (not= 0 (mod acc n)) (* acc (/ n (gcd n acc))) acc)) 1 (range 1 11))
2520
user=> (reduce (fn[acc n] (if (not= 0 (mod acc n)) (* acc (/ n (gcd n acc))) acc)) 1 (range 1 21))
232792560

Tail recursive Clojure function for computing combinations

I have a function that, given a vector, returns all unordered combinations:
(defn combination [ps]
(loop [acc []
ps ps]
(if (= 2 (count ps))
(conj acc (apply vector ps))
(recur (apply conj acc (map #(vector (first ps) %) (rest ps)))
(rest ps)))))
This works just fine, but seems a bit convoluted to me.
Is there a more straight-forward, idiomatic way to accomplish this in Clojure? I'm happy to use a Clojure core or library function, as this is certainly part of my definition of "idiomatic". :)
Clojure has clojure.math.combinatorics which contains many convenient functions. So arguably the "idiomatic" way to do what you did in Clojure would be to import/require clojure.math.combinatorics and then simply call combinations with n = 2.
...> (comb/combinations [1 2 3 4] 2)
((1 2) (1 3) (1 4) (2 3) (2 4) (3 4))
For this to work you'll need to first add the correct dependency.
As I write this the latest version is: [org.clojure/math.combinatorics "0.0.7"]
I did then require it ":as comb":
(:require [clojure.math.combinatorics :as comb]
In case you don't want to use math.combinatorics, you can edit your question to precise it and I'll delete my answer.
Your code returns all selections of two elements taken in order. Another way to do this is ...
(defn combination [s]
(let [tails (take-while next (iterate rest s))]
(mapcat (fn [[f & rs]] (map #(vector f %) rs)) tails)))
This is shorter than yours and is lazy too. But it's likely to be slower.
Somewhat facetiously ...
(defn combination [ps]
(clojure.math.combinatorics/combinations ps 2))
... which is lazy, but the source code is two or three times as long as yours.

How to call the lazy-seq made so far within construction of a lazy-seq?

For my prime numbers lazy seq, I am checking to see if an index value is divisible by all the primes below that current index (prime?). The problem is, when I call primes within itself (primes within shr-primes line), it only returns the initial value. Is it possible to keep the lazy-seq updated while building it lazily? It seems counter-intuitive to the lazy-seq concept.
(def primes
(cons 2 (for [x (range)
:let [y (-> x (* 2) (+ 3))
root (math/floor (math/sqrt y))
shr-primes (take-while (partial >= root) primes) ;; primes stuck at init value
prime? (every? #(not= % 0) (pmap #(rem y %) shr-primes))]
:when prime?]
y)))
If you're doing the Project Euler problems, I don't want to spoil the exercise for you, but here's how you would define a Fibonacci sequence so that the lazy-seq keeps "updating" itself as it goes:
(defn fib-maker
([] (concat [0 1] (fib 0 1)))
([a b] (lazy-seq (cons b (fib b (+ a b))))))
(def fib (fib-maker))
I've used the above approach to implement the prime number sequence you've outlined above, so if you want more details let me know. Meanwhile, this will hopefully be a helpful hint.

List operations in Lisp

I have been searching everywhere for the following functionality in Lisp, and have gotten nowhere:
find the index of something in a list. example:
(index-of item InThisList)
replace something at a specific spot in a list. example:
(replace item InThisList AtThisIndex) ;i think this can be done with 'setf'?
return an item at a specific index. example:
(return InThisList ItemAtThisIndex)
Up until this point, I've been faking it with my own functions. I'm wondering if I'm just creating more work for myself.
This is how I've been faking number 1:
(defun my-index (findMe mylist)
(let ((counter 0) (found 1))
(dolist (item mylist)
(cond
((eq item findMe) ;this works because 'eq' checks place in memory,
;and as long as 'findMe' was from the original list, this will work.
(setq found nil)
(found (incf counter))))
counter))
You can use setf and nth to replace and retrieve values by index.
(let ((myList '(1 2 3 4 5 6)))
(setf (nth 4 myList) 101); <----
myList)
(1 2 3 4 101 6)
To find by index you can use the position function.
(let ((myList '(1 2 3 4 5 6)))
(setf (nth 4 myList) 101)
(list myList (position 101 myList)))
((1 2 3 4 101 6) 4)
I found these all in this index of functions.
find the index of something in a list.
In Emacs Lisp and Common Lisp, you have the position function:
> (setq numbers (list 1 2 3 4))
(1 2 3 4)
> (position 3 numbers)
2
In Scheme, here's a tail recursive implementation from DrScheme's doc:
(define list-position
(lambda (o l)
(let loop ((i 0) (l l))
(if (null? l) #f
(if (eqv? (car l) o) i
(loop (+ i 1) (cdr l)))))))
----------------------------------------------------
> (define numbers (list 1 2 3 4))
> (list-position 3 numbers)
2
>
But if you're using a list as a collection of slots to store structured data, maybe you should have a look at defstruct or even some kind of Lisp Object System like CLOS.
If you're learning Lisp, make sure you have a look at Practical Common Lisp and / or The Little Schemer.
Cheers!
Answers:
(position item sequence &key from-end (start 0) end key test test-not)
http://lispdoc.com/?q=position&search=Basic+search
(setf (elt sequence index) value)
(elt sequence index)
http://lispdoc.com/?q=elt&search=Basic+search
NOTE: elt is preferable to nth because elt works on any sequence, not just lists
Jeremy's answers should work; but that said, if you find yourself writing code like
(setf (nth i my-list) new-elt)
you're probably using the wrong datastructure. Lists are simply linked lists, so they're O(N) to access by index. You might be better off using arrays.
Or maybe you're using lists as tuples. In that case, they should be fine. But you probably want to name accessors so someone reading your code doesn't have to remember what "nth 4" is supposed to mean. Something like
(defun my-attr (list)
(nth 4 list))
(defun (setf my-attr) (new list)
(setf (nth 4 list) new))
+2 for "Practical Common Lisp". It is a mixture of a Common Lisp Cookbook and a quality Teach Yourself Lisp book.
There's also "Successful Common Lisp" (http://www.psg.com/~dlamkins/sl/cover.html and http://www.psg.com/~dlamkins/sl/contents.html) which seemed to fill a few gaps / extend things in "Practical Common Lisp".
I've also read Paul Graham's "ANSI Common Lisp" which is more about the basics of the language, but a bit more of a reference manual.
I have to agree with Thomas. If you use lists like arrays then that's just going to be slow (and possibly awkward). So you should either use arrays or stick with the functions you've written but move them "up" in a way so that you can easily replace the slow lists with arrays later.

Resources