<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog of Brynne</title>
	<atom:link href="http://www.evanbrynne.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.evanbrynne.com</link>
	<description>UX. Performance. Code. Computers. Waaaay too many books.</description>
	<lastBuildDate>Mon, 26 Mar 2012 08:42:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>The Right Place at the Right Time: Fun with Data Structures</title>
		<link>http://www.evanbrynne.com/2012/03/the-right-place-at-the-right-time-fun-with-data-structures/</link>
		<comments>http://www.evanbrynne.com/2012/03/the-right-place-at-the-right-time-fun-with-data-structures/#comments</comments>
		<pubDate>Fri, 16 Mar 2012 10:38:24 +0000</pubDate>
		<dc:creator>evan</dc:creator>
				<category><![CDATA[Cool Problems]]></category>

		<guid isPermaLink="false">http://www.evanbrynne.com/?p=647</guid>
		<description><![CDATA[I&#8217;m a huge fan of algorithms and data structures, and how to put them to work in my code. I know that sounds incredibly generic but there&#8217;s something unique and thrilling about the investigation of a problem, breaking it down into atomic bites, and then applying all the techniques and tools at my disposal to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a huge fan of algorithms and data structures, and how to put them to work in my code. I know that sounds incredibly generic but there&#8217;s something unique and thrilling about the investigation of a problem, breaking it down into atomic bites, and then applying all the techniques and tools at my disposal to find just the right solution out of the thousands of possibilities. I&#8217;ve tried to explain this before to my friends and family, often to no avail, but just the other day I ran into a problem that really showcased how often almost any tool will work for the job, the trick is in selecting the right one. I decided to put up a post on this because I think it really could be useful in teaching someone, someday a little more about the correct application of datatypes, and help move them from writing code that just works, to code that works <em>well</em>.</p>
<p>Just a couple of notes: I&#8217;ve written in python here not only because I generally enjoy writing in it, but because it does such a fantastic job syntactically getting out of the way of the logic of the code. I firmly believe it&#8217;s prioritization of readability that really exposes the purpose of the code makes it a fantastic teaching language. Also, in this post I&#8217;m just ignoring memory usage differences, they all should be pretty negligible. </p>
<p>The problem is as follows. Given a class (shown below), complete it such that the <code>add_val(value)</code> function adds a value to some data structure which stores the set of previously entered values, and <code>sums_to(value)</code> checks whether the value supplied is the sum of any two numbers currently stored.</p>
<p><code><br />
class SumFromList:<br />
&nbsp;&nbsp;insert_val(value):<br />
&nbsp;&nbsp;&nbsp;&nbsp;#Add a value to the current set<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;sums_to(value):<br />
&nbsp;&nbsp;&nbsp;&nbsp;#Return whether any two numbers in the stored set sum to the given value<br />
</code></p>
<p>The first thing that popped into my head when I saw this was a solution for the <code>adds_to(value)</code> function. If the values were stored in a sorted array, then a quick search function could be implemented by setting pointers to the beginning (the smallest entry) and the end (the largest) of the array. Then set a loop which, if the sum of the two values pointed to sum to a value less than the one supplied, incremented the starting pointer. Alternately, if the value was greater than the one supplied the end pointer would be decremented, and of course if they add to the given value, return true. By this method, it could be accurately checked whether we have a pair which sum to the value in O(n) time.</p>
<p><code><br />
&nbsp;&nbsp;sums_to(val):<br />
&nbsp;&nbsp;&nbsp;&nbsp;head = 0<br />
&nbsp;&nbsp;&nbsp;&nbsp;tail = len(value_set) - 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;while(head < tail):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum = value_set[head] + value_set[tail]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(sum == val):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;elif(sum > val):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tail = tail - 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;head = head + 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;return false<br />
</code></p>
<p>Now this is all well and good, but it doesn&#8217;t consider the <code>insert_val(value)</code> function performance at all, nor have we done any requirements gathering beyond the initial specifications.</p>
<p>There are three different usage patterns to consider. Firstly, insertions could be significantly more frequent than checks, in which case our naive search may be good enough, provided that our insertion is especially efficient. We could also have relatively few insertions, and a great deal of calls to <code>sums_to(value)</code>, in which case we could justify a pretty ugly insertion function if we can get O(1) or O(log(n)) checking for sum-pairs. Finally, we could have similar amounts of both, in which case we would pick whichever of our two solutions performed better generally.</p>
<p>Addressing the first case, as it ties in nicely to my proposed sum-pair checker, it&#8217;s now worth looking at the <code>insert_val(value)</code> function to see what we can do to make this better. Specifically, are there any data types or algorithms that can give us a performance boost. </p>
<p>We were originally working with an array, where finding the insertion index for the value is O(log(n)) and then there&#8217;s an additional O(n) for memcpy(), which isn&#8217;t great. We could get a bit of a performance boost and maintain compatibility with our <code>sums_to(value)</code> implementation with a doubly linked list, dropping the additional O(log(n)) because while we can&#8217;t use the bisection method to find the insertion index any more, moving all following elements is no longer necessary. </p>
<p>What took me a little longer to come to than I&#8217;d care to admit, and I&#8217;m sure a few of you have arrived at the idea already, is to use a balanced binary tree. Insertion is only O(log(n)), and retrieving values in ascending or descending order, while maybe slightly more complex than with an array or linked list, is pretty simple. This would require a bit of a rewrite of our <code>sums_to(value)</code> function, and maybe a couple of extra functions to handle tree creation and traversal, but would provide by far the most elegant solution.</p>
<p>Should we instead be designing for a system where pair-sum checks are significantly more frequent, then we should look to another data structure, the hash map, for our O(1) performance solution. We will maintain two state variables, one with an unordered list of the values added through <code>insert_val(value)</code> and one with a map where each key is a sum of two of the numbers in the list and each value is simply &#8217;1&#8242; (or anything else you&#8217;d like, really). Our <code>insert_val(value)</code> function should now append each new value to the end of our list, which is O(1), and then iterate over the entire list, summing the new value and the current value and the sum as a key to the hash map. This way the <code>sums_to(value)</code> function needs only to check if the key exists, which can be O(1), our desired result.</p>
<p><code><br />
class SumFromList:<br />
&nbsp;&nbsp;value_list = []<br />
&nbsp;&nbsp;sum_dict = {}<br />
&nbsp;&nbsp;insert_val(value):<br />
&nbsp;&nbsp;&nbsp;&nbsp;value_list.append(value)<br />
&nbsp;&nbsp;&nbsp;&nbsp;for i in value_list:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum_dict[value + i] = 1<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;sums_to(value):<br />
&nbsp;&nbsp;&nbsp;&nbsp;if value in sum_dict:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true<br />
&nbsp;&nbsp;&nbsp;&nbsp;else:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false<br />
</code></p>
<p>While this may not be incredibly elegant, it&#8217;s certainly fast at checking for sum-pairs. And it could potentially be made more robust by a little further investigation into the requirements. If there&#8217;s values are likely to repeat frequently, implementing methods to store never more than two copies of the value would not interfere with results and provide boosts in both speed and memory footprint.</p>
<p>I don&#8217;t know if this is a common practice problem or not, it was the first time I had bumped into it, but it struck me as such a fantastic example of how the many data types we as programmers have at our disposal have each their own strengths and weaknesses, and of how there&#8217;s often a stand out choice (or two), even if almost any could work. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanbrynne.com/2012/03/the-right-place-at-the-right-time-fun-with-data-structures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Starting the Job Hunt and Moving to Git</title>
		<link>http://www.evanbrynne.com/2011/11/starting-the-job-hunt-and-moving-to-git/</link>
		<comments>http://www.evanbrynne.com/2011/11/starting-the-job-hunt-and-moving-to-git/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 10:37:49 +0000</pubDate>
		<dc:creator>evan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://www.evanbrynne.com/?p=295</guid>
		<description><![CDATA[So maybe it&#8217;s a little late in the game, but this marks my official start to what I hope to be my regular blogging habit. Oddly enough, today also is the beginning of the Great Job Hunt of &#8217;11. As you may suspect, it&#8217;s not purely coincidental that these two landmarks happen to fall on [...]]]></description>
			<content:encoded><![CDATA[<p>So maybe it&#8217;s a little late in the game, but this marks my official start to what I hope to be my regular blogging habit. Oddly enough, today also is the beginning of the Great Job Hunt of &#8217;11. As you may suspect, it&#8217;s not purely coincidental that these two landmarks happen to fall on the same day. As the first step in my post-graduation job search I&#8217;m properly building myself a web presence. I&#8217;ll be fleshing out this site a little, building my profiles on google+ and linkedin, and uploading some of my personal projects to github to show off what I&#8217;ve learned.</p>
<p>My main change to evanbrynne.com will be a new potential-employer landing page, linked to from my resume, which will give a bit more of a professional bio and link to my git pages and projects. If anyone ever reads this, particularly a prospective employer, any feedback would definitely be appreciated. Although I&#8217;ve done well with co-op placements and research groups at UVic, presenting myself in a professional and flattering manner is still something I&#8217;m struggling with, so for the moment I&#8217;m going for candid and honest. Finishing university (for now) and going out into the real world scares the pants off me, but it&#8217;s also one of the most exciting things I&#8217;ve ever done. I really love what I do, and the thought of getting to code, work, and learn every day of the week and really feel like I&#8217;m contributing to something sounds incredible. I hope I can put myself out there successfully and end up with a job that really challenges me; nothing would make me happier.</p>
<p>Anyhow, this post took somewhat of a different direction than I intended. I think I&#8217;ll try planning out my next posts a little more thoroughly ahead of time and see if that works better. Either way, thanks for reading. From here on in I promise to be a little less self involved. If I&#8217;m feeling genuinely ambitious I might even aim for witty. I&#8217;m sure that&#8217;ll go well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanbrynne.com/2011/11/starting-the-job-hunt-and-moving-to-git/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sweet and Delicious Pancakes</title>
		<link>http://www.evanbrynne.com/2011/07/sweet-and-delicious-pancakes/</link>
		<comments>http://www.evanbrynne.com/2011/07/sweet-and-delicious-pancakes/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 22:15:06 +0000</pubDate>
		<dc:creator>evan</dc:creator>
				<category><![CDATA[Recipes]]></category>

		<guid isPermaLink="false">http://www.evanbrynne.com/?p=278</guid>
		<description><![CDATA[I&#8217;ve never been a huge pancake fan. I mean I like them, they&#8217;re alright, but they&#8217;re nothing to write home about. They&#8217;re never quite how I&#8217;d like them. So once I started cooking more often I set about trying to tweak a pancake recipe into something that was more catered to my tastes. I found [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve never been a huge pancake fan. I mean I like them, they&#8217;re alright, but they&#8217;re nothing to write home about. They&#8217;re never quite how I&#8217;d like them. So once I started cooking more often I set about trying to tweak a pancake recipe into something that was more catered to my tastes. I found a few recipes to bastardize online, and after a few iterations I think I&#8217;ve done it.</p>
<p>What follows is the recipe for, what I consider to be, the Ultimate Pancake. Enjoy.</p>
<p>1 1/2 cups all-purpose flour<br />
3 teaspoons baking powder<br />
1 teaspoon salt<br />
2 tablespoons white sugar<br />
2 teaspoons of vanilla extract.<br />
2 Handfulls of frozen mixed berries OR 1 well ripened banana.<br />
1 1/4 cups milk<br />
1 egg<br />
3 tablespoons butter, melted</p>
<p>Mix together the dry ingredients in a bowl while your butter melts. Add either the banana or berries (or both I suppose), though if you&#8217;re using a banana, make sure that it&#8217;s a little more ripe that how you would eat it. If they&#8217;re nice and firm and fresh, just starting to brown, it&#8217;ll add an unpleasant green flavour. Next pour in the milk, egg, butter, and vanilla and mix until you&#8217;ve got most of the lumps out.</p>
<p>Heat a pan at medium and add a gratuitous amount of butter (trust me on this one). 1/4 or 1/3 cup scoops of batter produce nicely sized pancakes, let them cook on one side until bubble are breaking the top surface, then flip and cook on the other side until it too is lightly browned. Repeat for 6-10 pancakes, replenishing the butter after each set.</p>
<p>Okay, so the butter really isn&#8217;t essential, but it makes them damn tasty.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanbrynne.com/2011/07/sweet-and-delicious-pancakes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

