Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
(ns tractmanager.countwordsgitst)
(def stride (atom 0))
(defn distance
"returns [deltaX deltaY]"
[[x1 y1] [x2 y2]]
[(- x2 x1) (- y2 y1)])
(defn add-to-element
"adds a value to an element at an index and returns the resulting collection"
[coll index value]
(assoc coll index (+ (nth coll index) value)))
(defn out-of-bounds?
"checks if the index is outside of the range of our screen array"
[stride coord]
(some #(or (<= stride %) (neg? %)) coord))
(defn neighbors
"returns the neighbors in an axis"
[coord index]
(->> (range -1 2)
(map (partial add-to-element coord index))))
(defn around
"returns the elements around the index"
[stride coord]
(->> coord
(#(neighbors % 0))
(mapcat #(neighbors % 1))
(filter (comp not (partial out-of-bounds? stride)))))
(defn map-coordinates
"returns a vector of coordinates representing our letter matrix"
(for [y (range (count matrix))]
(for [x (range (count (first matrix)))]
(vector x y))))
(defn create-dictionary
"a hashmap with the coordinates of each letter"
(zipmap (apply concat (map-coordinates matrix))
(apply concat matrix)))
(defn select-values
"returns all the [keys value] pair of the desired value in a collection"
[target query]
(filter (fn [[_ value]] (= value query)) target))
(defn find-direction
"searches neighbors for a letter and returns the direction of the letter if one is found"
[dictionary start letter]
(->> (around @stride start)
(filter (comp (partial = letter) dictionary))
(map (partial distance start))))
(defn check-direction
"checks a supplied direction for the rest of the word we are searching for"
[dictionary start direction letters]
(if (nil? direction)
(loop [position (map + start direction)
query (first letters)
next (rest letters)]
(if (nil? query)
(if (= query (dictionary position))
(recur (map + position direction)
(first next)
(rest next))
(defn check-all-directions
"checks all the possible directions for the rest of the word"
[dictionary directions letters index item]
(check-direction dictionary
(first item)
(first (nth directions index))
(defn count-words-in-matrix
"finds all occurances of the first letter of the word in the matrix and then checks for the rest of the word around it"
[matrix word]
(reset! stride (count (first matrix)))
(let [dictionary (create-dictionary matrix)
characters (char-array word)
possible (select-values dictionary (first characters))
letters (rest characters)
directions (map (comp #(find-direction dictionary % (first letters)) first) possible)]
(if (> (count possible) 0)
(-> (if (< 0 (count letters))
(->> possible
(map-indexed (partial check-all-directions dictionary directions letters))
(filter true?))
(def mat
[[\A \O \T \D \L \R \O \W]
[\L \C \B \M \U \M \L \U]
[\D \R \U \J \D \B \L \J]
[\P \A \Z \H \Z \Z \E \F]
[\B \C \Z \E \L \F \H \W]
[\R \K \U \L \V \P \P \G]
[\A \L \B \L \P \O \P \Q]
[\B \E \M \O \P \P \J \Y]])
(assert (= 2 (count-words-in-matrix mat "HELLO")))
(assert (= 1 (count-words-in-matrix mat "WORLD")))
(assert (= 2 (count-words-in-matrix mat "BUZZ")))
(assert (= 0 (count-words-in-matrix mat "CLOJURE")))
(assert (= 0 (count-words-in-matrix mat "COWABUNGA")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment