Skip to content

Instantly share code, notes, and snippets.

@mkremins
mkremins / smearfle.cljc
Created June 21, 2019 19:28
Smearing shuffle
(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,
@mkremins
mkremins / complete.elm
Created September 29, 2015 17:19
Text completions with match highlighting
import Debug
import List
import String
type alias Match = {full: String, before: String, match: String, after: String}
score : Match -> Int
score {before} = String.length before
match : String -> String -> Maybe Match
@mkremins
mkremins / let_log.clj
Created September 9, 2015 16:27
Like clojure.core/let, but logs the value of every bound symbol
(defn indent [n s]
(let [spaces (clojure.string/join (repeat n " "))]
(->> (clojure.string/split-lines s)
(map (partial str spaces))
(clojure.string/join "\n"))))
(defn bound-syms [pat]
(condp #(%1 %2) pat
(some-fn map? vector?) (distinct (mapcat bound-syms pat))
symbol? [pat]
@mkremins
mkremins / parse_arglist.clj
Created September 4, 2015 03:14
Parse arglists for fn-like forms
(def valid-name?
"Returns truthy if argument is a non-namespaced symbol."
(every-pred symbol? (complement namespace)))
(defn parse-arglist
"Given an `arglist` (a vector of parameter names for a function method),
returns a map of information about the method. May throw an exception if
`arglist` cannot be parsed."
[arglist]
(assert (every? valid-name? arglist)
@mkremins
mkremins / core_defs.cljs
Created November 27, 2014 22:21
Inspect cljs.core defs in CLJS
(def replacements
[["_PLUS_" \+] ["_STAR_" \*] ["_SLASH_" \/] ["_QMARK_" \?] ["_BANG_" \!]
["_LT_" \<] ["_GT_" \>] ["_EQ_" \=] ["_DOTDOT_" ".."] ["_" \-]])
(defn unmunge [s]
(reduce (fn [s [before after]]
(clojure.string/replace s before after))
s replacements))
(defn alphabetical? [c]
@mkremins
mkremins / weighted_choice.clj
Created October 8, 2014 20:04
Weighted random choice
(defn weighted-choice
"Given a map `choices {outcome weight}`, returns a randomly chosen `outcome`.
The likelihood that a particular `outcome` will be chosen is proportional to
its assigned `weight`."
[choices]
(->> choices
(mapcat (fn [[outcome weight]] (repeat weight outcome)))
rand-nth))
@mkremins
mkremins / scale.cljc
Last active November 30, 2017 00:23
Convert number from one scale to another
(defn scale
"Converts the number `x` from the scale `[old-min old-max]` to the scale
`[new-min new-max]`."
[x [old-min old-max] [new-min new-max]]
(let [old-range (- old-max old-min)
new-range (- new-max new-min)]
(+ (/ (* (- x old-min) new-range) old-range) new-min)))
@mkremins
mkremins / defntraced.clj
Created July 22, 2014 21:35
Define traced function
; http://www.reddit.com/r/Clojure/comments/2behsz/clojurescript_debugging_tips/cj4mvok
(defmacro defntraced
"Define a function with it's inputs and output logged to the console."
[sym & body]
(let [[_ _ [_ & specs]] (macroexpand `(defn ~sym ~@body))
new-specs
(map
(fn [[args body]]
(let [prns (for [arg args]
@mkremins
mkremins / partial_eval.clj
Last active August 29, 2015 14:02
Compile fn from expr containing unbound symbols
(ns expr-fn.core
(:require [clojure.walk :as walk]))
(defn forms-seq [form]
(tree-seq coll?
#(if (map? %) (interleave (keys %) (vals %)) %)
form))
(defn resolved? [form]
(if (coll? form)
@mkremins
mkremins / opts.clj
Created April 24, 2014 19:17
Clojure: parse sequential opts delimited by a known set of names
(defn parse-opts [ks aseq]
(let [ks (set ks)]
(loop [last-k nil
opts {}
frontier aseq]
(if-let [value (first frontier)]
(if (ks value)
(recur value opts (rest frontier))
(recur last-k (update-in opts [last-k] (fnil conj []) value) (rest frontier)))
opts))))