Instantly share code, notes, and snippets.

ericnormand/00 Unfriendly neighbors.md

Created May 3, 2022 18:08
Show Gist options
• Save ericnormand/598b0fc7aea99b628cfc7120857dc7df to your computer and use it in GitHub Desktop.

Unfriendly neighors

Let's say we have a sequence of integers:

`[1 3 2 4 1]`

There are 4 spots between numbers where we could insert a new number (represented by commas):

```[1 ,, 3 ,, 2 ,, 4 ,, 1]
;; ^    ^    ^    ^
;; |    |    |    spot 3.5, between 3 and
;; |    |    spot 2.5, between 2 and 3
;; |    spot 1.5, between 1 and 2
;; spot 0.5, between 0 and 1```

We can represent those spots as halves, such as 0.5.

We only want to insert numbers when they are "happy". Odd numbers are happy when we insert them next to at least one odd number. Even numbers are happy when we insert them next to at least one even number.

Write a function that takes a sequence of integers and an integer. It should return the happy spots and the unhappy spots.

```(spots [1 1]     1) ;=> {:happy [0.5]                   }
(spots [1 1]     2) ;=> {                 :unhappy [0.5]}
(spots [1 1 2]   4) ;=> {:happy [1.5]     :unhappy [0.5]}
(spots [1 1 2 2] 3) ;=> {:happy [0.5 1.5] :unhappy [2.5]}```

Note: Inserting a number may make pre-existing numbers unhappy. Ignore them!

Thanks to this site for the problem idea, where it is rated Very Hard in Ruby. The problem has been modified.

nbardiuk commented May 3, 2022

```(defn spots [numbers candidate]
(let [good-neighbor? (if (odd? candidate) odd? even?)
pairs (partition 2 1 numbers)
spots (range 0.5 (count numbers))]
(->> (for [[neighbors spot] (map vector pairs spots)]
(if (some good-neighbor? neighbors)
{:happy [spot]}
{:unhappy [spot]}))
(reduce (partial merge-with into)))))```

First cut, quick and dirty

```(defn happy? [c [_ pr]] (if (even? c) (some even? pr) (some odd? pr)))

(defn spots [lst cand]
(let [mi (map-indexed #(vector (+ 0.5 %1) %2) (partition 2 1 lst))
ha (mapv first (filter (partial happy? cand) mi))
uha (mapv first (remove (partial happy? cand) mi))
s1 (if (seq ha) (assoc {} :happy ha) {})]
(if (seq uha) (assoc s1 :unhappy uha) s1)))```

golfed version

```(defn spots [lst cand]
(let [happy? (fn [[_ pr]] (if (even? cand) (some even? pr) (some odd? pr)))
mi (map-indexed #(vector (+ 0.5 %1) %2) (partition 2 1 lst))]
(remove #(empty? (val %))
{:happy (mapv first (filter happy? mi))
:unhappy (mapv first (remove happy? mi))})))```

```(defn spots [xs n]
(let [m (->> (map #(even? (+ n %)) xs)
(partition 2 1)
(map #(if (some identity %) :happy :unhappy))
(map vector (iterate inc 0.5))
(group-by second))]
(update-vals m #(map first %))))```

jonasseglare commented May 4, 2022

```(defn spots [elements x]
(apply merge-with into
(for [[w f] [[:happy true] [:unhappy]]
[a b & r] (iterate rest elements)
:while b :when (= f (some #(even? (+ x %)) [a b]))]
{w [(- (count elements) (count r) 1.5)]})))```

miner commented May 5, 2022

```(defn spots [xs x]
(let [test? (if (odd? x) odd? even?)
xv (if (vector? xs) xs (into [] xs))]
(reduce (fn [m i]
(let [k (if (or (test? (xv i)) (test? (xv (inc i)))) :happy :unhappy)]
(assoc m k (conj (m k []) (+ i 0.5)))))
{}
(range (dec (count xv))))))```

JonathanHarford commented May 6, 2022

```(defn spots [neighborhood neighbor]
(->> neighborhood
(map #(even? (+ neighbor %)))
(partition 2 1)
(map-indexed (fn [i [x y]]
{(if (or x y) :happy :unhappy) [(+ 0.5 i)] }))
(apply merge-with concat)))```

Altariarite commented May 10, 2022

```(defn happy?
"odd/even: happy with at least one odd/even"
[neighbours num]
(cond
(and (even? num) (some even? neighbours)) :happy
(and (odd? num) (some odd? neighbours)) :happy
:else :unhappy))

(defn spots
"takes a sequence of integers and an integer. return the happy spots and the unhappy spots."
[seq num]
(->>
(partition 2 1 seq)
(map-indexed (fn [idx e]
{(happy? e num) [(+ 0.5 idx)]}))
(apply merge-with into)))```

KingCode commented May 26, 2022

```(defn spots [xs n]
(let [pred (if (odd? n) odd? even?)]
(->> xs (partition 2 1)
(map-indexed vector)
(reduce (fn [m [i part]]
(update m (if (some pred part)
:happy
:unhappy)
conj
(+ i 0.5)))
{:happy [] :unhappy []}))))```