I'd strongly suggest following standard Clojure formatting, otherwise you're going to run into problems. If you use your own custom formatting that only you can read easily, then people are going to find it very difficult to help or collaborate with you. Deliberately putting up barriers to communication is a strong incentive for people to pass over your posts - why should they have to reformat your code just to understand it?
- James On 23 November 2014 at 20:05, Dan Campbell <dcwhat...@gmail.com> wrote: > > 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> 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 >>> 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 >>> 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. >>> 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.