[2015-01-19] Challenge #198 [Easy] Words with EnemiesThe challenge is to eliminate pairs of same characters from two words and report of the letters survived. | (ns daily.easy-198
(:require
[dommy.core :refer-macros [sel1]]
[reagent.core :as reagent :refer [atom]])) |
Solution | |
Convert a string into a multiset of characters. Since Clojure has no native multiset, I'm using a map of characters to integers, where the integer value is the number of that character that is in the string. | (defn count-chars
[word]
(reduce #(merge-with + %1 {%2 1}) {} word)) |
The reverse operation. Take a multiset of characters and expand it a string. | (defn expand-chars
[char-counts]
(apply str
(flatten
(for [[char count] char-counts]
(repeat count char))))) |
Combine two multisets, destroying duplicate letters. This may result in negative letter counts, but they will be ignored on expansion. | (defn explode [left right] (merge-with - left right)) |
Put it all together.
| (defn eval-enemy-words
[left right]
(expand-chars
(explode
(count-chars left)
(count-chars right)))) |
ResultYou can try it out with one pair of words at a time using the following fields. | (defn single-input []
(let [left (atom "hat")
right (atom "cat")]
(fn []
[:div
[:p "Input: "
[:input {:type "text" :value @left
:on-change #(reset! left (-> % .-target .-value))}]
[:input {:type "text" :value @right
:on-change #(reset! right (-> % .-target .-value))}]
[:p "Output: " (str (eval-enemy-words @left @right))]
(let [l-count (count @left)
r-count (count @right)]
[:p (if (= l-count r-count)
"tie"
(if (> l-count r-count)
"left wins"
"right wins"))])]]))) |
(reagent/render-component [single-input] (sel1 :#single-input)) | |