Fork me on GitHub
#clojure
<
2021-09-19
>
ericdallo02:09:30

Hello! kind of noob question: I need a function that should receive a vector of sequential int numbers and map to another vector that will have `1` s if the number changed comparing with previous element and `0` if not. example:

``````(is (= [0 0 0 1 0 1 0 0 0 1 0 0]
(foo [0 0 0 1 1 2 2 2 2 3 3 3]))) ``````
I managed to find a solution, but it doesn't looks that easy/fast 😅 Does anyone knows if there is a better/simpler way?

ericdallo02:09:55

my solution:

``````(defn foo [input]
(->> input
(map-indexed (fn [i e]
(if-let [prev-e (nth input (dec i) nil)]
(if (= e prev-e)
(loop [j (->> i dec dec)]
(if-let [other-e (nth input j nil)]
(if (= other-e prev-e)
(recur (dec j))
0)
0))
1)
e)))
vec))``````

andrewhr02:09:06

I'm not sure how to proper deal with the special case of the first value, but something like that is helpful to you?

``````(defn foo [input]
(->> (cons (first input) input)
(partition 2 1)
(mapv (fn [[prev curr]]
(if (= prev curr) 0 1)))))``````
EDIT: hack to force a pair of the first item, so [] produces []

R.A. Porter02:09:04

Here are a couple of meh solutions...

``````(defn foo [c]
(reduce-kv (fn [a k v]
(cond
(= k 0) 
(= (nth c (dec k)) v) (conj a 0)
:else (conj a 1)))
[]
c))``````
and
``````(defn foo [c]
(->> (reduce (fn [{:keys [acc prev]} v]
(if (= v prev)
{:acc (conj acc 0) :prev v}
{:acc (conj acc 1) :prev v}))
{:acc [] :prev (first c)}
c)
:acc))``````

``````(defn problem
[nums]
(mapv #(= (nth nums %) (nth nums (dec %)))
(range 1 (count nums))))``````
returns booleans for all adjacent pairs

phronmophobic02:09:04

For comparing consecutive elements, I like using `map` 's extra args `(map my-compare xs (next xs))` here's an implementation of foo:

``````(defn foo [xs]
(->> (map not= xs (next xs))
(map {true 1
false 0})
(cons 0)))``````

💯 8
ericdallo02:09:31

Damm, I didn't know about that extra map arg, thank you so much all! I'll later replace mine with which the one that fits better for my case Ben Sless06:09:49

A bit from a mathematical angle, this is a discrete derivative of the sequence Practically, you can map (comp abs compare) on the signal + shifted signal

2
noisesmith18:09:59

it's basically @U7RJTCH6J’s solution

``````(cmd)user=> (let [signal [0 0 0 1 1 2 2 2 2 3 3 3] shifted-signal (rest signal)]
(map (comp #(Math/abs %) compare) signal shifted-signal))
(0 0 1 0 1 0 0 0 1 0 0)``````

🎉 2
noisesmith18:09:25

which is missing a leading 0

Benjamin12:09:58

jira + clojure: do you have any opinions what a good way to interact with jira is ? (use case is creating tickes atm)

GGfpc12:09:31

Hi! I have a question: 1. Is there a way to fully describe a nested spec? When I describe a spec it stops at the top level, is there a method that describes recursively or something?

GGfpc12:09:57

Also, is Schema still used these days? It seems much better in terms of actually describing what the data will look like

borkdude12:09:56

@ggfpc12495 Schema is still very much alive and used, although you don't hear about it a lot in the "news"

borkdude12:09:13

Malli (#malli) has a similar way of representing specifications as data, if you are into that.

GGfpc12:09:20

Yeah, I've been looking into malli in the last few minutes, I'll take a look

GGfpc21:09:05

Are there any widely used code analysis tools like Sonarqube for clojure?

Alex Miller (Clojure team)21:09:58

there are sonar plugins for Clojure that use things like clj-kondo and I think also nvd-checker type stuff

lvh23:09:05

Is there a way to use expresso to solve a set of simultaneous equations where it's smart enough not to use superfluous equations that reintroduce unknowns? Example mortgage payment calculator:

``````(def mortgage-equations
[(x/ex (= monthly-rate (/ rate 12)))
(x/ex (= number-of-payments (* years 12)))
(x/ex (= interest-factor (** (+ 1 monthly-rate) number-of-payments)))
(x/ex (= total-payment (* principal interest-factor)))
;; If I add these two superfluous equations I get a result with unknowns in
;; it; if I remove them, I get the number I want
(x/ex (= monthly-pi (/ total-payment number-of-payments)))
(x/ex (= monthly-piti (+ monthly-pi monthly-property-tax monthly-insurance)))])

(apply x/solve 'total-payment
(x/ex (= rate 235E-4))
(x/ex (= years 30))
(x/ex (= principal 1E6))
mortgage-equations)

;; => #{{total-payment (* -360N (+ monthly-property-tax monthly-insurance (- monthly-piti)))}}
;; was expecting a number``````
I'm sure there's an answer involving reordering but that seems brittle 🙂

Maravedis06:09:09

Please try to encapsulate code in tripled backticks or use `shift + ctrl + alt + c` to insert a code block. It's more readable that way 🙂 https://slack.com/intl/en-fr/help/articles/202288908-Format-your-messages