<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Data-Structures-and-Algorithms on Andrew Quinn&#39;s TILs</title>
    <link>https://til.andrew-quinn.me/tags/data-structures-and-algorithms/</link>
    <description>Recent content in Data-Structures-and-Algorithms on Andrew Quinn&#39;s TILs</description>
    <image>
      <title>Andrew Quinn&#39;s TILs</title>
      <url>https://til.andrew-quinn.me/papermod-cover.png</url>
      <link>https://til.andrew-quinn.me/papermod-cover.png</link>
    </image>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Sun, 10 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://til.andrew-quinn.me/tags/data-structures-and-algorithms/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Replacing a 3 GB SQLite database with a 10 MB FST (finite state transducer) binary</title>
      <link>https://til.andrew-quinn.me/posts/replacing-a-3-gb-sqlite-database-with-a-7-mb-fst-finite-state-trandsucer-binary/</link>
      <pubDate>Sun, 10 May 2026 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/replacing-a-3-gb-sqlite-database-with-a-7-mb-fst-finite-state-trandsucer-binary/</guid>
      <description>&lt;p&gt;&lt;em&gt;Note for
&lt;a href=&#34;https://www.youtube.com/watch?v=aOJOfh2_4PE&#34;&gt;numberphiles&lt;/a&gt;:
all numbers have been rounded to their first significant
digit, because I&amp;rsquo;m a fan of Rob Eastaway&amp;rsquo;s
&lt;a href=&#34;https://robeastaway.com/blog/introducing-zequals&#34;&gt;&amp;ldquo;zequals&amp;rdquo; method&lt;/a&gt;
of getting to the point when it comes to estimation. It&amp;rsquo;s much
more valuable to walk away with the heuristic &amp;ldquo;some dude got
a 300x memory reduction by swapping out a database he hacked
together for a tiny, static, specialized data structure that
does exactly what he needs it to and no more.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Binary search isn&#39;t about search III. Loop invariant of rightmost element search</title>
      <link>https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search-iii-loop-invariant-of-rightmost-element-search/</link>
      <pubDate>Sun, 09 Mar 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search-iii-loop-invariant-of-rightmost-element-search/</guid>
      <description>&lt;p&gt;If you followed
&lt;a href=&#34;https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search/&#34;&gt;&amp;ldquo;Binary search isn&amp;rsquo;t about search&amp;rdquo;&lt;/a&gt;
and
&lt;a href=&#34;https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search-ii-loop-invariant-of-leftmost-element-search/&#34;&gt;&amp;ldquo;Binary search isn&amp;rsquo;t about search II&amp;rdquo;&lt;/a&gt;
properly, the following statements should suffice as a summary:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-1&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-1&#34;&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-2&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-2&#34;&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;L[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;:l] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; T &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; L[r:len(L)]    &lt;span style=&#34;color:#75715e&#34;&gt;# ordinary binary search loop invariant&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;L[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;:l] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; T &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; L[r:len(L)]   &lt;span style=&#34;color:#75715e&#34;&gt;# leftwise binary search loop invariant&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s complete the triptych. Take a wild guess what invariant we use for &lt;em&gt;rightmost&lt;/em&gt; element binary search:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-1-1&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-1-1&#34;&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;L[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;:l] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; T &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; L[r:len(L)]   &lt;span style=&#34;color:#75715e&#34;&gt;# rightwise binary search loop invariant&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;a-motivating-example&#34;&gt;A motivating example&lt;/h2&gt;
&lt;p&gt;Consider again an array like&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Binary search isn&#39;t about search II. Loop invariant of leftmost element search</title>
      <link>https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search-ii-loop-invariant-of-leftmost-element-search/</link>
      <pubDate>Sat, 08 Mar 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search-ii-loop-invariant-of-leftmost-element-search/</guid>
      <description>&lt;p&gt;In the first
&lt;a href=&#34;https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search/&#34;&gt;&amp;ldquo;Binary search isn&amp;rsquo;t about search&amp;rdquo;&lt;/a&gt;
post, we spoke about
&lt;a href=&#34;https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search/#hl-2-5&#34;&gt;using &lt;code&gt;assert&lt;/code&gt; statements to enforce your loop invariants&lt;/a&gt;.
Our plain old everyday binary search invariant can be summarized as such:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;For all x in &lt;code&gt;L[0:l]&lt;/code&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, x is &lt;em&gt;strictly&lt;/em&gt; less than &lt;code&gt;T&lt;/code&gt;, the element we are searching for.&lt;/li&gt;
&lt;li&gt;For all y in &lt;code&gt;L[r:len(L)]&lt;/code&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, y is &lt;em&gt;strictly&lt;/em&gt; greater than &lt;code&gt;T&lt;/code&gt;, the element we are searching for.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Or, if we want to be even terser, we could note this as simply&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Binary search isn&#39;t about search</title>
      <link>https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search/</link>
      <pubDate>Fri, 07 Mar 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search/</guid>
      <description>&lt;p&gt;Suppose you&amp;rsquo;re trying to track down a bug that appeared in a series of Git commits.
You&amp;rsquo;ve been idly keeping track of where this bug appears in your
&lt;a href=&#34;https://github.com/not-an-aardvark/lucky-commit&#34;&gt;lucky&lt;/a&gt;
commits by hand, while busy with other things. So far you&amp;rsquo;ve compiled this table:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-1&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-1&#34;&gt; 1&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-2&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-2&#34;&gt; 2&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-3&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-3&#34;&gt; 3&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-4&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-4&#34;&gt; 4&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-5&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-5&#34;&gt; 5&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-6&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-6&#34;&gt; 6&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-7&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-7&#34;&gt; 7&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-8&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-8&#34;&gt; 8&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-9&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-9&#34;&gt; 9&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-10&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-10&#34;&gt;10&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000000    🧼 clean, no bug.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000001    🧼
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000002    🧼
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000003    🧼
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000004    🧼
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000005    🧼
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000006    🐛 bug first appears here.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000007    🐛
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000008    🐛
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000009    🤔 bug mysteriously disappears...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Then an EMP explodes in your vicinity and scrambles your memory circuits. The Internet
is down, you don&amp;rsquo;t have the
&lt;a href=&#34;https://git-scm.com/docs/git-bisect&#34;&gt;git-bisect man pages&lt;/a&gt;
downloaded locally, and all you remember is that your first commit was good, your last
commit was good but for reasons you don&amp;rsquo;t understand, and &lt;em&gt;something&lt;/em&gt; bad is probably
still lurking in there. But where?&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>
