Yep, sure enough, works like a gem, thanks. I had originally tried reduce, but wasn't able to get it to work, in this context. reduce-kv would have saved a lot of time, on previous code.
Sorry about the formatting, James. I structure my code differently than the standard Clojure format, and some of the tab sizes (2 or 3 spaces) got lost in the copying & pasting. Here's my final version, which works for several input strings: ; Credit to James Reeves (defn simplify "Replace expression with simplified expressions, using { s_substring, s_replace-character } map of replacements " [ s_expr map_translations ] (if (= (count s_expr) 1) s_expr ( let [ next-expr ( reduce-kv clojure.string/replace s_expr map_translations )] (if ( < (count next-expr) ) (count s_expr) ) (recur next-expr map_translations ) ) ; else let ) ; if (= (count s_expr) 1) ) On Sunday, November 23, 2014 12:45:16 PM UTC-5, James Reeves wrote: > > Well, first of all, it would *really* help if you formatted your code, > because currently your code is almost impossible to read. > > Let's format it first: > > (defn simplify-string [original substring replacement] > (let [simplified (str/replace original substring replacement)] > simplified)) > > (defn simplify-dat-guy [exp] > (loop [[k v] translations exp exp] > (recur [k v] (simplify-string exp k v)))) > > (defn completely-simplify-dat-guy [exp] > (loop [exp exp] > (cond > (= (.length exp) 1) exp > (second-condition exp) (recur (simplify-dat-guy exp))))) > > We can simplify this a little further still by removing simplify-string, > since it's just a wrapper around str/replace: > > (defn simplify-dat-guy [exp] > (loop [[k v] translations exp exp] > (recur [k v] (str/replace exp k v)))) > > And since recur works with functions, we can also remove the outer loop: > > (defn completely-simplify-dat-guy [exp] > (cond > (= (.length exp) 1) exp > (second-condition exp) (recur (simplify-dat-guy exp))))) > > The loop in "simplify-dat-guy" is also an example of a fold over a map, so > we can replace it with reduce-kv: > > (defn simplify-dat-guy [exp] > (reduce-kv str/replace exp translations)) > > Now let's look at your problem. Assuming I've understood correctly, you > want to simplify until you have a string of length 1, or a string that > cannot be reduced any further? > > So in that case, something like: > > (defn simplify [expr translations] > (if (= (count expr) 1) > expr > (let [next-expr (reduce-kv str/replace expr translations)] > (if (< (count next-expr) (count expr) > (recur next-expr))))) > > If we cannot reduce the expression, rather than returning "-1", let's just > return nil instead. > > - James > > > On 23 November 2014 at 16:25, Dan Campbell <dcwh...@gmail.com > <javascript:>> wrote: > >> Hi, >> >> I have to loop through a string, consecutively replacing substrings with >> single characters, one substring at a time. Each time through the loop, I >> need to use a cond to check that the length of the last replaced string, is >> shorter than the length of the previous replaced string. >> >> So, as an artificial example, say you have a string "1001110011011", and >> a map or vector of substrings and replacements >> >> ( def map_translations >> { >> { "00" "0" }, >> { "01" "0" }, >> { "10" "0" }, >> { "11" "1" } >> } >> >> ( The resemblance to a conjunction truth table is coincidental. This is >> the simplest example I could think of. ) >> >> >> So I want to loop through the map of translations several times, each >> time trying to simplify the original expression further, until a result of >> either "-1" or a single character is returned. >> >> If the length of the replaced string is greater than or equal to the >> length of the last replacement, then I'd want to return a "-1" string. >> >> But I can't figure out, how to compare the length of a result of a recur >> assignment, to the length of the PREVIOUS recur assignment. >> >> >> So, it might look something like this (untested): >> >> >> >> ( defn simplify-string >> [ s_original-string s_substring s_replacement-character ] >> ( >> let [ s_simplified-string ( clojure.string/replace s_original-string >> s_substring s_replacement-character ) ] >> s_simplified-string >> ) >> ) >> >> >> ( defn simplify-dat-guy >> "Loops through a map of substring to character translations, >> attempting to simplify a given expression. >> e.g., '00101' through successive translations would become a shorter >> form >> " >> [ s_exp ] >> ( loop >> [ [k v] map_longform-shortform-translation s_simplified-expression >> s_exp ] >> ( recur [ k v ] ( simplify-string s_simplified-expression k v ) ) >> ) >> ) >> >> >> ( defn completely-simplify-dat-guy >> "Loops through simplify-dat-guy several times, >> until either a single character or a "-1" is returned. >> e.g., '00101' through successive simplify-dat-guys would eventually >> become "0". >> " >> [ s_exp ] >> ( loop >> [ s_simplified-expression s_exp ] >> ( >> cond >> ( = ( .length s_simplified-expression ) 1 ) >> s_simplified-expression >> ( comment >> I want to put a second condition in here, something like >> ( = ( .length s_simplified-expression ) ( .length >> PREVIOUS_s_simplified_expression ) ) >> "-1" >> ) >> ( recur ( simplify-dat-guy s_simplified-expression ) ) >> ) >> ) >> ) >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clo...@googlegroups.com >> <javascript:> >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+u...@googlegroups.com <javascript:> >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+u...@googlegroups.com <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.