Skip to content

Instantly share code, notes, and snippets.

@justgage
Last active August 29, 2015 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justgage/617c386964f0745d93ab to your computer and use it in GitHub Desktop.
Save justgage/617c386964f0745d93ab to your computer and use it in GitHub Desktop.
Anagram challenge in clojure
;; This is is a chalenge I did for hacker rank
;; enjoy,
;; ~ Gage
(defn first-half "gets the first half of a string"
[input]
(subs input 0 (/ (count input) 2)))
(defn second-half "gets the second half of the string"
[input]
(subs input (/ (count input) 2)))
(defn add-letter-counts
"adds a letter to a map with the value 1 or increments the letter that is already there"
[letter-counts letter]
(assoc letter-counts
letter (inc (letter-counts letter 0))))
(defn dec-to-zero
"will reduce the number `n` to zero if it's above zero. Otherwise, return zero"
[n]
(if (> n 0) (dec n) 0))
(defn dec-letter-counts
"adds a letter to a map with value zero or decrements the letter to zero if it's already there"
[letter-counts letter]
(assoc letter-counts
letter (dec-to-zero (letter-counts letter 0))))
;; The meat of the code!
(defn anagram-diff
"This will tell the number of letters that should be changed to make
the first half of input an anagram of the second half of input (the input is a string)"
[input]
;; if we can't split the input evenly...
(if (not (== (mod (count input) 2) 0))
-1 ;; return -1 meaning invalid input
;; else compute the answer
(let [left (seq (first-half input)) ;; grab the left half of the string as a list
right (seq (second-half input))] ;; grab the right half of the string as a list
(as-> {} counts ;; create a new map to put letter counts into and name it "counts"
(reduce add-letter-counts counts left) ;; adds the letter counts to the "counts" map
;; for example: abb -> {:a 1, :b 2})
(reduce dec-letter-counts counts right) ;; minus all the letters that are the same from the counts
;; for example (abb - add) -> {:a 0 :d 0 :b 2}
(reduce #(+ %1 (val %2)) 0 counts))))) ;; sum up the counts to get the number of letters to
;; be replaced to make it an anagram
(defn standard-in [] "this will read from standard in (first line being the number of inputs)
and prints out the numbers letters that would have to be changed to make it
an anagram"
(let [n (Integer/parseInt (read-line))] ; first line is the an integer indicating the number of inputs to follow
(dotimes [_ n] ;; for each of the inputs...
(-> (read-line) ; pull in a anagram string (in the form of two strings squished together)
(anagram-diff) ; compute the difference
(println))))) ; print out the answer
;; GO!
(standard-in)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment