stuck in recursion of clojure - missing a bracket - recursion

I am writing a clojure recursion function so that given:
(luty [1 2 3 4])
should have output like this:
((1 2 3 4) (2 3 4) (3 4) (4) ()
My code is:
(defn luty [a1]
(if (empty? a1)
(list )
(cons (seq a1) (luty (rest a1) )
)))
I am getting output:
((1 2 3 4) (2 3 4) (3 4) (4)) //comment missing a ()
Can anybody suggest me where I am getting wrong?

If we print out the process and look at the second to last opperation:
user> (defn luty [a1]
(println "a1 is" a1)
(if (empty? a1)
()
(cons (seq a1) (luty (rest a1)))))
#'user/luty
user> (luty [1 2 3 4])
a1 is [1 2 3 4]
a1 is (2 3 4)
a1 is (3 4)
a1 is (4)
a1 is ()
((1 2 3 4) (2 3 4) (3 4) (4))
user> (cons '(4) ())
((4))
We can see that the result of adding (4) to the empty list is ((4)) rather than ((4) ()) as you would most likely want. This can be fixed by making the base case a list containing the empty list, instead of just an empty list
user> (defn luty [a1]
(if (empty? a1)
'(())
(cons (seq a1) (luty (rest a1)))))
#'user/luty
user> (luty [1 2 3 4])
((1 2 3 4) (2 3 4) (3 4) (4) ())

The return value of cons is a list with as the first element the first argument and the rest of the list as the second argument. If the second argument is empty or nil, that means you get a list with the first argument as the single member.
The reason for this is that lists are (conceptually, at least, in clojure) linked lists with 2-space cells; one pointer for the head element and one pointer for the tail (another list, which in clojure is guaranteed to be a seq-like thing - in many other lisps you can set the second pointer to any value you want, so you're not guaranteed to get a "proper" list out of a cons there). A nil in the "tail" position marks the end of the list.
Lists are the most easily implemented and understandable persistent (in the clojure sense of immutable, structure-sharing) data structure.

Just to give you a different way of looking at it:
user> (defn luty [a1]
(reductions (fn [c _] (rest c)) (or (seq a1) '()) (-> a1 count range)))
=> #'user/luty
user> (luty [1 2 3 4])
=> ((1 2 3 4) (2 3 4) (3 4) (4) ())
user> (luty [])
=> (())
user> (luty nil)
=> (())

Related

Clojure - blend of "get" and "nth"?

I am struggling to find a function that will find a happy-medium between the get function and nth. I have been doing a lot of research on these sequence type functions, does anyone know a work around for this or know a function that performs as such?
I need nth's ability to grab sublists:
=> (nth '(1 (2 3) 4 5) 1)
(2 3)
=> (get 1 '(1 (2 3) 4 5))
nil
And I need get's ability to return "nil" when out of range:
=> (get -1 '(1 (2 3) 4 5))
nil
=> (nth '(1 (2 3) 4 5) -1)
Execution error (IndexOutOfBoundsException) at user/eval149 (REPL:1).
null
I need this code for a recursive sub-seq function:
(defn sub-seq [coll i j]
(nth coll i)
(if (< i (+ i j))
(sub-seq coll (inc' i) j)
)
)
(The sub-seq function is supposed to return 'j' elements starting at position 'i'.)
Here are some sample outputs for what I am trying to write:
=> (sub-seq '(1 2 (3 4) (5 (6 7))) 1 2))
(2 (3 4))
=> (sub-seq '(1 2 3 4 5 6 7) 2 4)
(3 4 5 6)
I finally got my function to work, thank you all for your help:
(defn sub-seq [coll i j]
(conj
(list*
(nth coll i nil)
(if (> j 1)
(sub-seq coll (+ i 1) (- j 1))))))
nth takes an optional third argument not-found. You can use it to provide a default value if your index is out of bounds:
user=> (nth '(1 (2 3) 4 5) -1)
Execution error (IndexOutOfBoundsException) at user/eval1 (REPL:1).
null
user=> (nth '(1 (2 3) 4 5) -1 nil)
nil
If you had a vector, you could use subvec directly:
(let [s [1 2 3 4 5 6 7]]
(subvec s 2 6))
If you have a sequence then you could write:
(defn subsequence [coll start n]
(->> coll
(drop start)
(take n)))
(subsequence '(1 2 (3 4) (5 (6 7))) 1 2)
=> (2 (3 4))
(subsequence '(1 2 3 4 5 6 7) 2 4)
=> (3 4 5 6)
Side note: When writing a Clojure program, often you can solve your problem more simply with sequence processing. Sometimes recursive algorithms are necessary, but often you can get by with Clojure's rich set of functions that operate on sequences.
You are misunderstanding get. It works on associative collections like maps and vectors. Consider:
(ns tst.demo.core
(:use tupelo.core tupelo.test))
(dotest
(let [data-list '(1 (2 3) 4 5)
data-vec (vec data-list) ]
(spyx (nth data-list 1))
(spyx (nth data-vec 1))
(spyx (get data-list 1))
(spyx (get data-vec 1))
))
with result
(nth data-list 1) => (2 3)
(nth data-vec 1) => (2 3)
(get data-list 1) => nil
(get data-vec 1) => (2 3)
Since a Clojure list is not associative like a map, list should not be used at all with lists. Ideally, get would throw an exception when passed a list argument to indicate it doesn't work with them.
For your specific goal, maybe just do something like:
(take j
(drop i coll))
For additional documentation please review here.

How do I filter out the first occurrence from a list in Racket using plai-typed? [duplicate]

This question already has answers here:
Delete element from List in Scheme
(3 answers)
Closed 5 years ago.
In Racket using plai-typed, I am trying to find an element in a list and remove the first one it finds. It will then return the list with the first element it sees removed.
Here is an example:
'(1 2 3 2 5)
Filter out the first 2 and you should get:
'(1 3 2 5)
This is what I am currently doing, but it returns: '(1 3 5)
(filter (lambda (x) (not (equal? x 2))) '(1 2 3 2 5))
So what I am currently doing removes all the occurrences when I just want to remove the first one.
[edit]If you did not want to use that built in function you can do
(define (remove-1st-helper l n)
(cond [(empty? l) empty]
[(= 1 n) l]
[(= 2 (first l)) (remove-1st-helper (rest l)(add1 n))]
[else (cons (first l) (remove-1st-helper (rest l) n))]))
(define (remove-1st-occurence l)
(if (empty? l) empty (remove-1st-helper l 0)))
Don't know Racket, but maybe you can define it as a piece-wise function like this:
-- Define myFilter of an empty list to be empty
myFilter [] = []
-- Decomposes list into first element and rest of list
myFilter (x:xs)
-- Ignore `x` but include the rest of the list
| x == 2 = xs
-- Include x and apply myFilter on xs
| otherwise = x:(myFilter xs)
(Haskell code).

Delete occurences of item from non-linear list

I am trying to delete all occurrences of an element from a list, from any levels of the list. I am required to use a map function though. I am using Common Lisp. For example I'd want to be able to do:
(fdelete '(1 2 3 4 (3)) 3) => (1 2 4)
What I've tried so far:
This function will do what's needed, sort of. It will replace all occurences of the given element with NIL, so it's not exactly what I want.
(defun fdelete (l e)
(cond
((null l) 0)
((equal l e) nil)
((atom l) l)
(t (mapcar (lambda(l) (fdelete l e )) l ))
)
)
This will do
(fdelete '(1 2 3 4 (3)) 3) => (1 2 NIL 4 (NIL))
My second try is with the mapcap function, since this one won't return a list the same size as the input list.
This will do what's needed, but it will 'destroy' my initial list, as in, it will bring all sublists 'to surface'.
(defun fdelete (l e)
(cond
((null l) 0)
((equal l e) nil)
((atom l) (list l))
(t(mapcan(lambda(x) (fdelete x e ))l ))
)
)
So this indeed does (fdelete '(1 2 3 4 (3)) 3) => (1 2 4)
but it will also do it wrong if I for example try this:
(fdelete '(1 2 3 (4) (3)) 3)) => (1 2 4)
I'd want it to do (fdelete '(1 2 3 (4) (3)) 3)) => (1 2 (4))
I hope my question is well formed and detailed enough, and I am providing working examples. Can someone give me a few hints on how to solve this problem?
Using mapcan is the correct choice since you can wrap in list to get a value or use nil to get item removed. For the list element, if it doesn't already match what to delete, you should check the result of the recursion and wrap it if it's not the empty list.
The solution would look something like:
(defun remove-deep (item list)
(mapcan (lambda (cur)
(cond ((equal item cur) '())
...))
list))
(remove-deep 3 '(1 nil 2 3 (3) (3 4)))
; ==> (1 nil 2 (4))
To apply the principle of least surprise I have renamed the function since delete is the destructive version of remove. Also I kept the argument order of the standard functions:

Process n items from a list at a time in Lisp

Given a list, how do I process N items at a time? Ruby has each_slice method on the Enumerable that does this; what would be the Lisp equivalent?
Common Lisp's loop can be used for this very nicely, as in the following two examples. The first example loops for (x y z) in a list. However, the default step is cdr (rest), so if the list is (1 2 3 4 5), you get (1 2 3), (2 3 4), etc., for (x y z).
CL-USER> (loop for (x y z) on '(1 2 3 4 5 6 7 8 9 10 11 12)
do (print (list z y x)))
(3 2 1)
(4 3 2)
(5 4 3)
(6 5 4)
(7 6 5)
(8 7 6)
(9 8 7)
(10 9 8)
(11 10 9)
(12 11 10)
(NIL 12 11)
(NIL NIL 12)
NIL
If you do not want the overlap between iterations, specify the stepping function to be something that moves farther down the list. For instance, if you're pulling three elements at a time, use cdddr:
CL-USER> (loop for (x y z) on '(1 2 3 4 5 6 7 8 9 10 11 12) by 'cdddr
do (print (list z y x)))
(3 2 1)
(6 5 4)
(9 8 7)
(12 11 10)
NIL
Implementing partition with this technique
Another answer implemented the counterpart to each_slice using an auxiliary function. However, notice that partition (in that sense) is just each_slice with the identity function. This suggests that we should be able to implement it using the idiom above. The anonymous function
(lambda (list)
(nthcdr n list))
is the step function that we need. Since we do not know how many elements the cells have until run time, we can't bind each element like we did above with (x y z). We do have to match each tail of the list as we step down and extract the subsequence n elements. Here's a loop based implementation of partition.
CL-USER> (defun partition (list cell-size)
(loop for cell on list by #'(lambda (list)
(nthcdr cell-size list))
collecting (subseq cell 0 cell-size)))
PARTITION
CL-USER> (partition '(1 2 3 4 5 6) 2)
((1 2) (3 4) (5 6))
(defun partition-helper (lst acc x)
(if (< (length lst) x)
acc
(partition-helper (subseq lst x) (cons (subseq lst 0 x) acc) x)))
(defun partition (lst x)
(reverse (partition-helper lst '() x)))
Then you can:
[25]> (PARTITION '(1 2 3 4 5 6) 2)
((1 2) (3 4) (5 6))
or:
[26]> (PARTITION '(1 2 3 4 5 6) 3)
((1 2 3) (4 5 6))
and then just mapcar over the list to process it 2 or 3 elements at a time.
If you wanted to split your list on a predicate (as opposed to a fixed length sublists), I would have recommended nsplit-list.
For fixed length sublists, you may want to use loop:
(defun by-N (list n fun)
(loop for tail on list by (lambda (l) (nthcdr n l))
do (funcall fun (subseq tail 0 (min (length tail) n)))))
(by-n (loop for i from 0 to 20 collect i) 5 #'print)
(0 1 2 3 4)
(5 6 7 8 9)
(10 11 12 13 14)
(15 16 17 18 19)
(20)
Note that this is not very efficient (it scans the list more than necessary and allocates a fresh sublist for passing to fun).
The efficient version is more complicated:
(defun batch-map (list batch-size function)
"Call FUNCTION on sublists of LIST of size BATCH-SIZE.
Returns the list of return values of FUNCTION."
(do ((tail list (cdr end)) end ret (bs1 (1- batch-size)))
((endp tail) (nreverse ret))
(setq end (nthcdr bs1 tail))
(if (consp end)
(let ((next (cdr end)))
(setf (cdr end) nil)
(unwind-protect (push (funcall function tail) ret)
(setf (cdr end) next)))
(push (funcall function tail) ret))))
All the answers are practical and can be used, but I believe none replicates exactly the Ruby's behavior:
> 1.upto(7).each_slice(3) { |x, y, z| p [x, y, z] }
[1, 2, 3]
[4, 5, 6]
[7, nil, nil]
To emulate Ruby, I believe the proper code is something similar to:
CL-USER> (defun each-slice (n list thunk)
(apply thunk (loop for i below n collect (nth i list)))
(if (> (length list) n)
(each-slice n (subseq list n) thunk)))
Generates a similar response when called:
CL-USER> (each-slice 3 '(1 2 3 4 5 6 7) (lambda (x y z) (print (list x y z))))
(1 2 3)
(4 5 6)
(7 NIL NIL)
NIL

Recursive lazy seq in Clojure

I can't understand why this lazy-seq causes a stackoverflow, and why not when you pass the sequence to dorun:
(defn very-lazy [s]
(lazy-seq
(if (seq s)
[(first s) (very-lazy (rest s))]
[])))
(dorun (very-lazy (range 200000000)))
>nil
(take 2 (very-lazy (range 20000000))
>...(1577 (java.lang.StackOverflowError
If it's lazy then take 2 should cause the lazy seq to iterate only two times, why doesn't happen and why dorun works?
In your example function returns lazyseq (0 (1 (2 (3 (...))))). That's why dorun runs without stackoverflow (there is sequence of two elements 0 and (1 (2 (...))) that dorun doesn't evaluate) and second fails (it returns infinite nested sequences that repl tries evaluate to print out).
I guess you're looking for this solution
(defn very-lazy [s]
(lazy-seq
(if (seq s)
(cons (first s) (very-lazy (rest s)))
[])))
(take 10 (very-lazy (range 200000000)))
-> (0 1 2 3 4 5 6 7 8 9)

Resources