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/
I enjoyed this challenge because it confronts you with the seemly obvious need to keep state while processing the collection. At least for me, an imperative solution seems so straight forward in my mind.
In this gist, I've seems several approaches to overcoming the problem e.g. loop, reduce, stateful transducer, recursion and some other clever ones that I struggle to understand.
I spend an embarrassing amount of time implementing two recursive solutions before settling on a straight forward brute force attempt that keeps state in a map.
I find it... practical!?
-----edit------
@miner you are correct. :-)
I adjusted my solution. I think my solution is less elegant but close to @burnall 's solution.