August 20, 2018
Just Juxt #6: Rotate a Sequence (4clojure #44)
Write a function which can rotate a sequence in either direction.
This problem is particularly significant, because it's the one that inspired this blog on the most recent Apropos show!
Here's a live testing area for you to play with. See if you can solve it with juxt
. Then check out the answer below!
(ns live.test
(:require [cljs.test :refer-macros [deftest is testing run-tests]]))
(defn rotate [n s]
)
(deftest test-44
(is (= (rotate 2 [1 2 3 4 5]) '(3 4 5 1 2)))
(is (= (rotate -2 [1 2 3 4 5]) '(4 5 1 2 3)))
(is (= (rotate 6 [1 2 3 4 5]) '(2 3 4 5 1)))
(is (= (rotate 1 '(:a :b :c)) '(:b :c :a)))
(is (= (rotate -4 '(:a :b :c)) '(:c :a :b))))
(run-tests)
First, a common answer:
(defn rotate [n s]
(take (count s) (drop (mod n (count s)) (cycle s))))
(run-tests)
Now the juxt
-ification - solution courtesy of hypirion:
(defn rotate [n s]
(apply concat ((juxt drop take) (mod n (count s)) s)))
(run-tests)
Here we are juxt
-ing with drop
and take
. Let's plug in our first test case:
(apply concat ((juxt drop take) (mod 2 (count [1 2 3 4 5])) [1 2 3 4 5]))
Here's just the call to drop
:
(drop (mod 2 (count [1 2 3 4 5])) [1 2 3 4 5])
And to take
:
(take (mod 2 (count [1 2 3 4 5])) [1 2 3 4 5])
Which results in this vector when juxt
ed:
((juxt drop take) (mod 2 (count [1 2 3 4 5])) [1 2 3 4 5])
And then we stick them together:
(apply concat ['(3 4 5) '(1 2)])
I hope you enjoyed today's juxt
. See you tomorrow!