<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Evie Salomon on Medium]]></title>
        <description><![CDATA[Stories by Evie Salomon on Medium]]></description>
        <link>https://medium.com/@evie_8157?source=rss-364e28e6f22c------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*EWiA_a8Qh8rGvGfzj-23CA.jpeg</url>
            <title>Stories by Evie Salomon on Medium</title>
            <link>https://medium.com/@evie_8157?source=rss-364e28e6f22c------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 08:22:26 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@evie_8157/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[More Whiteboards. More Problems.]]></title>
            <link>https://medium.com/@evie_8157/more-whiteboards-more-problems-42fea9f4a518?source=rss-364e28e6f22c------2</link>
            <guid isPermaLink="false">https://medium.com/p/42fea9f4a518</guid>
            <category><![CDATA[whiteboarding]]></category>
            <category><![CDATA[women-in-tech]]></category>
            <category><![CDATA[imposter-syndrome]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Evie Salomon]]></dc:creator>
            <pubDate>Mon, 07 May 2018 15:11:53 GMT</pubDate>
            <atom:updated>2018-05-07T15:19:32.989Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*r7E9jktgXY0pz4DviNpR3g.jpeg" /></figure><p>In a technical interview, whiteboard problems can take you by surprise. Sometimes it can be difficult to follow the solution you envision in your mind and reach the finish line, especially if somebody is trying to direct you to do it a different way.</p><p>When under pressure, if we cannot come up with the <strong><em>best</em></strong> answer, at least we can come up with a <strong><em>working</em></strong> solution.</p><p>Let’s take this age old problem of merging sets of ranges:</p><p>Combine [1..5, 10..15, 35..40] with [5..20, 38..48]</p><p>The first conundrum here is whether the ends of your ranges are inclusive or exclusive. An easy way to see past this problem is to define your ranges according to start and length instead of start and end. The end of a range is a vague notion (potentially inclusive or exclusive), but length is obvious.</p><p>Now that we have a way to express our data precisely, let’s go to work.</p><p>The input, therefore, is an array of range objects, where a range object can denoted quite literally:</p><pre><em>{<br>  start: 35,<br>  length: 5<br>}</em></pre><p>We can describe our function as follows:</p><pre><em>function mergeRanges(arr, arr2) {<br>  let result = [];<br>  // compute something<br>  return result;<br>}</em></pre><p>We know as a given that in each of the original arrays, nothing is overlapping. But we know that the merged result could be anywhere from 1 element in size to the sum total of each of the original elements.</p><p>Since any element could overlap with any other element, I think it’s fair to go through each element one by one to check if they overlap with something else, and to walk each array so that our indexes are lined up.</p><pre>1..5   10..15        35...40<br>   5..........20       38.......48</pre><p>But alas, I’m getting ahead of myself. The idea of walking both arrays in theory sounds straightforward, but implementing could get tricky <strong><em>real fast</em></strong>.</p><p>So let’s jump into the brute force solution. Simply try to mash every element with every other element, and repeat until nothing collides. We’ll use nested loops, very similar to the implementation of a bubble sort.</p><pre><em>function mergeRanges(arr1, arr2) {<br>  let result = arr1.concat(arr2);<br>  let goAgain = true;<br>  while (goAgain) {<br>    goAgain = false;<br>    for (let i = 0; i &lt; result.length — 1; i++) {<br>      for (let j = i + 1; j &lt; result.length; j++) {<br>        if (overlaps(result[i], result[j])) {<br>          result[i] = merge(result[i], result[j]);<br>          result.splice(j, 1);<br>          j--; // since the element at j got trashed, walk backwards<br>          goAgain = true;<br>        }<br>      }<br>    }<br>  }<br>  return result;<br>}</em></pre><p>Notice that I made some new functions on-the-fly, <strong>overlaps</strong> and <strong>merge</strong>? Let’s fill those in. Now, what is overlap? Overlap means that leftmost OR rightmost element of one range is present in the other range.</p><pre>[....]        [....]       [....]      [..........]<br>   [....]  [....]       [..........]      [....]</pre><p>First, I’ll make a helper function to get the exclusive end. I know I said length was more intuitive, and it is, but this saves us some busywork.</p><pre><em>const getEnd = a =&gt; {<br>  return a.start + a.length;<br>}</em></pre><p>Now, the overlap function:</p><pre><em>const overlaps = (a, b) =&gt; {<br>  let leftAinB = a.start &gt;= b.start &amp;&amp; a.start &lt; getEnd(b);<br>  let rightAinB = getEnd(a) &gt; b.start &amp;&amp; getEnd(a) &lt;= getEnd(b);<br>  return leftAinB || rightAinB;<br>}</em></pre><p>And finally, the merge function:</p><pre><em>const merge = (a, b) =&gt; {<br>  // assume a and b overlap<br>  let start = Math.min(a.start, b.start);<br>  let length = Math.max(getEnd(a), getEnd(b)) — start;<br>  return { start, length };<br>}</em></pre><p>Now let’s say for all intents and purposes that this solution works and there are no bugs. How fast is it? Because we have concentric loops, and the algorithm could be re-run every time elements are merged, the runtime is going to be O(n³) where n represents the average size of each of the arrays. This is a decent solution for a small data set, but I think we can do better. Can we create a solution that is O(m + n)?</p><pre><em>function mergeRanges(arr1, arr2) {<br>  let index1 = 0;<br>  let index2 = 0;<br>  let result = [];<br>  while (index1 &lt; arr1.length &amp;&amp; index2 &lt; arr2.length) {<br>    // case 1: range 1 comes before range 2 and does not overlap<br>    if (getEnd(arr1[index1]) &lt; arr2[index2]) {<br>      result.push(arr1[index1]);<br>      index1++;<br>    }<br>    // case 2: range 2 comes before range 1 and does not overlap<br>    if (getEnd(arr2[index2]) &lt; arr1[index1]) {<br>      result.push(arr2[index2]);<br>      index2++;<br>    }<br>    // case 3: they overlap<br>    result.push(merge(arr1[index1], arr2[index2]));<br>    index1++;<br>    index2++;</em></pre><pre><em>    // Wait a minute, I’m going to have to run through the list<br>    // of results again to see if they merge.</em></pre><pre><em>    // Ugh, I think it’s time to pull my hair out. All of it.<br>  }<br>  return result;<br>}</em></pre><p>Regrettably, my brain has turned to stew. The caffeine buzz I was on that got me through the brute force solution is no longer working. I’m feeling flustered. I’m embarrassed. I’m thinking to myself, <strong><em>“am I just dumb?”</em></strong></p><p>If only I had more practice. If only I was better at these kinds of problems. I can already imagine that engineer interviewing me looking down on me because he knows the answer. Is he smarter than me? Does he have the solution memorized? Am I a complete failure? Should I just plow through like a moron, fully realizing that I am a moron with no chance for improvement? As I ask for help along the way will they realize that I am a magical unicorn and pamper me with fairy dust? I think I’ll take up another profession.</p><p>Seriously, these are the thoughts going through my head. The pressure is real here, folks. What to do? I think I am going to talk it through, bracing myself for the worst but hoping for the best.</p><p>Because here’s the reality: In a supportive environment, the people around us will help us. In an unsupportive environment, they won’t. If someone is unwilling to help you at your most vulnerable state, then your glow is not shining upon them. That’s not because you don’t have a glow but it’s because their darkness is repelling it.</p><p>Yes, go through the ringer, but no, don’t feel like less of a person because you got bruised and beaten down. Ask any expert, and they will tell you persistence pays. You might be reduced to your most humble, but it is at your most humble that your true strengths will emerge.</p><p>Until then, go with the brute force solution. As you can see, it was quite a roundabout way of solving this problem, but it required only 1 fork in the road, not 10. The optimized solution is certainly something in my capacity, but it’s going to take a 3rd cup of coffee, and thanks but I could really use my beauty rest tonight.</p><p>When faced with an impossible compromise, take the easy way out. When you’re your own boss, sure, be ambitious, but as long as you’re working for somebody else, just get things done. You’ll naturally float to a place where you are valued for the magical unicorn you really are inside, and there will be plenty of smart people dousing you with buckets of fairy dust.</p><p>So go out there, be you, and save the perfection for your self-care routine.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=42fea9f4a518" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>