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.

Reply via email to