Skip to content

Instantly share code, notes, and snippets.

@guilespi
Created November 13, 2013 23:27
Show Gist options
  • Save guilespi/7458410 to your computer and use it in GitHub Desktop.
Save guilespi/7458410 to your computer and use it in GitHub Desktop.
Split a string into words, parallel implementation using clojure fold
(defn maybe-word
[s]
(if (= "" s) [] [s]))
(defprotocol WordState
(append-chunk [this chunk] "Append a chunk to current word state")
(append-segment [this segment] "Append a segment to current word state")
(to-word-list [this] "Returns the state as a list of words"))
(defrecord Segment [l A r]
WordState
(append-chunk [_ chunk]
(->Segment l
A
(str r (:s chunk))))
(append-segment [_ segment]
(->Segment l
(doall (concat A (maybe-word (str r (:l segment))) (:A segment)))
(:r segment)))
(to-word-list [_]
(concat [l] A [r])))
(defrecord Chunk [s]
WordState
(append-chunk [_ chunk]
(->Chunk (str s (:s chunk))))
(append-segment [_ segment]
(->Segment (str s (:l segment))
(:A segment)
(:r segment)))
(to-word-list [_]
[s]))
(defn process-char
[c]
(if (= c \space)
(->Segment "" [] "")
(->Chunk (str c))))
(defmulti append-state (fn [state s] (class s)))
(defmethod append-state Chunk
[state chunk]
(append-chunk state chunk))
(defmethod append-state Segment
[state segment]
(append-segment state segment))
(defn words
[w]
(to-word-list
(reduce (fn [state char]
(append-state state (process-char char)))
(->Chunk "")
(seq w))))
(defn combine-states
([]
(->Chunk ""))
([s1 s2]
(append-state s1 s2)))
(defn parallel-words
[w]
(to-word-list
(r/fold 10
combine-states
(fn [state char]
(append-state state (process-char char)))
(vec (seq w)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment