Created
June 21, 2019 19:28
-
-
Save mkremins/a2ae86b0676920087dfca89eda22340d to your computer and use it in GitHub Desktop.
Smearing shuffle
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn smearfle | |
"\"Smearing shuffle\": shuffle a list while semi-preserving its original order. | |
Slide a window of size `window-size` (default 3) across the list from left to right | |
in increments of `step-size` (default 1), shuffling the contents of the window on each step. | |
The end result: some items are carried a random distance left or right of their | |
original starting point, but disruption of the list's order is largely local, | |
so it's unlikely that any given item is (for instance) carried all the way | |
from the beginning to the end of the list. | |
You can use this to add some variation to the order in which a sorted list is traversed, | |
making it useful for implementing certain types of weighted random behavior. | |
First sort by your desired weighting property, then `smearfle` the sorted list | |
to mix things up a bit while still largely preserving the overall prioritization. | |
Try it out on `(range 100)` to get a feel for how it behaves. You could probably also | |
call it `scramble` if you're the sort of person who hates fun." | |
([xs] (smearfle 3 xs)) | |
([window-size xs] (smearfle window-size 1 xs)) | |
([window-size step-size xs] | |
(loop [xs (vec xs) | |
start-pos 0] | |
(let [end-pos (+ start-pos window-size)] | |
(if (> end-pos (count xs)) | |
xs | |
(let [lefts (subvec xs 0 start-pos) | |
window (subvec xs start-pos end-pos) | |
rights (subvec xs end-pos)] | |
(recur (-> lefts (into (shuffle window)) (into rights)) | |
(+ start-pos step-size)))))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment