<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: mari tang</title>
    <description>The latest articles on Forem by mari tang (@tttaaannnggg).</description>
    <link>https://forem.com/tttaaannnggg</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F96884%2F843a7eec-d735-490c-a6fa-6d4fe440a50a.jpg</url>
      <title>Forem: mari tang</title>
      <link>https://forem.com/tttaaannnggg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tttaaannnggg"/>
    <language>en</language>
    <item>
      <title>sicp 1.13 - higher order functions</title>
      <dc:creator>mari tang</dc:creator>
      <pubDate>Tue, 14 Jul 2020 20:58:11 +0000</pubDate>
      <link>https://forem.com/tttaaannnggg/sicp-1-13-higher-order-functions-3dpj</link>
      <guid>https://forem.com/tttaaannnggg/sicp-1-13-higher-order-functions-3dpj</guid>
      <description>&lt;p&gt;Whew, the math really starts kicking in on this one. I'm working off of &lt;a href="https://www.youtube.com/watch?v=eJeMOEiHv8c&amp;amp;list=PLE18841CABEA24090" rel="noopener noreferrer"&gt;this lecture series&lt;/a&gt; alongside the book itself, and honestly, I haven't been able to finish the entire problemset, but I'm trying to keep myself on track with 2 lessons per week, so here we are.&lt;/p&gt;

&lt;p&gt;I had a bit of trouble following Hal, since the way that these concepts are applied is geared towards solving math problems- in this case, how to calculate a square root.&lt;/p&gt;

&lt;p&gt;I'll skip past a lot of it, but there are a few core concepts that I got out of this lesson that are a bit unrelated to the concept of higher order functions, but are implemented through higher order functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  what is a derivative?
&lt;/h2&gt;

&lt;p&gt;I'll talk about derivatives first, since that's the thing i've got the most context for.&lt;/p&gt;

&lt;p&gt;As I understand them (from my memories of highschool calculus), derivatives are functions that describe the rate of change of another function. i.e. if you have &lt;code&gt;f(x) = 3x + 5&lt;/code&gt;, and chart it out, you'll notice a pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;f(0) = 5
f(1) = 8
f(2) = 11
f(3) = 14
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;every time &lt;code&gt;x&lt;/code&gt; increases by &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;f(x)&lt;/code&gt; increases by &lt;code&gt;3&lt;/code&gt;. so what's the derivative of &lt;code&gt;f(x)&lt;/code&gt;? &lt;code&gt;3&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;pretty simple so far, right? we generally use the notation &lt;code&gt;f'(x)&lt;/code&gt; (notice the &lt;code&gt;'&lt;/code&gt; to denote a derivative. &lt;code&gt;f'(x)&lt;/code&gt;, pronounced "f prime of x", is a function that describes the rate of change in &lt;code&gt;f(x)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I'm not going to teach you how to do derivatives the mathy way, but I'll at least say that they get more complicated as the functions you're differentiating get more complicated. for instance, we can look at the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;f(x)  = x^2 + 2x + 5
f'(x) = 2x + 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;f(x)&lt;/code&gt; changes at a rate of &lt;code&gt;f'(x)&lt;/code&gt;, which makes sense, doesn't it? if we chart out &lt;code&gt;f(x)&lt;/code&gt;, it grows faster and faster as &lt;code&gt;x&lt;/code&gt; increases, rather than growing steadily like our previous example does.&lt;/p&gt;

&lt;p&gt;Anyways, if we want to bring it back to dealing with higher order functions, I'll put it this way: taking the derivative of a function &lt;code&gt;f(x)&lt;/code&gt; produces a function that describes the rate of change of &lt;code&gt;f(x)&lt;/code&gt;. In other words, we can think of a derivative as a higher order function.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do we find a derivative?
&lt;/h2&gt;

&lt;p&gt;How would we figure out what that function is?&lt;/p&gt;

&lt;p&gt;Getting the real deal is a bit... difficult / I have no idea at my level, but we can approximate it.&lt;/p&gt;

&lt;p&gt;There's a mathematical definition for a derivative:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;f'(x) = (f(x + dx) - f(x))/(dx)
as dx -&amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this will need a little bit of explaining as well. If we think about our previous example, where we took the derivative of &lt;code&gt;f(x) = 3x + 5&lt;/code&gt;, what were we doing?&lt;/p&gt;

&lt;p&gt;Well, we put &lt;code&gt;f(0)&lt;/code&gt; in, then &lt;code&gt;f(1)&lt;/code&gt;, and calculated the difference between them. &lt;code&gt;f(1) - f(0)&lt;/code&gt;. That gives us the total change between &lt;code&gt;f(0)&lt;/code&gt; and &lt;code&gt;f(1)&lt;/code&gt;, but how do we get the rate at which it's changing? The change in total amount divided by the extent to which we changed our input will give us the answer.&lt;/p&gt;

&lt;p&gt;Again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;f'(x) = (f(x + dx) - f(x))/(dx)
as dx -&amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;dx&lt;/code&gt;, thus, represents the amount by which we change our inputs. but why &lt;code&gt;as dx -&amp;gt; 0&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;We want to produce a function that is able to tell us what the rate of change is at any point in &lt;code&gt;f(x)&lt;/code&gt;, so we need a function that is continuous. The only way we get that is by using a &lt;code&gt;dx&lt;/code&gt; that is so infinitesimally small that it's basically &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For the purposes of this function, though, we're only estimating a derivative, so we'll give it an arbitrary small value. something like &lt;code&gt;dx = 0.0000001&lt;/code&gt; will be good enough for us.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation in Scheme
&lt;/h2&gt;

&lt;p&gt;With all that being said, all we have to do is translate that into scheme, as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;derivative&lt;/span&gt; 
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;dx&lt;/span&gt; &lt;span class="mf"&gt;0.000001&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;f&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="nv"&gt;dx&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;f&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nv"&gt;dx&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in this function definition, &lt;code&gt;derivative&lt;/code&gt; is defined as a lambda function that takes in a function &lt;code&gt;f&lt;/code&gt;, defines a &lt;code&gt;dx&lt;/code&gt; to be &lt;code&gt;0.000001&lt;/code&gt; and returns a lambda function that takes in some &lt;code&gt;x&lt;/code&gt; and uses our previous formula to compute the rate of change in &lt;code&gt;f&lt;/code&gt; at &lt;code&gt;x&lt;/code&gt;. This is not a perfect answer, but it's close enough for some uses.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>SICP 1.2 - Ackermann's Function and Contemplating Infinity</title>
      <dc:creator>mari tang</dc:creator>
      <pubDate>Sat, 11 Jul 2020 00:23:30 +0000</pubDate>
      <link>https://forem.com/tttaaannnggg/sicp-1-2-ackermann-s-function-and-contemplating-infinity-4o5c</link>
      <guid>https://forem.com/tttaaannnggg/sicp-1-2-ackermann-s-function-and-contemplating-infinity-4o5c</guid>
      <description>&lt;p&gt;Let's talk about Ackermann's function. It looks something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;cond&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to describe its behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if y is 0, return 0&lt;/li&gt;
&lt;li&gt;if x is 0, return 2*y&lt;/li&gt;
&lt;li&gt;if y is 1, return 2&lt;/li&gt;
&lt;li&gt;otherwise, return Ackemrann's function with x = x-1 and y = Ackermann(x, y-1)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In order to evaluate it at anything besides the base cases, we're actually recursively evaluating Ackermann's function to even get the second argument. Working it out with arguments as low as (A 2 4) leads to huge numbers. (A 2 4) results in 65536, and larger numbers such as (A 4 4) are theoretically computable, but not within our lifetimes, at least with current hardware.&lt;/p&gt;

&lt;p&gt;How do we start to deal with numbers like that?&lt;/p&gt;

&lt;p&gt;SICP has us manually compute &lt;code&gt;(A 1 10)&lt;/code&gt;, &lt;code&gt;(A 2 4)&lt;/code&gt;, and &lt;code&gt;(A 3 3)&lt;/code&gt;, which should be enough to convince you that we're dealing with unfathomably large numbers.&lt;/p&gt;

&lt;p&gt;I started to see some interesting patterns. (A 1 10) starts unrolling like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;span class="o"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))))))))))&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we hit the &lt;code&gt;(A 1 1)&lt;/code&gt; we've finally got a base case, and it returns &lt;code&gt;2&lt;/code&gt; to the parent context. &lt;code&gt;(A 0 2)&lt;/code&gt; then evaluates to &lt;code&gt;(* 2 2)&lt;/code&gt;, which will kick one down to &lt;code&gt;(A 0 4)&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;p&gt;If the &lt;code&gt;10&lt;/code&gt; just unrolls the function 10 layers deep until it finally results in a &lt;code&gt;2&lt;/code&gt;, and each layer is resolved by multiplying the value returned from the next layer by &lt;code&gt;2&lt;/code&gt;, what we've actually got is &lt;code&gt;(A 1 10) = 2^10&lt;/code&gt;, which we can generalize as &lt;code&gt;(A 1 y)&lt;/code&gt; = &lt;code&gt;2^y&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's a good step, and it explains the behavior of the function for certain values, but let's dig a bit deeper. Can we do the same thing for other values of &lt;code&gt;x&lt;/code&gt;? Let's look at the case of &lt;code&gt;(A 0 y)&lt;/code&gt;, and plug in some values so we can see what happens.&lt;/p&gt;

&lt;p&gt;(A 0 1) =&amp;gt; 2&lt;br&gt;
(A 0 2) =&amp;gt; 4&lt;br&gt;
(A 0 3) =&amp;gt; 6&lt;br&gt;
(A 0 4) =&amp;gt; 8&lt;/p&gt;

&lt;p&gt;that looks like a &lt;code&gt;2*y&lt;/code&gt; to me!&lt;/p&gt;

&lt;p&gt;Here's the part that blew my mind: how do we prove it?&lt;/p&gt;

&lt;p&gt;Well, functions in comp sci are not entirely unlike functions in math. We can actually just plug in what we know- we can do partial applications of arguments and see how much we can work out. if we want to find out what &lt;code&gt;(A 0 y)&lt;/code&gt; is, we can actually just try to evaluate it!&lt;/p&gt;

&lt;p&gt;Let's take the body of our function and substitute 0 for x and y for y.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;cond&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it looks like the second conditional is being hit. &lt;code&gt;0 == 0&lt;/code&gt;, after all. so what does that return? &lt;code&gt;(* 2 y)&lt;/code&gt;, exactly as desired.&lt;/p&gt;

&lt;p&gt;Let's scale it up. what if we work with &lt;code&gt;(A 1 y)&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;cond&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;what we get is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if &lt;code&gt;(A 0 y) = 2*y&lt;/code&gt;, we can substitute &lt;code&gt;2*y&lt;/code&gt; for &lt;code&gt;(A 0 y)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, but we still have to get the second argument by evaluating &lt;code&gt;(A 1 (- y 1))&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;hmmmmmm&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;hmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;okay, so we've seen how this unfolds, right? Eventually we'll get to &lt;code&gt;...(A 1(- y y-1))&lt;/code&gt;, which is &lt;code&gt;...(A 1 1)&lt;/code&gt;. Let's see what that looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;cond&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;well, &lt;code&gt;1 == 1&lt;/code&gt;, no?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which becomes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and finally&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;A&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each of the &lt;code&gt;(A 0 ...)&lt;/code&gt; becomes 2 * (whatever the rest is). What do we call it when we multiply by the same number a bunch of times? exponentiation! we're doing &lt;code&gt;n*2&lt;/code&gt; &lt;code&gt;y&lt;/code&gt; times, so that's &lt;code&gt;2^y&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;You can scale up to &lt;code&gt;(A 2 y)&lt;/code&gt;, which ends up being the next order higher, raising &lt;code&gt;2^2^2...&lt;/code&gt; &lt;code&gt;y&lt;/code&gt; times. &lt;/p&gt;

&lt;p&gt;so why all of this? Ackermann's function does a few interesting things. each X is one level "up" from the previous (constant -&amp;gt; multiplication -&amp;gt; exponentiation -&amp;gt; exponentiation of exponents), which i find abstractly really fascinating.&lt;/p&gt;

&lt;p&gt;On more practical levels, it gives us insight into how we can understand super-exponential growth through recursion, how we can think about a function that grows at a nearly unthinkable rate.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>What I learned today (SICP 1.1)</title>
      <dc:creator>mari tang</dc:creator>
      <pubDate>Thu, 09 Jul 2020 22:34:42 +0000</pubDate>
      <link>https://forem.com/tttaaannnggg/what-i-learned-today-sicp-1-1-12k9</link>
      <guid>https://forem.com/tttaaannnggg/what-i-learned-today-sicp-1-1-12k9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Sadly, this series is not written for anyone except me, as a way of tracking my progress while I teach myself some computer science fundamentals. You've been warned.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm working through the venerable SICP, using the book and &lt;a href="https://www.youtube.com/playlist?list=PLE18841CABEA24090" rel="noopener noreferrer"&gt;this playlist&lt;/a&gt; and doing the exercises in the book as homework. Today I've covered chapter 1.1&lt;/p&gt;

&lt;p&gt;I'm using Jupyter Notebook with the &lt;a href="https://github.com/joeltg/mit-scheme-kernel" rel="noopener noreferrer"&gt;MIT-Scheme-Kernel&lt;/a&gt; via a docker image. I've had to do a bit of digging to understand how to get it to persist, though. Here's a script I wrote to run the notebook, forward port 8888 (the one used by Jupyter), and persist the notebooks that I make at whatever you fill in for &lt;code&gt;&amp;lt;host filepath&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is, of course, assuming you've got docker installed. it'll handle the rest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!bin/bash

docker run --rm -it -p 8888:8888 -v &amp;lt;host filepath&amp;gt;:/work kkwok/jupyter-mit-scheme 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, what did I actually learn today?&lt;/p&gt;

&lt;p&gt;We did an exercise where we built a function to do an approximation of the value of a square root. The initial version of this would start from some arbitrary guess, check if guess * guess is within some proximity of the number we're trying to sqrt, then improve it if not, and try the whole process over again.&lt;/p&gt;

&lt;p&gt;One thing I learned was that we're making implicit assumptions about the problem when we decide on the threshold for a "close enough" guess. If we want the guess to be within 0.001 of the real target, well- what if our number is huge, like 123801983120? It'll take forever to get close enough to be within 1 of the target, let alone 0.001! Same goes for small numbers. If we're trying to find the square root of 0.0001, any number we guess will probably always be within the threshold, making it worthless!&lt;/p&gt;

&lt;p&gt;So, what do we do? the answer is that we look not at an absolute closeness, but a relative closeness; what percent does our guess change? That'll scale regardless of whether the number itself is actually big or small. Brilliant.&lt;/p&gt;

&lt;p&gt;Okay, so now that that's out of the way, what else is there to learn?&lt;/p&gt;

&lt;p&gt;The sqrt function we wrote is composed of a couple of different pieces. it's composed of &lt;code&gt;sqrt&lt;/code&gt;, the "main" function, and its dependencies &lt;code&gt;close-enough?&lt;/code&gt; and &lt;code&gt;improve-guess&lt;/code&gt;, which check if we're close enough to the target, and get us closer to our target respectively.&lt;/p&gt;

&lt;p&gt;the main &lt;code&gt;sqrt&lt;/code&gt; function itself- if you think about it, all of the domain specific stuff for finding a square root is encapsulated in &lt;code&gt;close-enough&lt;/code&gt; and &lt;code&gt;improve-guess&lt;/code&gt;, which are what determines where the number goes and when it's there. That's a process that isn't about square roots. it's about iterative approximation.&lt;/p&gt;

&lt;p&gt;The last exercise of ch 1.2 was to build a cube root approximation function. we were given &lt;code&gt;(x/(y^2) + 2y)/3&lt;/code&gt; as a formula for improving a guess at a cube root, when we're trying to get to &lt;code&gt;y^3 = x&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;All that we actually need to do is replace the &lt;code&gt;improve-guess&lt;/code&gt; function with one that carries out this process, and it frickin' works.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Distributed Systems: The CAP Theorem</title>
      <dc:creator>mari tang</dc:creator>
      <pubDate>Thu, 08 Aug 2019 14:24:47 +0000</pubDate>
      <link>https://forem.com/tttaaannnggg/distributed-systems-the-cap-theorem-2p8a</link>
      <guid>https://forem.com/tttaaannnggg/distributed-systems-the-cap-theorem-2p8a</guid>
      <description>&lt;p&gt;So, I'm gonna start talking about distributed systems, as I learn them. I'm starting with the CAP theorem, which seems like a central consideration in designing distributed data stores (DBs with sharding).&lt;/p&gt;

&lt;p&gt;This is mostly a summary of other sources, particularly &lt;a href="https://codahale.com/you-cant-sacrifice-partition-tolerance/"&gt;Coda Hale's fantastic article&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The three parts of CAP are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Consistency:&lt;/strong&gt; Every time we try to read data from the database, we'll either get the most recent data, or nothing. (This is different from ACID consistency, which is about maintaining compliance with a schema/table structure)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Availability:&lt;/strong&gt; Requests receive data in response (pretty much no matter what, without any assurance that the most recent data will be sent out)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Partition Tolerance:&lt;/strong&gt; This one basically means that it works over a network / can function despite messages being dropped, truncated, delayed, or otherwise damaged by the network&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essentially, we take &lt;strong&gt;Partition Tolerance&lt;/strong&gt; as a given- We can't really have a distributed data store without being reliant on a network, and it gets definitionally not-distributed if we give this one up. People are going to accidentally cut wires, or EMPs will happen, or the power grid will go down. We can't have a distributed system at all without having to consider these hiccups.&lt;/p&gt;

&lt;p&gt;So the choice becomes this: When the network takes down one of our nodes, do we still accept requests, sending back partial (or not-fully up to date) data? Or do we wait for everything to come back online, reconcile any writes that might have happened in the meantime, and not send data until we know we're good to go?&lt;/p&gt;

&lt;p&gt;Of course, it's not completely cut and dried. &lt;a href="https://www.voltdb.com/blog/2010/10/21/clarifications-cap-theorem-data-related-errors/"&gt;Stonebreaker&lt;/a&gt; makes assertions about CAP that, frankly, I'm not quite qualified to talk about. It seems like his concern is that availability isn't a &lt;em&gt;real&lt;/em&gt; thing, and that single node failures can happen while maintaining consistency, without disruption to availability.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;To summarize my first point, the CAP theorem assumes reliable applications, reliable DBMS, reliable humans and no change in resources.  Unfortunately, these are all issues, which must be considered. In addition, modeling node failures as network partitions leads to an obviously bad conclusion.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Obvious to who? Probably someone more well-versed in DBs than I. Regardless, Stonebreaker ends up clarifying that it doesn't make much sense to "give up" consist.ency, since a sufficiently screwed up network will kill your application anyways. It's not infrastructural failure, but human error, bad actors, and glitchy code that are the real, frequent sources of downtime.&lt;/p&gt;

&lt;p&gt;Hale responds with some stories, though:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Multi-node failures may be rarer than single-node failures, but they are still common enough to have serious effects on business. In my limited experience I’ve dealt with long-lived network partitions in a single data center (DC), PDU failures, switch failures, accidental power cycles of whole racks, whole-DC backbone failures, whole-DC power failures, and a hypoglycemic driver smashing his Ford pickup truck into a DC’s HVAC system. And I’m not even an ops guy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ultimately, I do somewhat lean towards Hale's perspective, and it's essentially this: There are usually tolerances for consistency, and eventual consistency is good enough a lot of the time. Losing availability means losing money, and that's ultimately what determines the requirements of most systems, so that's what we need to prioritize.&lt;/p&gt;

&lt;p&gt;(As an aside, I'm also really tickled by the names of distributed systems - &lt;a href="https://www.cockroachlabs.com/"&gt;CockroachDB&lt;/a&gt;, and &lt;a href="https://www.project-voldemort.com/voldemort/"&gt;Project Voldemort&lt;/a&gt; are particularly funny names to me)&lt;/p&gt;

&lt;p&gt;Further reading:&lt;br&gt;
&lt;a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2011/10/ConsistencyAndBaseballReport.pdf"&gt;https://www.microsoft.com/en-us/research/wp-content/uploads/2011/10/ConsistencyAndBaseballReport.pdf&lt;/a&gt;&lt;br&gt;
&lt;a href="https://codahale.com/you-cant-sacrifice-partition-tolerance/"&gt;https://codahale.com/you-cant-sacrifice-partition-tolerance/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://martin.kleppmann.com/2015/05/11/please-stop-calling-databases-cp-or-ap.html"&gt;https://martin.kleppmann.com/2015/05/11/please-stop-calling-databases-cp-or-ap.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Consistency_model"&gt;https://en.wikipedia.org/wiki/Consistency_model&lt;/a&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>sharding</category>
      <category>distributedsystems</category>
    </item>
    <item>
      <title>Adventures in BLE with Node</title>
      <dc:creator>mari tang</dc:creator>
      <pubDate>Tue, 06 Aug 2019 19:24:11 +0000</pubDate>
      <link>https://forem.com/tttaaannnggg/adventures-in-ble-with-node-191p</link>
      <guid>https://forem.com/tttaaannnggg/adventures-in-ble-with-node-191p</guid>
      <description>&lt;p&gt;Out of curiosity, I decided that today would be the day I set up a node server that can control my YN360 (a Chinese LED wand meant for photography), so that I can start using it as an alarm clock, a remote light that I can turn on and off, a notification light, or to do fancy programmatic things for interesting videos/photos. &lt;/p&gt;

&lt;p&gt;My plan is to have a node server running on my Thinkpad x230 (which I'm gradually growing into a home server). I found that the x230 has a bluetooth chipset that can at least recognize my YN360, so hopefully it'll be able to write to it as well.&lt;/p&gt;

&lt;p&gt;I'm kinda stuck at the moment, so writing this blog is part of my debugging process.&lt;/p&gt;

&lt;h2&gt;
  
  
  BLE
&lt;/h2&gt;

&lt;p&gt;As far as I can understand from the &lt;a href="https://www.bluetooth.com/blog/a-developers-guide-to-bluetooth/" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;, a BLE device basically has a series of &lt;strong&gt;attributes&lt;/strong&gt;, which come in a few different flavors: &lt;em&gt;Services&lt;/em&gt;, &lt;em&gt;Characteristics&lt;/em&gt;, and &lt;em&gt;Descriptors&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;Service&lt;/em&gt; is a set of related &lt;em&gt;Characteristics&lt;/em&gt;, which may represent a specific feature of the device (i.e. one &lt;em&gt;Service&lt;/em&gt; might hold device info). &lt;em&gt;Characteristics&lt;/em&gt; are current data that has to do with either internal state or external state as measured by a sensor.&lt;/p&gt;

&lt;p&gt;The LED brightness / state of the YN360 should be handled by &lt;em&gt;Characteristics&lt;/em&gt;, so we won't get further into it than that. Instead, let's talk about the YN360-specific stuff I found.&lt;/p&gt;

&lt;h2&gt;
  
  
  YN360 hardware
&lt;/h2&gt;

&lt;p&gt;On the YN360 side, I learned a lot from &lt;a href="https://samuelpinches.com.au/hacking/hacking-yn360-light-wand/" rel="noopener noreferrer"&gt;Samuel Pinches's excellent blog&lt;/a&gt;, but the main takeaways were that the YN360 takes a few commands that determine which LEDs to turn on and to what brightness.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;0xAEAA01XXYY56&lt;/code&gt; will turn on the white LEDs, where the cold LEDs have a brightness of &lt;code&gt;XX&lt;/code&gt; and the warm LEDs have a brightness of &lt;code&gt;YY&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0xAEA1RRGGBB56&lt;/code&gt; does the same for the RGB LEDs, with &lt;code&gt;RR&lt;/code&gt; being the red value, &lt;code&gt;BB&lt;/code&gt; being blue, and &lt;code&gt;GG&lt;/code&gt; being green.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0xAEEE00000056&lt;/code&gt; turns off the light (but even when off, it'll still listen for BTLE commands)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I fired up LightBlue (&lt;a href="https://play.google.com/store/apps/details?id=com.punchthrough.lightblueexplorer&amp;amp;hl=en_US" rel="noopener noreferrer"&gt;android&lt;/a&gt;, &lt;a href="https://itunes.apple.com/us/app/lightblue-explorer/id557428110?mt=8" rel="noopener noreferrer"&gt;iOS&lt;/a&gt;) to do a bit of investigation into the device.&lt;/p&gt;

&lt;p&gt;I found a service with a UUID of &lt;code&gt;f000aa61-0451-4000-b000-00000000000000&lt;/code&gt;, and within that service, I found two characteristics: &lt;code&gt;f000aa63-0451-4000-b000-00000000000000&lt;/code&gt; and &lt;code&gt;f000aa61-0451-4000-b000-00000000000000&lt;/code&gt;. I'm not sure exactly what this means, but I noticed that the latter (starting with &lt;code&gt;f000aa61&lt;/code&gt;) supported writes. After sending it &lt;code&gt;AEAA01999956&lt;/code&gt; (white LED string with a brigthness of 99), the light actually turned on!&lt;/p&gt;

&lt;p&gt;Now, the goal is to get Node to send the signal, so that I can have routes on my home server to interact with the light over my local network.&lt;/p&gt;

&lt;h2&gt;
  
  
  node
&lt;/h2&gt;

&lt;p&gt;NodeJS was a bit harder, and I still haven't got it fully running yet. I found a library called &lt;a href="https://github.com/noble/noble" rel="noopener noreferrer"&gt;noble&lt;/a&gt;, which refused to install on my machine. The last commit was made on Jun 7, 2018. Luckily, there's an &lt;a href="https://github.com/abandonware/noble" rel="noopener noreferrer"&gt;abandonware fork&lt;/a&gt; of it that was last updated on April 15, 2019. Luckily this one installs, and it was even able to detect my YN360 with a scan!&lt;/p&gt;

&lt;p&gt;The flow is something like this:&lt;/p&gt;

&lt;p&gt;discover device -&amp;gt; connect to device -&amp;gt; find services -&amp;gt; write to the appropriate service. The &lt;code&gt;discover&lt;/code&gt;, &lt;code&gt;connect&lt;/code&gt;, and &lt;code&gt;discoverAllServicesAndCharacteristics&lt;/code&gt; methods are all callback-based, so they'd have to be nested inside of one another, or defined as named functions in an effort to reduce nesting.&lt;/p&gt;

&lt;p&gt;I've gotten up to the point where I've found 2 &lt;em&gt;Characteristics&lt;/em&gt; that can be written to. One has a name of &lt;code&gt;'Device Name'&lt;/code&gt;, which I'm assuming ain't it. The other has an undefined name. By checking UUIDs, I can see that it matches the UUID of &lt;code&gt;f000aa61-0451-4000-b000-00000000000000&lt;/code&gt; (without spaces), which should refer to the &lt;em&gt;Characteristic&lt;/em&gt; we need to write to.&lt;/p&gt;

&lt;p&gt;The last bit, now, is to try to actually write to the dang thing, then refactor my code into a more modular shape.&lt;/p&gt;

</description>
      <category>ble</category>
      <category>node</category>
      <category>server</category>
    </item>
    <item>
      <title>what's the first website/project you made?</title>
      <dc:creator>mari tang</dc:creator>
      <pubDate>Tue, 30 Jul 2019 17:54:57 +0000</pubDate>
      <link>https://forem.com/tttaaannnggg/what-s-the-first-website-project-you-made-87n</link>
      <guid>https://forem.com/tttaaannnggg/what-s-the-first-website-project-you-made-87n</guid>
      <description>&lt;p&gt;I'm in the interview process for my next tech job, but I figured I'd stop to look back a bit. The earliest bit of web development I can remember was my &lt;a href="http://www.angelfire.com/blog/mrurl/" rel="noopener noreferrer"&gt;Angelfire site&lt;/a&gt;. It's a static site that I built at the tender age of 11, all the way back in 2005.&lt;/p&gt;

&lt;p&gt;It wasn't always orange- I had a cool tiled black-and-green matrix-style background (it was an animated GIF as well!) until link rot killed it. There were also a bunch of embedded pieces of code from other sites that were supposed to add different animations or sounds, none of which really work any more anyways. The whole thing is written solely in HTML, with some inline styling. &lt;/p&gt;

&lt;p&gt;It was super fun making it, and both embarrassing and fun to look at it again, now that I'm a proper MERN stack developer working with all kinds of high-tech containerization and automation tools.&lt;/p&gt;

&lt;p&gt;Do any of y'all have old projects you'd like to share?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Algorithms: Range Sum Query</title>
      <dc:creator>mari tang</dc:creator>
      <pubDate>Sun, 14 Jul 2019 22:56:03 +0000</pubDate>
      <link>https://forem.com/tttaaannnggg/algorithms-range-sum-query-2hcf</link>
      <guid>https://forem.com/tttaaannnggg/algorithms-range-sum-query-2hcf</guid>
      <description>&lt;p&gt;It's algorithm time again!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://leetcode.com/problems/range-sum-query-immutable/" rel="noopener noreferrer"&gt;This one's a leetcode easy&lt;/a&gt;, but there's a lot to be learned from it.&lt;/p&gt;

&lt;p&gt;Here's the problem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;RANGE SUM QUERY&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, if we have an array of, say &lt;code&gt;[1,2,3,4,5]&lt;/code&gt;, and indices of &lt;code&gt;2&lt;/code&gt; and &lt;code&gt;4&lt;/code&gt;, we'd add &lt;code&gt;3 + 4 + 5&lt;/code&gt; to get &lt;code&gt;12&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Pretty simple, right? We can just loop over our array and sum up whatever's between (and including) the indexes we get.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;NumArr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;NumArr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rangeSum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not a horrible solution. If we query our array only once or twice, or if we expect to get in a variety of arrays, this works. Computers are very good at addition-&lt;a href="https://streamhpc.com/blog/2012-07-16/how-expensive-is-an-operation-on-a-cpu/" rel="noopener noreferrer"&gt;it's possibly the fastest operation a CPU can do&lt;/a&gt;. In fact, it's so fast that it actually does pass the leetcode tests.&lt;/p&gt;

&lt;p&gt;However, there are two stipulations provided, which give us space to improve and optimize our solution.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;You may assume that the array does not change.&lt;/li&gt;
&lt;li&gt;There are many calls to sumRange function.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, let's think about how this works. If we're doing a sufficient number of sums, some of them will probably hit the same range, right? We can cache our solution and look it up instead of re-calcluating it. Let's put a cache on the constructor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caching
&lt;/h3&gt;

&lt;p&gt;What shape should the cache take?&lt;br&gt;
If we think about it for a minute, a two dimensional array seems to make the most sense- we're adding a range from &lt;code&gt;i&lt;/code&gt; to &lt;code&gt;j&lt;/code&gt;, so we can dump our cached results at &lt;code&gt;this.cache[i][j]&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;NumArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[]);&lt;/span&gt; &lt;span class="c1"&gt;//fill cache with one empty array per item in arr&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;NumArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sumRange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]){&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works, but the extra task of storing stuff in our cache makes the initial query to a range much slower. Each successive time we query is gonna be plenty fast, but it also counts on us landing on our exact range again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is there an even better solution?
&lt;/h3&gt;

&lt;p&gt;Short answer: yes. very yes.&lt;/p&gt;

&lt;p&gt;Getting there was a bit of a pain. Initially, I'd glanced at the leetcode solution and saw something about precomputing the results. I took this to mean that we should pre-calculate and cache the entire thing- and why not?&lt;/p&gt;

&lt;p&gt;If we're computing any range sum, we're doing repeated work. i.e. if we sum the values from index &lt;code&gt;0&lt;/code&gt; to index &lt;code&gt;5&lt;/code&gt;, we've calculated &lt;code&gt;arr[0]+arr[1]&lt;/code&gt;, &lt;code&gt;arr[0]+arr[1]+arr[2]&lt;/code&gt;, etc etc. This means that we can simply cache some of those intermediary values as we go.&lt;/p&gt;

&lt;p&gt;I could intuit that I could at least get the first set of sums like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;NumArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When this finishes computing, our cache will be an array with all of the sums from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;n&lt;/code&gt;. &lt;code&gt;[(sum of index 0), (sum of index 0 to index 1), (sum of index 0 to index 2), ...., (sum of index 0 to index n)]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That's a nice little bit of computation that makes our lives easier, but how would we think about getting all of the sums of &lt;code&gt;index 1 to index n&lt;/code&gt;, then &lt;code&gt;index 2 to index n&lt;/code&gt;, all the way up to &lt;code&gt;index n-1 to index n&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;I tried to figure out if there was an easy way to compute all possible sums, but kept getting &lt;code&gt;O(n^2)&lt;/code&gt; solutions that would time out on leetcode.&lt;/p&gt;

&lt;p&gt;So I tried to figure out what sort of patterns I could see in a test case, modelling it by hand with a very simple array of &lt;code&gt;[0,1,2,3,4]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhywo4yb1cix5f8sqw1mb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhywo4yb1cix5f8sqw1mb.jpg" width="800" height="790"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are a few interesting things going on. We can see that each successive row is basically made by taking the previous row and subtracting whatever integer we're skipping.&lt;/p&gt;

&lt;p&gt;The first row is made by summing all numbers.&lt;br&gt;
The second row can be made by taking the first row and subtracting the first number&lt;br&gt;
The third row can be made by taking the second row and subtracting the second number&lt;br&gt;
The fourth row can be made by taking the third row and subtracting the third number&lt;br&gt;
...and so on.&lt;/p&gt;

&lt;p&gt;It took a bit for this to sink in, but the secret here depends on rearranging that previous insight:&lt;/p&gt;

&lt;p&gt;In other words, we can find any range from &lt;code&gt;i&lt;/code&gt; to &lt;code&gt;j&lt;/code&gt; by taking the sum of numbers from index &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;j&lt;/code&gt;, and subtracting the sum of numbers from index &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;i&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With this being the case, all of the data we need is created when we make our initial pass. We're guaranteed to have the appropriate sum for index &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;i&lt;/code&gt;, and likewise, for index &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;j&lt;/code&gt;. We don't even have to cache every possible answer to have an &lt;code&gt;O(1)&lt;/code&gt; operation.&lt;/p&gt;

&lt;p&gt;Here's what my final result looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;NumArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// done to avoid an "if" check for the first number&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;NumArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sumRange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This saves immensely on time complexity- Our initial pass through the array is &lt;code&gt;O(n)&lt;/code&gt;, which is the same time complexity as calculating a single range sum in the first place (i.e. if you want to sum from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;arr.length-1&lt;/code&gt;). Afterwards, getting any successive answers is an &lt;code&gt;O(1)&lt;/code&gt; operation!&lt;/p&gt;

&lt;p&gt;The only real tradeoff is that the space complexity of this solution is also &lt;code&gt;O(n)&lt;/code&gt;, but it's well worth it.&lt;/p&gt;

</description>
      <category>alogrithms</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Algorithms: Closest to TwoSum</title>
      <dc:creator>mari tang</dc:creator>
      <pubDate>Fri, 05 Jul 2019 08:28:19 +0000</pubDate>
      <link>https://forem.com/tttaaannnggg/algorithms-closest-to-twosum-3npj</link>
      <guid>https://forem.com/tttaaannnggg/algorithms-closest-to-twosum-3npj</guid>
      <description>&lt;p&gt;Today I was introduced to another algorithm. It was framed to me as similar to TwoSum, but with a major caveat- Rather than figuring out if/which two numbers in an array added to a target number, it asked to figure out the two numbers that summed closest to the target.&lt;/p&gt;

&lt;p&gt;If that's not immediately clear, let's look at an example case.&lt;/p&gt;

&lt;p&gt;If we have a set of &lt;code&gt;[1,5,12,6,13]&lt;/code&gt;, with a target of &lt;code&gt;12&lt;/code&gt;, the closest we can get is either &lt;code&gt;1+12&lt;/code&gt;, which is &lt;code&gt;13&lt;/code&gt; (distance of 1), or &lt;code&gt;5+6&lt;/code&gt;, which is &lt;code&gt;11&lt;/code&gt; (also distance of 1).&lt;/p&gt;

&lt;p&gt;It's not too hard to do it in &lt;code&gt;O(n^2)&lt;/code&gt; time. We can just compute all possible sums, and either compare them at the end (&lt;code&gt;O(n)&lt;/code&gt; space complexity), or maintain a &lt;code&gt;lowestDistance&lt;/code&gt; value that we update as we continue to navigate our array (&lt;code&gt;O(1)&lt;/code&gt; space). That might look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;closestTwo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;lowestDistance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dist&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;lowestDistance&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;lowestDistance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, we can actually do better than &lt;code&gt;O(n^2)&lt;/code&gt;. How much better? We'll find out.&lt;/p&gt;

&lt;p&gt;At first, I was perplexed by this; with the way that the problem is framed, I guessed that the solution might be similar to twoSum, and that it would have something to do with that type of inverted thinking. Here are a few of the routes that I went down.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We could do the twoSum thing and subtract our target from each number, storing them in a datastructure that we can check quickly, like a &lt;code&gt;Set&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;However, if we're talking about being "close", rather than spot on, we can't fuzz the thing we're going to give to our &lt;code&gt;.has()&lt;/code&gt;- I want to delimit it by a certain range, but even the closest number could end up being very far from our target, and if we have to check each step in the range, it ends up being extremely slow.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;We could sort the array. it's &lt;code&gt;O(nlogn)&lt;/code&gt;, which would make the behavior of the array more predictable

&lt;ul&gt;
&lt;li&gt;But how do we find a solution from there? Perhaps a binary search is possible?&lt;/li&gt;
&lt;li&gt;If we do a binary search, how do we know what we're looking for?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Well, the sort and binary search kind of actually works. It's still not the fastest, but we can do it in &lt;code&gt;O(nlogn)&lt;/code&gt; time, which is the best time complexity I've gotten so far, even though it can be optimized further.&lt;/p&gt;

&lt;p&gt;Here's how this approach works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start one pointer at the beginning of the array&lt;/li&gt;
&lt;li&gt;Subtract it from the target sum&lt;/li&gt;
&lt;li&gt;Whatever the remainder is, binary search through all items after it and grab the closest value you can find&lt;/li&gt;
&lt;li&gt;Move the pointer to the next item in the array and repeat the process&lt;/li&gt;
&lt;li&gt;Compare to previous lowest distance and keep whatever's a closer answer&lt;/li&gt;
&lt;li&gt;Repeat until you've traversed the entire array&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's write it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;closestTwo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;lowestDist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;lowestNums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;searchTarget&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;guess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;lastGuess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;lastDist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchTarget&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;lastGuess&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;dist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchTarget&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;guess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;guess&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;dist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchTarget&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchTarget&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;guess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;dist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchTarget&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dist&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;lastDist&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;lastGuess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;lastDist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lastDist&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;lowestDist&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="nx"&gt;lowestDist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lastDist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;lowestNums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="nx"&gt;lowestNums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lastGuess&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;lowestNums&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, this is well and fine, but it's doing 2 &lt;code&gt;O(nlogn)&lt;/code&gt; operations. The first is that we sort it, and the second is that we're iterating through the array, plus doing a binary search for each of those iterations. That's as good as the time complexity gets, but we can tweak it a bit to do one &lt;code&gt;O(nlogn)&lt;/code&gt; operation (sorting), and one &lt;code&gt;O(n)&lt;/code&gt; operation.&lt;/p&gt;

&lt;p&gt;Let's talk about how we do this.&lt;/p&gt;

&lt;p&gt;Remember when I said earlier that the behavior of our array gets a lot more predictable after we've sorted it? Let's think about how we can use that to our advantage. If we sort from low to high, we know that the closer you are to the beginning of the array, the lower your number is, and the more you move towards the end, the higher the number is. The lowest possible sum is the two first items of the array, and the highest possible sum is the two last items of the array.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[1,2,3,4,5]&lt;/code&gt; has a lowest possible sum of &lt;code&gt;1+2&lt;/code&gt;, and a highest possible sum of &lt;code&gt;4+5&lt;/code&gt;- but how do we figure out the stuff in between? The magic of it is that we can do so by moving around a couple of pointers, which will inevitably converge to the closest possible sum. The way that we ensure that we're moving closer to the desired solution is that we'll use two pointers- one at the start and one at the end of our array. Here's how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sort the array&lt;/li&gt;
&lt;li&gt;Put a pointer at the beginning of the array&lt;/li&gt;
&lt;li&gt;Put a pointer at the end of the array&lt;/li&gt;
&lt;li&gt;sum the two values we're pointing at&lt;/li&gt;
&lt;li&gt;Is our sum higher or lower than the target?&lt;/li&gt;
&lt;li&gt;If the sum is too high, move the end pointer to the next lowest item. If it's too low, move the low pointer to the next higher item&lt;/li&gt;
&lt;li&gt;Find the sum of the two values again&lt;/li&gt;
&lt;li&gt;If that sum has a higher distance than the last sum, return the previous values&lt;/li&gt;
&lt;li&gt;Otherwise, continue the process.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's what that looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;closestSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;lowPointer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;highPointer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;closestDist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;lowPointer&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!==&lt;/span&gt;&lt;span class="nx"&gt;highPointer&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lowPointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;highPointer&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dist&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;closestDist&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="nx"&gt;closestDist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lowPointer&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;highPointer&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;lowPointer&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;highPointer&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's also not the easiest to read, but we're basically either scooching our low pointer up, or our high pointer down. We know that it's over if our guesses are getting worse, or if our pointers are directly next to each other, at which point we can simply break out of our loop and return our values.&lt;/p&gt;

&lt;p&gt;Major takeaways: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Making comparisons and analogies is good, but don't let yourself get trapped in them - I might have been able to solve this faster if I didn't already know twoSum&lt;/li&gt;
&lt;li&gt;An initial sort is often key to manipulating your dataset, and can provide you with valuable tools for searching it (binary search in O(logn) in particular).&lt;/li&gt;
&lt;li&gt;There are other types of intuitions to develop about handling your dataset- I couldn't intuit that moving pointers from the outside in would guarantee full coverage of the array, but it's now clear to me that any subarray can be reached by doing so. This may prove useful for other algorithms.&lt;/li&gt;
&lt;li&gt;This solution also works for twoSum, though the time complexity is slightly worse b/c of the sort. If the array were pre-sorted, we'd be able to do this in both O(n) time and O(1) space.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>algorithms</category>
      <category>twosum</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Creating and provisioning VMs with Vagrant and VirtualBox</title>
      <dc:creator>mari tang</dc:creator>
      <pubDate>Sat, 29 Jun 2019 02:59:43 +0000</pubDate>
      <link>https://forem.com/tttaaannnggg/creating-and-provisioning-vms-with-vagrant-and-virtualbox-7o8</link>
      <guid>https://forem.com/tttaaannnggg/creating-and-provisioning-vms-with-vagrant-and-virtualbox-7o8</guid>
      <description>&lt;p&gt;At my job, we've been having a lot of issues with students having misconfigured / incompatible (or annoying to set up) hardware. Dealing with PostgreSQL, MongoDB, Docker, and filesystem operations in a place where people are split between Windows and UNIX-like environments is a total pain, and WSL isn't fully mature, so I decided to prepare a VM that would allow them to develop MERN stack applications with minimal fuss. (it's &lt;a href="https://github.com/tttaaannnggg/webvm" rel="noopener noreferrer"&gt;here&lt;/a&gt; if you want to check it out or give feedback!)&lt;/p&gt;

&lt;p&gt;I used &lt;a href="https://www.vagrantup.com/" rel="noopener noreferrer"&gt;Vagrant&lt;/a&gt; with &lt;a href="https://www.virtualbox.org/" rel="noopener noreferrer"&gt;VirtualBox&lt;/a&gt;, which I hear isn't ideal for heavy lifting- but hey, we'll use Docker if we need better performance.&lt;/p&gt;

&lt;p&gt;The process of using Vagrant is pretty simple. You create a &lt;code&gt;Vagrantfile&lt;/code&gt;, which defines the behavior of your VM. In my case, I want to use it for webdev, so I'm starting with an Ubuntu 18.04 installation (as opposed to a Windows one). I'm also forwarding ports 3000, 5432, 8000, 8080, and 27017, which are for web servers, except for 5432 and 27017, which are for PostgreSQL and MongoDB respectively.&lt;/p&gt;

&lt;p&gt;My &lt;code&gt;Vagrantfile&lt;/code&gt; looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/bionic64"

  # we're opening 3000, 8000, and 8080 because they're the most
  # likely to be used during your webdev process.
  #
  # if you need more ports, copy paste the examples and change the numbers
  config.vm.network "forwarded_port", guest:3000, host:3000
  config.vm.network "forwarded_port", guest:5432, host:5432
  config.vm.network "forwarded_port", guest:8000, host:8000
  config.vm.network "forwarded_port", guest:8080, host:8080
  config.vm.network "forwarded_port", guest:27017, host:27017

  # this will run initial setup
  config.vm.provision :shell, path: "bootstrap.sh"
end

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm sure there's a way for me to loop over and forward an array of ports, but I'll work that out later. The important thing is that if we need to forward additional ports, we can do so inside of this file, following the same syntax we've already got.&lt;/p&gt;

&lt;p&gt;So, the &lt;code&gt;config.vm.box&lt;/code&gt; tells us what OS to use, the &lt;code&gt;config.vm.network&lt;/code&gt; tells us how to deal with networking - but what does the &lt;code&gt;config.vm.provision&lt;/code&gt; do? Well, to answer that question, I'll tell you about how I ended up settling on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Provisioning
&lt;/h2&gt;

&lt;p&gt;So, initially when I installed Vagrant and spun up a VM, I was using it pretty much the same way that I used my actual Linux box. I was installing stuff on it, even using vim within the VM to edit and write code. But, one of the things that appealed to me about VMs is that they let you set up an environment exactly the way that you want it. What's the best way to go about that?&lt;/p&gt;

&lt;p&gt;Well, one thing we can do is package our entire VM image as a box. This is a nice idea, but it means that we'll have to upload the image somewhere, and download the whole thing every time we want to get another machine set up.&lt;/p&gt;

&lt;p&gt;The alternative to this is that we "provision" our machine automatically. Rather than packaging everything together, we can simply have a set of scripts that will automatically install our utilities when we first set up our VM. We can use a tool like &lt;a href="https://www.ansible.com/" rel="noopener noreferrer"&gt;Ansible&lt;/a&gt; for this (and I'll move over to it eventually), but I opted for a simple bash script, which is what we're doing when we see the line &lt;code&gt;config.vm.provision :shell, path: "bootstrap.sh"&lt;/code&gt;. The &lt;code&gt;Vagrantfile&lt;/code&gt; references a &lt;code&gt;bootstrap.sh&lt;/code&gt; script file that is simply a list of bash commands that will install and configure stuff for us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/usr/bin/env bash

apt-get update
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
nvm install node
sudo apt-get install -y npm
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.list
sudo apt-get update
sudo apt-get install -y mongodb
sudo systemctl start mongod
sudo systemctl enable mongod
sudo apt-get install -y postgresql postgresql-contrib
sudo su - postgres -c "createuser vagrant"
sudo mkdir /data
sudo mkdir /data/db

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we're mostly adding PPAs and installing stuff, with the addition of a couple of operations where we're creating a user for our PostgreSQL installation and a data folder for our MongoDB. We just run &lt;code&gt;vagrant up&lt;/code&gt;, and everything else takes care of itself.&lt;/p&gt;

&lt;p&gt;All in all, this process is super nice, because I only have to package and pass around the &lt;code&gt;Vagrantfile&lt;/code&gt; and &lt;code&gt;bootstrap.sh&lt;/code&gt; script, which are only a few lines each, rather than a 500-800MB behemoth. Everything gets reliably set up, and then we're working with exactly the environment we want!&lt;/p&gt;

&lt;p&gt;It's definitely a little bit of a process to set up (though nowhere near as involved as dual booting Ubuntu, or as expensive as buying a new computer), and I can foresee issues with getting confused about shared folders or which OS they're working in, but I'm really excited to save some of the Windows users from the nightmare of configuring their computers for a curriculum that was developed entirely for UNIX environments.&lt;/p&gt;

&lt;h1&gt;
  
  
  Next Steps
&lt;/h1&gt;

&lt;p&gt;I'd like to dig into Ansible, and provision machines using a playbook. I'd also like to figure out if Docker is a more feasible / efficient solution to this problem (but having a full OS that defaults to an interactive terminal and being able to just keep projects in the shared folder is so much better than rewriting a docker compose file every time you want to do something else, and Docker on Windows is annoying!). I'll probably add a docker installation to it, and I'd like to dig into emulating clusters using multiple VMs (I've been meaning to learn Kubernetes, and it'd be nice to learn to deal with the complexities of load balancing across multiple pieces of hardware)&lt;/p&gt;

&lt;p&gt;In general, I'm focusing on the backend, and dipping into the &lt;a href="https://roadmap.sh/devops" rel="noopener noreferrer"&gt;DevOps roadmap&lt;/a&gt;. I've really been enjoying this level of abstraction and the process of thinking about systems at scale! Now that I've had a taste of containerization and virtualization, I'd like to virtualize/containerize and try scaling some projects. I've got a Raspberry Pi cluster in the works, and want to try setting up a CI/CD pipeline and a webserver on it, with some cute extras like home automation (check out my &lt;a href="https://github.com/tttaaannnggg/node-yn360" rel="noopener noreferrer"&gt;server for doing BLE transmissions to a YN360 RGB light&lt;/a&gt;!).&lt;/p&gt;

&lt;p&gt;I'm pretty excited to delve a bit deeper into this world, and am pretty excited to see what comes out of it! Any suggestions as far as what technologies I should look at next?&lt;/p&gt;

</description>
      <category>it</category>
      <category>devops</category>
      <category>virtualization</category>
    </item>
    <item>
      <title>Redux for Buddies Pt2: writing to state</title>
      <dc:creator>mari tang</dc:creator>
      <pubDate>Wed, 29 May 2019 21:14:21 +0000</pubDate>
      <link>https://forem.com/tttaaannnggg/redux-for-dummies-pt2-writing-to-state-3mj0</link>
      <guid>https://forem.com/tttaaannnggg/redux-for-dummies-pt2-writing-to-state-3mj0</guid>
      <description>&lt;p&gt;Where we last left off, we had a general understanding of the Redux loop. We understood that &lt;strong&gt;containers&lt;/strong&gt; provide access to our &lt;code&gt;store&lt;/code&gt;, which we selectively use to hydrate our components' &lt;code&gt;props&lt;/code&gt; via &lt;code&gt;mapStateToProps&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As a quick refresher, here's what the general loop looks like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;store&lt;/strong&gt; (state) -&lt;em&gt;defines&lt;/em&gt;-&amp;gt; &lt;strong&gt;frontend&lt;/strong&gt; -&lt;em&gt;triggers&lt;/em&gt;-&amp;gt; &lt;strong&gt;event handler&lt;/strong&gt; (or other functionality) -&lt;em&gt;sends data/signal (action) to&lt;/em&gt;-&amp;gt; &lt;strong&gt;reducer&lt;/strong&gt; -&lt;em&gt;updates&lt;/em&gt;-&amp;gt; &lt;strong&gt;store (state)&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For convenience's sake, we'll take the code we've written and replace the &lt;code&gt;otherComponent&lt;/code&gt; we were rendering with a &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag that will display our &lt;code&gt;userCount&lt;/code&gt;. With that modification, here's our code so far:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userCount&lt;/span&gt; &lt;span class="c1"&gt;// store looks like: {'userCount':5}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mapDispatchToProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;//we'll fill this in and explain it later!&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;DisplayUsers&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mapStateToProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mapDispatchToProps&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;DisplayUsers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, to get state updates to work, we need to send data from the frontend. We'll start with that. Remember &lt;code&gt;mapDispatchToProps&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Well, &lt;code&gt;dispatch&lt;/code&gt; is what allows our frontend to send data up to the &lt;code&gt;store&lt;/code&gt;. Let's imagine that we have a button that we want to click to add 1 to our &lt;code&gt;usercount&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userCount&lt;/span&gt; &lt;span class="c1"&gt;// store looks like: {'userCount':5}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mapDispatchToProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;//we'll fill this in and explain it later!&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;DisplayUsers&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* some function */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So, in order to mutate our state, we need to &lt;code&gt;dispatch&lt;/code&gt; an &lt;code&gt;action&lt;/code&gt; to our &lt;code&gt;store&lt;/code&gt;. Let's start by talking about what an &lt;code&gt;action&lt;/code&gt; is, starting with how they're created.&lt;/p&gt;

&lt;h2&gt;
  
  
  Action Creators / Actions
&lt;/h2&gt;

&lt;p&gt;An Action Creator is a function. It takes a single argument in, and returns an object which we refer to as an &lt;code&gt;action&lt;/code&gt;. An &lt;code&gt;action&lt;/code&gt; is just an object that has two properties on it: &lt;code&gt;type&lt;/code&gt; and &lt;code&gt;payload&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's what an action creator might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;types&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../constants/actionTypes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ADD_USER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;  
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see, &lt;code&gt;addUser&lt;/code&gt; returns an object that looks like this: &lt;code&gt;{type: types.ADD_USER, payload: /* whatever payload we give it */}&lt;/code&gt;, which is the &lt;code&gt;action&lt;/code&gt; that it is creating.&lt;/p&gt;

&lt;p&gt;So, what is a &lt;code&gt;type&lt;/code&gt;? and what data might we want to have in our &lt;code&gt;payload&lt;/code&gt;?&lt;/p&gt;

&lt;h3&gt;
  
  
  Action Types
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;type&lt;/code&gt; is really just a string that we're importing from our &lt;code&gt;actionTypes&lt;/code&gt; file. By convention, the names of our actions are capitalized.&lt;/p&gt;

&lt;p&gt;Basically, there are different types of state updates that we would like our &lt;code&gt;reducers&lt;/code&gt; to &lt;br&gt;
handle, and our &lt;code&gt;type&lt;/code&gt; determines which one to use. We'll get into our &lt;code&gt;reducers&lt;/code&gt; a little further down, but, for now, we'll look at what our &lt;code&gt;actionTypes.js&lt;/code&gt; file might have inside of it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ADD_USER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ADD_USER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's really just a string with a few conventions applied to it.&lt;/p&gt;

&lt;p&gt;So, as far as why we'd store that string in a variable instead of just typing it in directly, it has to do with the reason that Redux exists in the first place: scale.&lt;/p&gt;

&lt;p&gt;At scale, there are a few benefits to using action types. From Dan Abramov's own words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It helps keep the naming consistent because all action types are gathered in a single place.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sometimes you want to see all existing actions before working on a new feature. It may be that the action you need was already added by somebody on the team, but you didn’t know.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The list of action types that were added, removed, and changed in a Pull Request helps everyone on the team keep track of scope and implementation of new features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you make a typo when importing an action constant, you will get undefined. This is much easier to notice than a typo when you wonder why nothing happens when the action is dispatched.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;it's total overkill for a project this scale, but so is Redux. That being said, we'll get to our &lt;code&gt;payload&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Payload
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;payload&lt;/code&gt; is the other property on our &lt;code&gt;action&lt;/code&gt;. This is the actual data that we'll send to our &lt;code&gt;reducers&lt;/code&gt;. (if our &lt;code&gt;action&lt;/code&gt; needs to provide data at all- increasing our user count by 1 doesn't require any info other than action type).&lt;/p&gt;

&lt;p&gt;We'll need to talk about &lt;code&gt;reducers&lt;/code&gt; to really understand &lt;code&gt;actions&lt;/code&gt;, but we'll talk about how we send &lt;code&gt;actions&lt;/code&gt; to our &lt;code&gt;reducers&lt;/code&gt; first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Back To mapDispatchToProps
&lt;/h2&gt;

&lt;p&gt;So, we've got an &lt;code&gt;actionCreator&lt;/code&gt;, which returns an &lt;code&gt;action&lt;/code&gt;, which has a &lt;code&gt;type&lt;/code&gt; and &lt;code&gt;payload&lt;/code&gt;. It's called &lt;code&gt;addUser&lt;/code&gt;. Let's import it and send it to our &lt;code&gt;store&lt;/code&gt;!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../actions/actions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userCount&lt;/span&gt; 
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mapDispatchToProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;addUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;DisplayUsers&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addUser&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mapStateToProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mapDispatchToProps&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;DisplayUsers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There are four changes we made. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we're importing &lt;code&gt;actions&lt;/code&gt;, as we defined above. &lt;/li&gt;
&lt;li&gt;we're adding a property to the object returned by &lt;code&gt;mapDispatchToProps&lt;/code&gt;, which is a function that takes in something called &lt;code&gt;dispatch&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mapDispatchToProps&lt;/code&gt; returns an object whose properties and methods will be made available on our &lt;code&gt;this.props&lt;/code&gt; by virtue of the next thing:&lt;/li&gt;
&lt;li&gt;We use &lt;code&gt;connect&lt;/code&gt; to make the properties on &lt;code&gt;mapStateToProps&lt;/code&gt; and the methods on &lt;code&gt;mapDispatchToProps&lt;/code&gt; available on our &lt;code&gt;this.props&lt;/code&gt; by running a function on all of those things and exporting the results.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;dispatch&lt;/code&gt; and &lt;code&gt;store&lt;/code&gt; are provided by Redux, by virtue of the &lt;code&gt;connect&lt;/code&gt; method we're importing from it. &lt;code&gt;dispatch&lt;/code&gt; ultimately accepts an &lt;code&gt;action&lt;/code&gt;, but in this case we're using an action creator to generate that action, providing similar benefits to using constant action types.&lt;/p&gt;

&lt;p&gt;Now that we've done all of this, we can finally hit the &lt;code&gt;reducers&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reducers
&lt;/h2&gt;

&lt;p&gt;In our implementation of Redux, we'll have an &lt;code&gt;index.js&lt;/code&gt; file that will serve as an entrypoint for our reducers- that is, we'll import all of our reducers to &lt;code&gt;index&lt;/code&gt; and have redux decide which ones to use. We'll also have a &lt;code&gt;usersReducer.js&lt;/code&gt; where we'll write our functionality.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;index.js&lt;/code&gt; will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;combineReducers&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;usersReducer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./usersReducer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reducers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;combineReducers&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;usersReducer&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;reducers&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;First, a note about the key name of &lt;code&gt;users&lt;/code&gt; that we're using to store &lt;code&gt;usersReducer&lt;/code&gt;. If you look at our &lt;code&gt;mapStateToProps&lt;/code&gt;, we're grabbing &lt;code&gt;store.users.userCount&lt;/code&gt;. This is why/how we shape our &lt;code&gt;store&lt;/code&gt;, which is just an object that holds objects that hold the state associated with their respective reducer.&lt;/p&gt;

&lt;p&gt;So, what does our &lt;code&gt;usersReducer&lt;/code&gt; look like?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;usersReducer&lt;/code&gt; should be a function that takes in two parameters, one of which is the &lt;code&gt;state&lt;/code&gt; contained by our &lt;code&gt;store&lt;/code&gt;, and the other of which is an &lt;code&gt;action&lt;/code&gt; (such as the ones we've created with our action creators and dispatched to the store by virtue of our &lt;code&gt;dispatch&lt;/code&gt;). The body of our &lt;code&gt;usersReducer&lt;/code&gt; should essentially be a big switch statement that returns an object, which will comprise the new &lt;code&gt;state&lt;/code&gt; of our &lt;code&gt;store&lt;/code&gt;, thus completing the process.&lt;/p&gt;

&lt;p&gt;Let's write our &lt;code&gt;usersReducer&lt;/code&gt;. We'll create some initial state, and have our function fall back to returning it if nothing happens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;types&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../constants/actionTypes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;userCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;usersReducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;type&lt;/code&gt; of an &lt;code&gt;action&lt;/code&gt; will determine what part of the &lt;code&gt;switch&lt;/code&gt; gets fired off. Let's add a case for when we receive &lt;code&gt;ADD_USER&lt;/code&gt; as our &lt;code&gt;type&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;types&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../constants/actionTypes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;userCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;usersReducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ADD_USER&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userCount&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;userCount&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;let's break down what we did here.&lt;/p&gt;

&lt;p&gt;First, we're creating a &lt;code&gt;const&lt;/code&gt; for &lt;code&gt;userCount&lt;/code&gt;. We're doing this to keep our code organized, which is more of a factor when we're trying to create a new &lt;code&gt;state&lt;/code&gt; that has multiple properties that differ from the old one. Next, we're simply returning a new object that spreads our previous state, then overwrites the old value of &lt;code&gt;userCount&lt;/code&gt; with a new one.&lt;/p&gt;

&lt;p&gt;We do this partially to merge our old &lt;code&gt;state&lt;/code&gt; into our new &lt;code&gt;state&lt;/code&gt;, and partially so that we generate an entirely new &lt;code&gt;state&lt;/code&gt; object. In generating a new &lt;code&gt;state&lt;/code&gt; object, we ensure that React recognizes that we've changed our &lt;code&gt;state&lt;/code&gt; and appropriately rerenders its components. (If you need more info on why we do this, I'll write a bit about primitive vs composite data types in JS and link here later)&lt;/p&gt;

&lt;p&gt;Anyways, now that we've handled our &lt;code&gt;reducer&lt;/code&gt;, that's the end of the whole Redux cycle. We've written to our &lt;code&gt;store&lt;/code&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's walk it through
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;a user clicks "add user"&lt;/li&gt;
&lt;li&gt;"add user" fires off a version of &lt;code&gt;addUser&lt;/code&gt; which has had &lt;code&gt;dispatch&lt;/code&gt; mapped to it by &lt;code&gt;mapDispatchToProps&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;addUser&lt;/code&gt; takes in the &lt;code&gt;action&lt;/code&gt; returned by our &lt;code&gt;ADD_USER&lt;/code&gt; action creator and triggers our &lt;code&gt;reducers&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;our &lt;code&gt;reducers&lt;/code&gt; find a matching &lt;code&gt;case&lt;/code&gt; for &lt;code&gt;ADD_USER&lt;/code&gt;, then generates a new &lt;code&gt;state&lt;/code&gt; object.&lt;/li&gt;
&lt;li&gt;the new &lt;code&gt;state&lt;/code&gt; object gets passed back to our frontend components by &lt;code&gt;mapStateToProps&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And that's the flow of this particular Redux implementations. There are plenty of other ways to do it, and the value of it is only really seen at scale. Thanks for following along!&lt;/p&gt;

</description>
      <category>redux</category>
      <category>react</category>
      <category>reactredux</category>
      <category>state</category>
    </item>
    <item>
      <title>NAND2Tetris: The Magic of NAND</title>
      <dc:creator>mari tang</dc:creator>
      <pubDate>Wed, 22 May 2019 06:31:41 +0000</pubDate>
      <link>https://forem.com/tttaaannnggg/nand2tetris-the-magic-of-nand-4lj5</link>
      <guid>https://forem.com/tttaaannnggg/nand2tetris-the-magic-of-nand-4lj5</guid>
      <description>&lt;p&gt;So, I've embarked on the journey of &lt;a href="https://www.nand2tetris.org/"&gt;nand2tetris&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What is nand2tetris? It's basically a vertically-integrated course on computer science. Starting from 0s and 1s, we build up a whole simulated computer, build an operating system on top of it, build a compiler on top of that OS, and finally build a game on that whole tower.&lt;/p&gt;

&lt;p&gt;It's quite a daunting task. How do we get started?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Magic of NAND
&lt;/h2&gt;

&lt;p&gt;In computers (or, at least in the computer that we're implementing), there is a single circuit that we basically use for everything. It's called &lt;code&gt;NAND&lt;/code&gt;. If you're familiar with boolean logic, it's defined something like this: &lt;code&gt;NOT(A AND B))&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The truth table for &lt;code&gt;NAND&lt;/code&gt; looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; A B | OUTPUT
==============
 0 0 |   1
 0 1 |   1
 1 0 |   1
 1 1 |   0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;While this may seem unimpressive, our &lt;code&gt;NAND&lt;/code&gt; gate includes behaviors in it such that we can create literally any other logic gate from some combination of just &lt;code&gt;NAND&lt;/code&gt; gates. We won't be getting into formal proofs, but we'll demonstrate how to build &lt;code&gt;NOT&lt;/code&gt;, &lt;code&gt;AND&lt;/code&gt;, and &lt;code&gt;OR&lt;/code&gt; from just &lt;code&gt;NAND&lt;/code&gt;. (taking &lt;code&gt;NAND&lt;/code&gt; as a given)&lt;/p&gt;

&lt;h2&gt;
  
  
  NOT
&lt;/h2&gt;

&lt;p&gt;We'll start with &lt;code&gt;NOT&lt;/code&gt;, since it's the simplest operation. The secret to &lt;code&gt;NOT&lt;/code&gt; has to do with a property of &lt;code&gt;AND&lt;/code&gt;. Anything &lt;code&gt;AND&lt;/code&gt; itself simply outputs itself. Have a look: &lt;code&gt;0 AND 0&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt;, and &lt;code&gt;1 AND 1&lt;/code&gt; is &lt;code&gt;1&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;If we consider &lt;code&gt;NAND&lt;/code&gt; to be a combination of &lt;code&gt;NOT&lt;/code&gt; and &lt;code&gt;AND&lt;/code&gt;, a value &lt;code&gt;NAND&lt;/code&gt; itself will cancel out the &lt;code&gt;AND&lt;/code&gt;, leaving the &lt;code&gt;NOT&lt;/code&gt; operation. If we refer back to our truth table, &lt;code&gt;0 NAND 0&lt;/code&gt; is &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;1 NAND 1&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt;. So, &lt;code&gt;NOT A&lt;/code&gt; is &lt;code&gt;A NAND A&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here's roughly what the logic gates look like. I'll represent &lt;code&gt;NAND&lt;/code&gt; as a box with &lt;code&gt;N&lt;/code&gt; written on it. If we've only got one input, we'll assume that it's hooked up to both inputs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W_iyRgBP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/adl8mn3i7ec25c0ae4pa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W_iyRgBP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/adl8mn3i7ec25c0ae4pa.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  AND
&lt;/h2&gt;

&lt;p&gt;Now that we've got a &lt;code&gt;NOT&lt;/code&gt;, it's pretty easy to get to &lt;code&gt;AND&lt;/code&gt;, for fairly self-evident reasons. A &lt;code&gt;NOT&lt;/code&gt; inverts a value, so &lt;code&gt;NOT&lt;/code&gt;ing a &lt;code&gt;NOT&lt;/code&gt; will cancel out the &lt;code&gt;NOT&lt;/code&gt;, leaving the original value. &lt;code&gt;~~0&lt;/code&gt; outputs &lt;code&gt;0&lt;/code&gt;, and &lt;code&gt;~~1&lt;/code&gt; outputs &lt;code&gt;1&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;NAND&lt;/code&gt; is &lt;code&gt;NOT&lt;/code&gt; applied to the result of an &lt;code&gt;AND&lt;/code&gt;, so if we cancel out the &lt;code&gt;NOT&lt;/code&gt;, we're left with the &lt;code&gt;AND&lt;/code&gt; operation. We've already built a &lt;code&gt;NOT&lt;/code&gt;, and can simply add it to the output of our &lt;code&gt;NAND&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The operation looks like this: &lt;code&gt;(A NAND B) NAND (A NAND B)&lt;/code&gt;, but it's easier to draw a diagram.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JOZkvfL4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vznifwgz881bjzfym4p0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JOZkvfL4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vznifwgz881bjzfym4p0.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we have &lt;code&gt;AND&lt;/code&gt; and &lt;code&gt;NOT&lt;/code&gt;, it won't be too hard to derive &lt;code&gt;OR&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  OR
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;OR&lt;/code&gt; can be built through DeMorgan's law, which I've been lucky enough to &lt;a href="https://dev.to/tttaaannnggg/a-couple-of-beautiful-things-i-learned-today-3864"&gt;derive myself&lt;/a&gt; a few months ago. Basically, we can represent &lt;code&gt;A OR B&lt;/code&gt; as &lt;code&gt;NOT ( NOT(A) AND NOT(B))&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;if our &lt;code&gt;NOT&lt;/code&gt; is &lt;code&gt;A NAND A&lt;/code&gt; and our &lt;code&gt;AND&lt;/code&gt; is made up of &lt;code&gt;(A NAND B) NAND (A NAND B)&lt;/code&gt;, we actually have enough to build an &lt;code&gt;OR&lt;/code&gt; by substituting them in for their relevant terms.&lt;/p&gt;

&lt;p&gt;This will be a mess to start, but we'll simplify it.&lt;/p&gt;

&lt;p&gt;First, let's replace our &lt;code&gt;NOT&lt;/code&gt;s, since they're simplest to do. &lt;code&gt;NOT(A)&lt;/code&gt; is &lt;code&gt;A NAND A&lt;/code&gt; and &lt;code&gt;NOT(B)&lt;/code&gt; is &lt;code&gt;B NAND B&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NOT( (A NAND A) AND (B NAND B) )&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The overall &lt;code&gt;NOT&lt;/code&gt; will take its term &lt;code&gt;(A NAND A) AND (B NAND B)&lt;/code&gt; and &lt;code&gt;NAND&lt;/code&gt; it with itself as both inputs. It'll come out like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;((A NAND A) AND (B NAND B)) NAND ((A NAND A) AND (B NAND B))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, &lt;code&gt;AND&lt;/code&gt; translates as follows: &lt;code&gt;A AND B&lt;/code&gt; = &lt;code&gt;(A NAND B) NAND (A NAND B)&lt;/code&gt;. If we make our substitution where &lt;code&gt;A&lt;/code&gt; = &lt;code&gt;(A NAND B)&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; = &lt;code&gt;(B NAND B)&lt;/code&gt;, this happens:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(((A NAND A) NAND (B NAND B)) NAND ((A NAND A) NAND (B NAND B))) NAND (((A NAND A) NAND (B NAND B)) NAND ((A NAND A) NAND (B NAND B)))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Which is, of course, completely unreadable. Let's represent it visually instead.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q9DVYmud--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1epcqm2ixb58s9htmzn3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q9DVYmud--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1epcqm2ixb58s9htmzn3.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is difficult to see in the written version of this logic gate implementation, but our last two &lt;code&gt;NAND&lt;/code&gt;s are simply acting as &lt;code&gt;NOT&lt;/code&gt; operators, flipping our output value, then flipping it back. We can simplify our logic gate by removing them, since &lt;code&gt;~~A&lt;/code&gt; is just &lt;code&gt;A&lt;/code&gt;, no matter the value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5Nhv3jGz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/sqzpe9gwsvd30zqcnwn5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5Nhv3jGz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/sqzpe9gwsvd30zqcnwn5.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, if we walk backwards from our diagram, we can translate it back into a statement.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(A NAND A) NAND (B NAND B)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Not so bad.&lt;/p&gt;

&lt;p&gt;We'll be building more complex systems in the future, but this is certainly a start!&lt;/p&gt;

</description>
      <category>nand2tetris</category>
      <category>booleanalgebra</category>
      <category>logic</category>
    </item>
    <item>
      <title>Logic Gates: The Controlled Not</title>
      <dc:creator>mari tang</dc:creator>
      <pubDate>Tue, 21 May 2019 06:56:04 +0000</pubDate>
      <link>https://forem.com/tttaaannnggg/logic-gates-the-controlled-not-417a</link>
      <guid>https://forem.com/tttaaannnggg/logic-gates-the-controlled-not-417a</guid>
      <description>&lt;p&gt;Tonight, my brother told me the story of a particular logic gate, the &lt;strong&gt;Controlled Not&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Controlled Not&lt;/strong&gt; is a gate that takes two inputs. If the first input is 0, the second input is unaffected, and sent as our output. If the first input is 1, we invert the second input before sending it as our output.&lt;/p&gt;

&lt;p&gt;Pretty neat, huh? Maybe take a minute to think about how to implement it from basic logic gates (not/and/or).&lt;/p&gt;

&lt;p&gt;I've had this spoiled for me, but here's my solution.&lt;/p&gt;

&lt;p&gt;Previously, I've created a multiplexer. A multiplexer can be described as follows: there are three inputs, a,b, and S. S is a selector, which determines whether we output A or B. If S is 1, we output A. If S is 0, we output B.&lt;/p&gt;

&lt;p&gt;It's represented as &lt;code&gt;(A*S)+(B*~S)&lt;/code&gt; and looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjj6cfhv4x39vnyiecq6y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjj6cfhv4x39vnyiecq6y.png" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adapting it to our use case is pretty simple. We just need to replace A and B with A and ~A. When S is true (when our controller is on), we want to flip our A, so we'll represent that operation as &lt;code&gt;(~A*S)&lt;/code&gt;. When S is false, we want to output our A unchanged, which means that we should slot it in for what used to be our B. This looks like this: &lt;code&gt;(A*~S)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;All together, we get &lt;code&gt;(~A*S)+(A*~S)&lt;/code&gt;, or in plainer terms, &lt;code&gt;(NOT(A) AND S) OR(A AND NOT(S))&lt;/code&gt;. It looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvi37etpvx2jrdkcpash.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvi37etpvx2jrdkcpash.png" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice anything? If not, we'll do a quick truth table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A S | OUTPUT
------------
0 0 |   0
0 1 |   1
1 0 |   1
1 1 |   0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've got a name for this, and it's XOR.&lt;/p&gt;

&lt;p&gt;Our takeaway is this: Even at the lowest, simplest level that we can use to try to make truth claims about the world around us- even when we've reduced everything to a collection of 1s and 0s that behave in 100% predictable ways, we're still constructing narratives around our data, still affected by the way that we choose to frame behavior, problems, solutions.&lt;/p&gt;

&lt;p&gt;So, step back. Think about your assumptions. Think about the stories you choose to tell about your software. They matter.&lt;/p&gt;

</description>
      <category>boolean</category>
      <category>logic</category>
      <category>algorithms</category>
      <category>puzzle</category>
    </item>
  </channel>
</rss>
