Reputation: 33
I am new to clojure I am trying to find whether a vector in clojure has consecutive elements: in python its simple using numpy
(np.diff(np.sort(np.array(numbers))))
But I am lost trying to find similar methods: My strategy was to
for example
(def x `(5 7 3 6 4))
Output would be (1 1 1 1)
I am confused how to work on this.
Upvotes: 0
Views: 629
Reputation: 70239
Clojure has a built-in dedupe function so an easy (but not particularly fast) answer is to dedupe and compare equals.
(defn consecutive?
[coll]
(not= coll (dedupe coll)))
(consecutive? [1 2 2 3]) ;; true
(consecutive? [1 2 3]) ;; false
Upvotes: 1
Reputation: 106401
Try something like this:
(defn diff [vals]
(map - (next vals) vals))
This returns a list of differences between each pair of consecutive elements are equal. It works because next
simply offsets the sequence of values by one element.
Example usage:
(diff [1 2 2 3])
=> (1 0 1)
To test whether consecutive numbers exist, you simply need to check for the presence of the value 1
in this list.
Upvotes: 5
Reputation: 29984
Please see this list of documentation, especially the Clojure CheatSheet. You are looking for the function partition
. You can use it like this:
(ns tst.demo.core
(:use tupelo.test))
(defn pair-delta
[pair]
(let [[a b] pair]
(- b a)))
(defn consectives?
[v]
(let [pairs (partition 2 1 (sort v))
deltas (mapv pair-delta pairs)
result (= #{1} (set deltas))]
result))
(dotest
(let [pos [1 2 3 6 5 4]
neg [1 2 3 6 5 ]]
(is= true (consectives? pos))
(is= false (consectives? neg))))
The template project shows how I like to set up a project, and includes my favorite helper functions.
Upvotes: -1
Reputation: 10865
Following your idea of getting the differences, after sorting you can use partition to get all the consecutive pairs and than use map to get all the differences. (Here it seemed more natural to get the reverse of the numpy diff, so the check is that every element is -1
instead of 1
.)
(defn contains-consecutive? [xs]
(let [sorted (sort xs)
differences (map #(apply - %) (partition 2 1 sorted))]
(every? #(= -1 %) differences)))
user> (contains-consecutive? [])
true
user> (contains-consecutive? [1])
true
user> (contains-consecutive? [1 3 2])
true
user> (contains-consecutive? [1 3 4])
false
user> (contains-consecutive? '(5 7 3 6 4))
true
Upvotes: 1