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 <[email protected]
> <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 [email protected]
>> <javascript:>
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> [email protected] <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 [email protected] <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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.