<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
		>
<channel>
	<title>Comments on: String Distance and Refactoring in Scala</title>
	<atom:link href="http://oldfashionedsoftware.com/2009/11/19/string-distance-and-refactoring-in-scala/feed/" rel="self" type="application/rss+xml" />
	<link>http://oldfashionedsoftware.com/2009/11/19/string-distance-and-refactoring-in-scala/</link>
	<description></description>
	<lastBuildDate>Wed, 25 Jan 2012 15:21:25 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>By: Authentication and Permissions</title>
		<link>http://oldfashionedsoftware.com/2009/11/19/string-distance-and-refactoring-in-scala/#comment-725</link>
		<dc:creator><![CDATA[Authentication and Permissions]]></dc:creator>
		<pubDate>Wed, 14 Dec 2011 16:58:36 +0000</pubDate>
		<guid isPermaLink="false">http://oldfashionedsoftware.com/?p=382#comment-725</guid>
		<description><![CDATA[i think you are going in right way for your task. And it&#039;s real method of string and code is ok to implement.]]></description>
		<content:encoded><![CDATA[<p>i think you are going in right way for your task. And it&#8217;s real method of string and code is ok to implement.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daniel Capo Sobral</title>
		<link>http://oldfashionedsoftware.com/2009/11/19/string-distance-and-refactoring-in-scala/#comment-600</link>
		<dc:creator><![CDATA[Daniel Capo Sobral]]></dc:creator>
		<pubDate>Fri, 04 Dec 2009 19:24:36 +0000</pubDate>
		<guid isPermaLink="false">http://oldfashionedsoftware.com/?p=382#comment-600</guid>
		<description><![CDATA[You do realize that, by memoizing, you are spending even more memory than the original solution? Not only you keep all values, you keep their coordinates as well!

You could go half-way, though. Recurse on rows, iterate on columns. Thinking about it, though, consider the following functions:

def emptyCosts(s: String) = List.range(0, s.length + 1)

def aboveCosts(costs: List[Int]) = cost map (_ + 1)

def diagCosts(costs: List[Int], c: Char, row: Int, s: String) = row +: (s zip costs).map {
  case (a, n) if a == c =&gt; n
  case (_, n) =&gt; n + 1
}

def sideCosts(costs: List[Int]) = costs.tail.foldLeft(List(costs.head)){
  case (left :: others, cost) =&gt; cost.min(left + 1) :: left :: others
} reverse

def lineCosts(costs: List[Int], c: Char, row: Int, s: String) = sideCosts(aboveCosts(costs) zip diagCosts(costs, c, row, s) map Function.tupled(_ min _))

def ld(s1: String, s2: String) = s1.zipWithIndex.foldLeft(emptyCosts(s2)) {
  case (costs, (c, row)) =&gt; lineCosts(costs, c, row + 1, s2)
} last

It can be made more efficient with Scala 2.8&#039;s &quot;zipped&quot;, and with judicious use of an iterator or view. 

At any rate, the previous line is used to compute the diagonal cost and the above cost, so that&#039;s the point of recursion. To compute the ld(s1, s2), compute ld(s1.take(s1.length - 1), s2), use that to compute diagonal and above costs. Get the minimum between these two, and then call sideCost to compute/optimize costs from the left. SideCost can be made recursive too.

If s1 is empty, call emptyCost instead. 

Once the recursive function is done, get the last element of the list that was computed.

Implementing this recursive version is left as an exercise for the reader of the comments, but it should avoid having to memoize anything or perform badly. :-)

It won&#039;t be tail-recursive, though. I wonder what would happen if one used Stream instead of List, however.

That was a thought-provoking post!]]></description>
		<content:encoded><![CDATA[<p>You do realize that, by memoizing, you are spending even more memory than the original solution? Not only you keep all values, you keep their coordinates as well!</p>
<p>You could go half-way, though. Recurse on rows, iterate on columns. Thinking about it, though, consider the following functions:</p>
<p>def emptyCosts(s: String) = List.range(0, s.length + 1)</p>
<p>def aboveCosts(costs: List[Int]) = cost map (_ + 1)</p>
<p>def diagCosts(costs: List[Int], c: Char, row: Int, s: String) = row +: (s zip costs).map {<br />
  case (a, n) if a == c =&gt; n<br />
  case (_, n) =&gt; n + 1<br />
}</p>
<p>def sideCosts(costs: List[Int]) = costs.tail.foldLeft(List(costs.head)){<br />
  case (left :: others, cost) =&gt; cost.min(left + 1) :: left :: others<br />
} reverse</p>
<p>def lineCosts(costs: List[Int], c: Char, row: Int, s: String) = sideCosts(aboveCosts(costs) zip diagCosts(costs, c, row, s) map Function.tupled(_ min _))</p>
<p>def ld(s1: String, s2: String) = s1.zipWithIndex.foldLeft(emptyCosts(s2)) {<br />
  case (costs, (c, row)) =&gt; lineCosts(costs, c, row + 1, s2)<br />
} last</p>
<p>It can be made more efficient with Scala 2.8&#8242;s &#8220;zipped&#8221;, and with judicious use of an iterator or view. </p>
<p>At any rate, the previous line is used to compute the diagonal cost and the above cost, so that&#8217;s the point of recursion. To compute the ld(s1, s2), compute ld(s1.take(s1.length &#8211; 1), s2), use that to compute diagonal and above costs. Get the minimum between these two, and then call sideCost to compute/optimize costs from the left. SideCost can be made recursive too.</p>
<p>If s1 is empty, call emptyCost instead. </p>
<p>Once the recursive function is done, get the last element of the list that was computed.</p>
<p>Implementing this recursive version is left as an exercise for the reader of the comments, but it should avoid having to memoize anything or perform badly. :-)</p>
<p>It won&#8217;t be tail-recursive, though. I wonder what would happen if one used Stream instead of List, however.</p>
<p>That was a thought-provoking post!</p>
]]></content:encoded>
	</item>
</channel>
</rss>

