How to get a sublist in a list in clojure - clojure

I am wondering get a sublist in a list,like:
user=> (findsublst '(hello world (10 clock)))
(10 clock)
what function can I use or how to define the functioin findsublst. Thank you so much!

With very little to go on, the following will return all first level list/sequences contained by the primary:
(filter seq? '(1 2 3 (4 5 6)))
=> ((4 5 6))

Related

LISP How to remove element at certain index from a list

I'm trying to learn LISP. I got my way around functions and I wanted to test myself with some.
I was trying to write a function that can remove an element from a list in a given index.
This seems pretty straightforward, but I can't manage to do it.
Example: I have the list (20 8 13 10) and I want to remove the number at index 2.
How would I go about something like this?
It's very easy. This is the base case:
(remove-nth 0 '(2 3)) ; => (3)
And the default case:
(remove-nth 1 '(1 2 3)) ; ==
(cons 1 (remove-nth 0 '(2 3)))
The only thing left for you to do is to actually implement it!
There is a third case. What if the list is nil? In the strictest sense you cannot do the job and you should signal an error or perhaps there isn't anything to do so it's ok to then have it as a base case that evaluates to '() so that (remove-nth 5 '(1 2)) ; ==> (1 2)

How to print each item of list in separate line clojure?

I'm very new in clojure. I want to print each item of list in newline. I'm trying like this:
user=> (def my-list '(1 2 3 4 5 ))
;; #'user/my-list
user=> my-list
;; (1 2 3 4 5)
user=> (apply println my-list)
;; 1 2 3 4 5
;; nil
But I want my output must be:
1
2
3
4
5
nil
can anyone tell me, How can I do this? Thanks.
If you already have a function that you would like to apply to every item in a single sequence, you can use run! instead of doseq for greater concision:
(run! println [1 2 3 4 5])
;; 1
;; 2
;; 3
;; 4
;; 5
;;=> nil
doseq is useful when the action you want to perform is more complicated than just applying a single function to items in a single sequence, but here run! works just fine.
This kind of use case (perform a side effect once for each member of a sequence) is the purpose of doseq. Using it here would be like
(doseq [item my-list]
(println item))
Note that this will not print nil but will return it. Working with it in the REPL will see the return values of all expressions printed, but doesn't happen in e.g. starting your project as a terminal program.
Another strategy would be to build a string from the list that you want to print and then just print the string.
user> (defn unlines [coll]
(clojure.string/join \newline coll))
#'user/unlines
user> (unlines [1 2 3 4 5])
"1\n2\n3\n4\n5"
user> (println (unlines [1 2 3 4 5]))
1
2
3
4
5
nil

How to apply a function to a sequence multiple times

I am working on some Lisp exercises using Clojure. I am trying to work these exercises without taking advantage of vectors and some Clojure functions.
This function
(defn rev-seq
[s1]
(concat (pop s1) (list (peek s1))))
puts the first element of a list at the end. I want to call this function as many times as it takes to reverse the list (without calling Clojure's reverse function).
I am not sure what to use in its place. I have experimented with map, apply, and repeat with no success. I would rather have a way to think differently about this than a straight answer, but I am not asking for a discussion.
Firstly, I think you'll need to convert rev-seq to use first/rest rather than peek/pop if you want to work on general sequences - at leas in Clojure 1.4 peek/pop seems to require a PersistentStack:
(defn rev-seq
[s1]
(concat (rest s1) (list (first s1))))
Then you should probably note that applying this function repeatedly will "cycle" a list rather than reversing it. You can see that if you look at the result of a small number of applications using iterate:
(def s '(1 2 3 4 5 6 7 8 9))
(nth (iterate rev-seq s) 3)
=> (4 5 6 7 8 9 1 2 3)
An option that would work is to reverse with a recursive function:
(defn reverse-seq [s]
(concat (reverse (next s)) (list (first s))))
(reverse-seq s)
=> (9 8 7 6 5 4 3 2 1)
Or alternatively you can do a reverse using the technique in clojure.core:
(defn reverse-seq [s]
(reduce conj () s))
(reverse-seq s)
=> (9 8 7 6 5 4 3 2 1)
Hope this gives you some ideas!
Recursion is powerful!
I translated
the solution
into Clojure.
(defn- inverte-aux
[lista resto]
(if lista
(recur (next lista) (cons (first lista) resto))
resto))
(defn inverte
[lista]
(inverte-aux lista nil))
user> (inverte [4 3 2 1 3])
(3 1 2 3 4)

Idiomatically iterating over a 2 (or higher) dimensional sequence in Clojure

Is there a 'proper' way to iterate over a two-dimensional sequence in Clojure?
Suppose I had a list of lists of numbers, like this
((1 2 3)
(4 5 6)
(7 8 9))
and I wanted to generate a new list of lists with each number incremented by one. Is there an easy way to do this in Clojure without relying on nested maps or loop/recurs? I've been able to do it, but my solutions are ugly and I find them difficult to understand when I re-read them.
Thanks
What you describe is precisely what clojure.walk is for:
(def matrix [[1 2 3]
[4 5 6]
[7 8 9]])
(use 'clojure.walk :only [prewalk])
(prewalk #(if (number? %) (inc %) %) matrix)
=> [[2 3 4] [5 6 7] [8 9 10]]
Note 1: it is idiomatic to use vectors instead of parentheses for literal sequential collections.
Note 2: walk preserves type.
You can always just use a list comprehension. I find myself using them quite often coming from an imperative background so I don't know how idiomatic it is. In your specific case, you can do:
(for [my-list my-matrix] (map inc my-list))
For the two-dimensional case, you could do something like:
(map #(map inc %) my-two-d-list)
That's not too bad to read: apply the function #(map inc %) to each element in a list.
For the higher-order case, you're basically talking about tree-traversal. You'd want a function that takes in a tree and a function, and applies that function to each node in the tree. You can find functions for this in clojure.walk.
The other answers by Sean and Matt both show concise and effective ways of getting the right result.
However there are some important extensions you can make to this:
It would be nice to handle the case of higher dimensions
It is good to wrap the functionality in a higher order function
Example code:
;; general higher order function
(defn map-dimensions [n f coll]
(if (= n 1)
(map f coll)
(map #(map-dimensions (dec n) f %) coll)))
;; use partial application to specialise to 2 dimensions
(def map-2d (partial map-dimensions 2))
(map-2d inc
'((1 2 3)
(4 5 6)
(7 8 9)))
=> ((2 3 4) (5 6 7) (8 9 10))
Since the introduction of core.matrix in 2013, this is now a much better way of handling operations over multi-dimensional arrays:
(use 'clojure.core.matrix)
(def M [[1 2 3]
[4 5 6]
[7 8 9]])
(emap inc M)
=> [[2 3 4 ]
[5 6 7 ]
[8 9 10]]
Advantages of using core.matrix:
Clean, idiomatic Clojure code
Lots of general purpose n-dimensional array manipulation functions - transpose, shape, reshape, slice, subarray etc.
Ability to plug in high performance array implementations (e.g. for big numerical arrays)
A belated answer, and maybe not exactly what is needed: you could try flatten. It will return a seq that you can iterate over:
(flatten '((1 2 3)
(4 5 6)
(7 8 9)))
user=> (1 2 3 4 5 6 7 8 9)
And in order to increment matrix elements and reassemble the matrix:
(partition 3 (map inc (flatten '((1 2 3)
(4 5 6)
(7 8 9)))))

sequence of a rolling average in Clojure

I'm looking for an elegant way to generate a sequence of the rolling average of a sequence of numbers. Hopefully something more elegant than using lazy-seq
Without any consideration of efficiency:
(defn average [lst] (/ (reduce + lst) (count lst)))
(defn moving-average [window lst] (map average (partition window 1 lst)))
user> (moving-average 5 '(1 2 3 4 5 6 7 8))
(3 4 5 6)
If you need it to be fast, there are some fairly obvious improvements to be made!
But it will get less elegant.
There's a very similar question on SO: Calculating the Moving Average of a List. It's more general -- a number of FP-friendly languages are represented, with the accepted answer using Scala -- but there are a few nice Clojure solutions.
I've posted my own solution over there. Note that it does use lazy-seq, but that's because I wanted it to perform well for large periods (which means adjusting the average at each step rather than calculating a separate average for each window of size = period into the input list). Look around that Q for nice solutions which made the other tradeoff, resulting in shorter code with a somewhat more declarative feel, which actually performs better for very short periods (although suffers significant slowdowns for longer periods, as is to be expected).
This version is a bit faster, especially for long windows, since it keeps a rolling sum and avoids repeatedly adding the same things.
Because of the lazy-seq, it's also perfectly general and won't blow stack
(defn partialsums [start lst]
(lazy-seq
(if-let [lst (seq lst)]
(cons start (partialsums (+ start (first lst)) (rest lst)))
(list start))))
(defn sliding-window-moving-average [window lst]
(map #(/ % window)
(let [start (apply + (take window lst))
diffseq (map - (drop window lst) lst)]
(partialsums start diffseq))))
;; To help see what it's doing:
(sliding-window-moving-average 5 '(1 2 3 4 5 6 7 8 9 10 11))
start = (+ 1 2 3 4 5) = 15
diffseq = - (6 7 8 9 10 11)
(1 2 3 4 5 6 7 8 9 10 11)
= (5 5 5 5 5 5)
(partialsums 15 '(5 5 5 5 5 5) ) = (15 20 25 30 35 40 45)
(map #(/ % 5) (20 25 30 35 40 45)) = (3 4 5 6 7 8 9)
;; Example
(take 20 (sliding-window-moving-average 5 (iterate inc 0)))
Instead of the partialsums fn (which is helpful to see what's going on), you can use reductions in clojure.core:
(defn sliding-window-moving-average [window lst]
(map #(/ % window)
(let [start (apply + (take window lst))
diffseq (map - (drop window lst) lst)]
(reductions + start diffseq))))