Skip to content

Instantly share code, notes, and snippets.

@ericnormand
Created April 5, 2021 19:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ericnormand/098143e8cdbecef0faeba92f730b9cba to your computer and use it in GitHub Desktop.
Save ericnormand/098143e8cdbecef0faeba92f730b9cba to your computer and use it in GitHub Desktop.
421 PurelyFunctional.tv Newsletter

Element promotion

Sometimes you have a list and you want to "promote" one element toward the front of the list. Essentially, you need to swap the element with its immediate predecessor (if it exists). Write a function promote that takes a predicate and a list. If the predicate is true, the element should be promoted.

Examples

(promote even? [1 3 5 6]) ;=> (1 3 6 5)
(promote even? []) ;=> ()
(promote even? [2 1]) ;=> (2 1)
(promote even? [0 2 4 6]) ;=> (0 2 4 6)
(promote even? [0 1 2 3 4 5 6]) ;=> (0 2 1 4 3 6 5)
(promote even? [1 2 2 2 2]) ;=> (2 2 2 2 1)

Thanks to Enzzo Cavallo for the challenge idea!

Please submit your solutions as comments on this gist.

To subscribe: https://purelyfunctional.tv/newsletter/

@KingCode
Copy link

KingCode commented Jun 12, 2021

(defn promote [pred xs]
  (->>
   (loop [[hd nxt & more :as all] xs acc []]
     (cond 
       (empty? all)
       acc 
       (= 1 (count all))
       (conj acc hd) 
       (or (pred hd) (not (pred nxt)))
       (recur (cons nxt more) (conj acc hd))
       :else 
       (recur (cons hd more) (conj acc nxt))))
   (apply list)))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment