[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)) | |