<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Adam Gluck's Blog</title>
    <description>I write about things that I find useful or cool</description>
    <link>https://adamgluck.com</link>
    <atom:link href="https://adamgluck.com/posts/rss.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sun, 31 Aug 2025 00:00:00 GMT</pubDate>
    <lastBuildDate>Fri, 03 Apr 2026 22:17:49 GMT</lastBuildDate>
    <generator>Next.js Static Blog</generator>
    <item>
      <title>The Great Elephant Race</title>
      <description>A fun riddle about elephants (and sets)</description>
      <pubDate>Sun, 31 Aug 2025 00:00:00 GMT</pubDate>
      <link>https://adamgluck.com/posts/elephant_race</link>
      <guid isPermaLink="true">https://adamgluck.com/posts/elephant_race</guid>
      <content:encoded><![CDATA[<p><img src="/elephant_race/cover.png" alt="Blog Cover"></p>
<h2 id="background"><a href="#background">Background</a></h2>
<p>While at work last week, my coworker gave me an interesting riddle. After working through it myself and giving it to some friends, I decided to make a little write up on the riddle and its solutions.</p>
<h2 id="the-riddle"><a href="#the-riddle">The Riddle</a></h2>
<p>There are 900 elephants in a race. Bob and Charlie know which elephants are in 1st and 2nd place.</p>
<p>You are allowed to ask Bob a question about the race that he will respond to with a number from 1 to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span>. After that Charlie will give you the number of either the 1st or 2nd place elephant.</p>
<p>You have to use Bob's answer to determine whether Charlie's number is the 1st or 2nd place elephant.</p>
<p><strong>What is the lowest upper bound of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> Bob can give you so that you can determine if the elephant Charlie gave you finished in 1st or 2nd?</strong></p>
<h3 id="clarifications"><a href="#clarifications">Clarifications</a></h3>
<h4 id="can-you-ask-bob-which-elephant-got-first-place"><a href="#can-you-ask-bob-which-elephant-got-first-place">Can you ask Bob which elephant got first place?</a></h4>
<p>Yes, if you ask Bob who got first place, you can use his answer to determine whether the elephant Charlie gives placed 1st or 2nd.
However the upper bound for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> in this case is 900 (there are better answers).</p>
<h4 id="can-bob-answer-with-fractions-or-decimals"><a href="#can-bob-answer-with-fractions-or-decimals">Can Bob answer with fractions or decimals?</a></h4>
<p>No, he must either answer with whole numbers or have the ability to map his possible answers to whole numbers.</p>
<h4 id="can-you-ask-bob-multiple-questions"><a href="#can-you-ask-bob-multiple-questions">Can you ask Bob multiple questions?</a></h4>
<p>You can make the question you ask Bob as long as you want. However, Bob is only allowed to answer with a single number.
You are allowed to make each digit depend on a sub-question, but then the lowest upper bound would be the range of possibilities
that Bob would answer with.</p>
<p>For example, you could ask Bob 2 yes or no questions and have him answer with a 2 digit number (1 digit per question) where 1 means yes and 2 means no. Since there would be 4 possible answers Bob could give (11,12,21,22), the upper bound for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> would be 4.</p>
<h4 id="this-sounds-like-a-math-problem"><a href="#this-sounds-like-a-math-problem">This Sounds Like a Math Problem?</a></h4>
<p>What problem isn't a math problem! Here's a version of the riddle formatted as a math question:</p>
<ul>
<li>Let <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>A</mi></mrow><annotation encoding="application/x-tex">A</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal">A</span></span></span></span> = The set of answers Bob can give</li>
<li>Let <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>E</mi></mrow><annotation encoding="application/x-tex">E</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.05764em;">E</span></span></span></span> = The set of unique elephants in the race</li>
<li>Let <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="script">F</mi><mo>=</mo><mo stretchy="false">{</mo><mi>f</mi><mo>:</mo><mi>E</mi><mo>×</mo><mi>E</mi><mo>×</mo><mi>A</mi><mo>→</mo><mo stretchy="false">{</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">}</mo><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">\mathcal{F} = \{f : E \times E \times A \to \{0,1\}\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathcal" style="margin-right:0.09931em;">F</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.7667em;vertical-align:-0.0833em;"></span><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.7667em;vertical-align:-0.0833em;"></span><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">→</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">1</span><span class="mclose">}}</span></span></span></span> be the set of questions you can ask Bob where:
<ul>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mtext>🐘</mtext><mi>a</mi></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mi>b</mi></msub><mo separator="true">,</mo><mtext>ans</mtext><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">f(\text{🐘}_a, \text{🐘}_b, \text{ans}) = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">a</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">b</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord text"><span class="mord">ans</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span> if elephants <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mi>a</mi></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.3014em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">a</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mi>b</mi></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4861em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">b</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> can be distinguished using Bob's answer <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>ans</mtext></mrow><annotation encoding="application/x-tex">\text{ans}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord text"><span class="mord">ans</span></span></span></span></span></li>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mtext>🐘</mtext><mi>a</mi></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mi>b</mi></msub><mo separator="true">,</mo><mtext>ans</mtext><mo stretchy="false">)</mo><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">f(\text{🐘}_a, \text{🐘}_b, \text{ans}) = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">a</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">b</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord text"><span class="mord">ans</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span></span></span></span> otherwise</li>
</ul>
</li>
</ul>
<p><strong>Find the minimum possible <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">∣</mi><mi>A</mi><mi mathvariant="normal">∣</mi></mrow><annotation encoding="application/x-tex">|A|</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">∣</span><span class="mord mathnormal">A</span><span class="mord">∣</span></span></span></span> such that:</strong></p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mi mathvariant="normal">∀</mi><msub><mtext>🐘</mtext><mi>a</mi></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mi>b</mi></msub><mo>∈</mo><mi>E</mi><mo separator="true">,</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mi mathvariant="normal">∃</mi><mtext>ans</mtext><mo>∈</mo><mi>A</mi><mo separator="true">,</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mi mathvariant="normal">∃</mi><mi>f</mi><mo>∈</mo><mi mathvariant="script">F</mi><mo>:</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo stretchy="false">(</mo><msub><mtext>🐘</mtext><mi>a</mi></msub><mo>=</mo><msub><mtext>🐘</mtext><mi>b</mi></msub><mo stretchy="false">)</mo><mtext>  </mtext><mo>⟹</mo><mtext>  </mtext><mo stretchy="false">(</mo><mi>f</mi><mo stretchy="false">(</mo><msub><mtext>🐘</mtext><mi>a</mi></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mi>b</mi></msub><mo separator="true">,</mo><mtext>ans</mtext><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align*}
&#x26;\forall \text{🐘}_a, \text{🐘}_b \in E, \\
&#x26;\exists \text{ans} \in A, \\
&#x26;\exists f \in \mathcal{F} : \\
&#x26;(\text{🐘}_a = \text{🐘}_b) \implies (f(\text{🐘}_a, \text{🐘}_b, \text{ans}) = 1)
\end{align*}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:6em;vertical-align:-2.75em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.25em;"><span style="top:-5.25em;"><span class="pstrut" style="height:2.84em;"></span><span class="mord"></span></span><span style="top:-3.75em;"><span class="pstrut" style="height:2.84em;"></span><span class="mord"></span></span><span style="top:-2.25em;"><span class="pstrut" style="height:2.84em;"></span><span class="mord"></span></span><span style="top:-0.75em;"><span class="pstrut" style="height:2.84em;"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.75em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.25em;"><span style="top:-5.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mord">∀</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">a</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">b</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="mpunct">,</span></span></span><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mord">∃</span><span class="mord text"><span class="mord">ans</span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mord mathnormal">A</span><span class="mpunct">,</span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mord">∃</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mord mathcal" style="margin-right:0.09931em;">F</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span></span></span><span style="top:-0.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mopen">(</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">a</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">b</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">⟹</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">a</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">b</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord text"><span class="mord">ans</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.75em;"><span></span></span></span></span></span></span></span></span></span></span></span>
<h4 id="can-bob-tell-the-future"><a href="#can-bob-tell-the-future">Can Bob tell the future?</a></h4>
<p>A peculiar individual asked me this question to which I answered yes out of curiosity. He then answered: "I would ask Bob to say 1 if Charlie is going to say the 1st place elephant, and 2 if Charlie says the 2nd place elephant". I have not seen a solution with a lower bound than this.</p>
<h2 id="the-intuitive-solution"><a href="#the-intuitive-solution">The Intuitive Solution</a></h2>
<p>A non-optimal but still efficient way of solving this problem is as follows:</p>
<ol>
<li><strong>Have Bob tell you a position of the first digit in the 1st place elephant that is different in the 2nd place elephant.</strong>
<ul>
<li>He will say 1 if it's the ones digit, 2 if it's the tens digit, and 3 if it's the hundreds digit.</li>
</ul>
</li>
<li><strong>Have Bob tell you what the value of that digit is for the 1st place elephant.</strong>
<ul>
<li>He will answer this as a number from 0-9.</li>
</ul>
</li>
<li><strong>Have Bob combine the 2 numbers as his answer</strong></li>
</ol>
<p>Since there are 30 possible answers Bob can give (3 max digits <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>×</mo></mrow><annotation encoding="application/x-tex">\times</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6667em;vertical-align:-0.0833em;"></span><span class="mord">×</span></span></span></span> 10 possible values), the lowest upper bound that Bob can give you is <strong><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>30</mn></mrow><annotation encoding="application/x-tex">n = 30</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">30</span></span></span></span></strong>.</p>
<h3 id="example-of-the-solution"><a href="#example-of-the-solution">Example of the Solution</a></h3>
<ul>
<li>Let the 1st place elephant be <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>45</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{45}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">45</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> and the 2nd place elephant be <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>149</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{149}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">149</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></li>
<li>Bob will answer "15" since the ones digit is "5" in the 1st place elephant and "9" in the 2nd place elephant</li>
<li>There are 2 numbers that Charlie can give you:
<ul>
<li>If Charlie gives you the 1st place elephant (<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>45</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{45}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">45</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>), you can see that the ones place digit is "5". Since you know the 1st place elephant has this characteristic and the 2nd place elephant doesn't, this must be the 1st place elephant.</li>
<li>If Charlie gives you the 2nd place elephant (<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>149</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{149}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">149</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>), you can see that the ones place digit is "9". Since you know the 1st place has a "5" in the ones place, this must be the 2nd place elephant.</li>
</ul>
</li>
</ul>
<h3 id="optimizations"><a href="#optimizations">Optimizations</a></h3>
<p>The intuitive solution assumes a base 10 number system. Surprisingly, different number systems like Base 12 and Base 7 will give different answers. Below is a more general approach that accounts for different bases:</p>
<ol>
<li>Let <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi></mrow><annotation encoding="application/x-tex">B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span> be the base of the chosen number system (decimal, binary, etc.)</li>
<li>Determine the maximum number of digits needed to represent 900
<ul>
<li>We'll refer to this as <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span></li>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi><mo>=</mo><mo stretchy="false">⌈</mo><msub><mrow><mi>log</mi><mo>⁡</mo></mrow><mi>B</mi></msub><mo stretchy="false">(</mo><mn>900</mn><mo stretchy="false">)</mo><mo stretchy="false">⌉</mo></mrow><annotation encoding="application/x-tex">D = \lceil \log_B(900) \rceil</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">⌈</span><span class="mop"><span class="mop">lo<span style="margin-right:0.01389em;">g</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.2342em;"><span style="top:-2.4559em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05017em;">B</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2441em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord">900</span><span class="mclose">)⌉</span></span></span></span></li>
</ul>
</li>
<li>Have Bob return position of digit along with value
<ul>
<li>Bob will answer in format <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>d</mi><mo separator="true">,</mo><mi>v</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(d, v)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">d</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mclose">)</span></span></span></span> where <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>d</mi><mo>∈</mo><mo stretchy="false">[</mo><mn>1</mn><mo separator="true">,</mo><mi>D</mi><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">d \in [1, D]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7335em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mclose">]</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>v</mi><mo>∈</mo><mo stretchy="false">[</mo><mn>0</mn><mo separator="true">,</mo><mi>B</mi><mo>−</mo><mn>1</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">v \in [0, B-1]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">]</span></span></span></span>
<ul>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>d</mi></mrow><annotation encoding="application/x-tex">d</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">d</span></span></span></span> represents the digit position (1st, 2nd, 3rd, etc.)</li>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>v</mi></mrow><annotation encoding="application/x-tex">v</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span></span></span></span> represents the digit value in base <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi></mrow><annotation encoding="application/x-tex">B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span></li>
</ul>
</li>
</ul>
</li>
</ol>
<p>In this solution, the minimum upper bound of answers will be <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mi>D</mi><mo>×</mo><mi>B</mi></mrow><annotation encoding="application/x-tex">n = D \times B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.7667em;vertical-align:-0.0833em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span>. However, since we know that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi><mo>=</mo><mo stretchy="false">⌈</mo><msub><mrow><mi>log</mi><mo>⁡</mo></mrow><mi>B</mi></msub><mo stretchy="false">(</mo><mn>900</mn><mo stretchy="false">)</mo><mo stretchy="false">⌉</mo></mrow><annotation encoding="application/x-tex">D = \lceil \log_B(900) \rceil</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">⌈</span><span class="mop"><span class="mop">lo<span style="margin-right:0.01389em;">g</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.2342em;"><span style="top:-2.4559em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05017em;">B</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2441em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord">900</span><span class="mclose">)⌉</span></span></span></span>, we can simplify the upper bound to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mo stretchy="false">⌈</mo><msub><mrow><mi>log</mi><mo>⁡</mo></mrow><mi>B</mi></msub><mo stretchy="false">(</mo><mn>900</mn><mo stretchy="false">)</mo><mo stretchy="false">⌉</mo><mo>×</mo><mi>B</mi></mrow><annotation encoding="application/x-tex">n = \lceil \log_B(900) \rceil \times B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">⌈</span><span class="mop"><span class="mop">lo<span style="margin-right:0.01389em;">g</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.2342em;"><span style="top:-2.4559em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05017em;">B</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2441em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord">900</span><span class="mclose">)⌉</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span>. Below are some example bases and their respective results:</p>
<table>
<thead>
<tr>
<th align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi></mrow><annotation encoding="application/x-tex">B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span> (Base)</th>
<th align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">⌈</mo><msub><mrow><mi>log</mi><mo>⁡</mo></mrow><mi>B</mi></msub><mo stretchy="false">(</mo><mn>900</mn><mo stretchy="false">)</mo><mo stretchy="false">⌉</mo></mrow><annotation encoding="application/x-tex">\lceil \log_B(900) \rceil</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">⌈</span><span class="mop"><span class="mop">lo<span style="margin-right:0.01389em;">g</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.2342em;"><span style="top:-2.4559em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05017em;">B</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2441em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord">900</span><span class="mclose">)⌉</span></span></span></span> (Digits Needed)</th>
<th align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi><mo>×</mo><mi>B</mi></mrow><annotation encoding="application/x-tex">D \times B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7667em;vertical-align:-0.0833em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span> (Min Upper Bound)</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">2</td>
<td align="center">10</td>
<td align="center">20</td>
</tr>
<tr>
<td align="center">3</td>
<td align="center">7</td>
<td align="center">21</td>
</tr>
<tr>
<td align="center">5</td>
<td align="center">4</td>
<td align="center">20</td>
</tr>
<tr>
<td align="center">7</td>
<td align="center">4</td>
<td align="center">28</td>
</tr>
<tr>
<td align="center">9</td>
<td align="center">4</td>
<td align="center">36</td>
</tr>
<tr>
<td align="center">10</td>
<td align="center">3</td>
<td align="center">30</td>
</tr>
<tr>
<td align="center">12</td>
<td align="center">3</td>
<td align="center">36</td>
</tr>
<tr>
<td align="center">30</td>
<td align="center">2</td>
<td align="center">60</td>
</tr>
</tbody>
</table>
<h3 id="whats-going-on-here"><a href="#whats-going-on-here">What's Going on Here?</a></h3>
<p>Why does changing the base of the number system change the minimum upper bound so much? To answer this, let's dive deeper into what's
happening in our solution. When we choose a base for our strategy, we're implicitly creating <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi><mo>×</mo><mi>B</mi></mrow><annotation encoding="application/x-tex">D \times B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7667em;vertical-align:-0.0833em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span> different groupings of elephants.
Each group is defined by fixing a value of a specific digit to a constant value.</p>
<p>Here are the groupings for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi><mo>=</mo><mn>10</mn></mrow><annotation encoding="application/x-tex">B=10</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">10</span></span></span></span> with padded zeros to more clearly show the pattern:</p>
<table>
<thead>
<tr>
<th>Group</th>
<th>Bob's Label</th>
<th align="center">Elephants in Group</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>1</mn></msub></mrow><annotation encoding="application/x-tex">G_{1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></td>
<td>(1,0)</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>000</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{000}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">000</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span><sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref aria-describedby="footnote-label">1</a></sup>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>010</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{010}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">010</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>020</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{020}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">020</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, ..., <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>970</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{970}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">970</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>980</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{980}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">980</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>990</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{990}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">990</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></td>
</tr>
<tr>
<td><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>2</mn></msub></mrow><annotation encoding="application/x-tex">G_{2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></td>
<td>(1,1)</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>001</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{001}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">001</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>011</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{011}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">011</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>021</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{021}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">021</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, ..., <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>971</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{971}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">971</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>981</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{981}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">981</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>991</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{991}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">991</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></td>
</tr>
<tr>
<td><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>3</mn></msub></mrow><annotation encoding="application/x-tex">G_{3}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">3</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></td>
<td>(1,2)</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>002</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{002}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">002</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>012</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{012}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">012</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>022</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{022}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">022</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, ..., <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>972</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{972}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">972</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>982</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{982}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">982</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>992</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{992}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">992</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></td>
</tr>
<tr>
<td>...</td>
<td>...</td>
<td align="center">...</td>
</tr>
<tr>
<td><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>28</mn></msub></mrow><annotation encoding="application/x-tex">G_{28}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">28</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></td>
<td>(3,7)</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>700</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{700}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">700</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>701</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{701}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">701</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>702</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{702}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">702</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, ...,  <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>797</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{797}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">797</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>798</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{798}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">798</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>799</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{799}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">799</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></td>
</tr>
<tr>
<td><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>29</mn></msub></mrow><annotation encoding="application/x-tex">G_{29}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">29</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></td>
<td>(3,8)</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>800</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{800}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">800</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>801</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{801}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">801</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>802</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{802}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">802</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, ..., <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>897</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{897}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">897</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>898</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{898}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">898</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>899</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{899}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">899</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></td>
</tr>
<tr>
<td><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>30</mn></msub></mrow><annotation encoding="application/x-tex">G_{30}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">30</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></td>
<td>(3,9)</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>900</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{900}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">900</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>901</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{901}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">901</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>902</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{902}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">902</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, ..., <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>997</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{997}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">997</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>998</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{998}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">998</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>999</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{999}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">999</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span><sup><a href="#user-content-fn-1" id="user-content-fnref-1-2" data-footnote-ref aria-describedby="footnote-label">1</a></sup></td>
</tr>
</tbody>
</table>
<p>Since there are 2 digits unconstrained in each group, there are <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mn>10</mn><mn>2</mn></msup><mo>=</mo><mn>100</mn></mrow><annotation encoding="application/x-tex">10^2=100</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">100</span></span></span></span> elements per group<sup><a href="#user-content-fn-1" id="user-content-fnref-1-3" data-footnote-ref aria-describedby="footnote-label">1</a></sup>. This means the total number of elephants
including duplicates is <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>30</mn><mo>×</mo><mn>100</mn><mo>=</mo><mn>3000</mn></mrow><annotation encoding="application/x-tex">30 \times 100 = 3000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7278em;vertical-align:-0.0833em;"></span><span class="mord">30</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">100</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">3000</span></span></span></span>, meaning each elephant appears in exactly 3 groups <sup><a href="#user-content-fn-1" id="user-content-fnref-1-4" data-footnote-ref aria-describedby="footnote-label">1</a></sup>.</p>
<h3 id="using-the-groups"><a href="#using-the-groups">Using the Groups</a></h3>
<p>Now let's explore why this way of grouping elephants helps Bob answer our question. When we ask Bob to tell us which digit is different
and the value it should be, we're essentially asking Bob to tell us which of the above groups contains the 1st place elephant but not the 2nd place elephant. Once Bob gives us a group, we just check if the elephant Charlie gives us is in that group. If it's in the group, Charlie gave us the 1st place elephant. Otherwise we know it's the 2nd place elephant.</p>
<p>We know that there is guaranteed to be a group that contains 1st place but not 2nd place because of two reasons:</p>
<ol>
<li>The 1st and 2nd place elephants are represented by two different numbers</li>
<li>Every pair of 2 distinct numbers must have at least 1 different digit for all number systems</li>
</ol>
<h2 id="the-advanced-answer"><a href="#the-advanced-answer">The Advanced Answer</a></h2>
<p>With the previous strategy, we discovered that we are actually turning the 900 elephants into 30 groups (for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi><mo>=</mo><mn>10</mn></mrow><annotation encoding="application/x-tex">B=10</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">10</span></span></span></span>) such that for distinct values <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mi>a</mi></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.3014em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">a</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mi>b</mi></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4861em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">b</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> (1st and 2nd place elephants), there is guaranteed to be a group that contains <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mi>a</mi></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.3014em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">a</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> but not <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mi>b</mi></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4861em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">b</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>.</p>
<p>Now we wish to determine the minimum number of groups we need to be able to distinguish the 1st from 2nd elephant given 900 distinct elephants.</p>
<h3 id="grouping-by-hand"><a href="#grouping-by-hand">Grouping by Hand</a></h3>
<p>Let's start by hand choosing groups for smaller numbers of elephants:</p>
<table>
<thead>
<tr>
<th align="left"><strong>Num Elephants = 3</strong></th>
<th align="left"><strong>Num Elephants = 4</strong></th>
<th align="left"><strong>Num Elephants = 5</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>1</mn></msub><mo>=</mo><mo stretchy="false">{</mo><msub><mtext>🐘</mtext><mn>1</mn></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mn>2</mn></msub><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">G_1 = \{\text{🐘}_1, \text{🐘}_2\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">}</span></span></span></span></td>
<td align="left"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>1</mn></msub><mo>=</mo><mo stretchy="false">{</mo><msub><mtext>🐘</mtext><mn>2</mn></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mn>3</mn></msub><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">G_1 = \{\text{🐘}_2, \text{🐘}_3\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">}</span></span></span></span></td>
<td align="left"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>1</mn></msub><mo>=</mo><mo stretchy="false">{</mo><msub><mtext>🐘</mtext><mn>1</mn></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mn>2</mn></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mn>3</mn></msub><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">G_1 = \{\text{🐘}_1, \text{🐘}_2, \text{🐘}_3\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">}</span></span></span></span></td>
</tr>
<tr>
<td align="left"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>2</mn></msub><mo>=</mo><mo stretchy="false">{</mo><msub><mtext>🐘</mtext><mn>1</mn></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mn>3</mn></msub><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">G_2 = \{\text{🐘}_1, \text{🐘}_3\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">}</span></span></span></span></td>
<td align="left"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>2</mn></msub><mo>=</mo><mo stretchy="false">{</mo><msub><mtext>🐘</mtext><mn>1</mn></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mn>4</mn></msub><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">G_2 = \{\text{🐘}_1, \text{🐘}_4\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">}</span></span></span></span></td>
<td align="left"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>2</mn></msub><mo>=</mo><mo stretchy="false">{</mo><msub><mtext>🐘</mtext><mn>1</mn></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mn>4</mn></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mn>5</mn></msub><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">G_2 = \{\text{🐘}_1, \text{🐘}_4, \text{🐘}_5\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">}</span></span></span></span></td>
</tr>
<tr>
<td align="left"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>3</mn></msub><mo>=</mo><mo stretchy="false">{</mo><msub><mtext>🐘</mtext><mn>2</mn></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mn>3</mn></msub><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">G_3 = \{\text{🐘}_2, \text{🐘}_3\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">}</span></span></span></span></td>
<td align="left"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>3</mn></msub><mo>=</mo><mo stretchy="false">{</mo><msub><mtext>🐘</mtext><mn>2</mn></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mn>4</mn></msub><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">G_3 = \{\text{🐘}_2, \text{🐘}_4\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">}</span></span></span></span></td>
<td align="left"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>3</mn></msub><mo>=</mo><mo stretchy="false">{</mo><msub><mtext>🐘</mtext><mn>2</mn></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mn>4</mn></msub><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">G_3 = \{\text{🐘}_2, \text{🐘}_4\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">}</span></span></span></span></td>
</tr>
<tr>
<td align="left"></td>
<td align="left"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>4</mn></msub><mo>=</mo><mo stretchy="false">{</mo><msub><mtext>🐘</mtext><mn>1</mn></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mn>3</mn></msub><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">G_4 = \{\text{🐘}_1, \text{🐘}_3\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">}</span></span></span></span></td>
<td align="left"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>G</mi><mn>4</mn></msub><mo>=</mo><mo stretchy="false">{</mo><msub><mtext>🐘</mtext><mn>3</mn></msub><mo separator="true">,</mo><msub><mtext>🐘</mtext><mn>5</mn></msub><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">G_4 = \{\text{🐘}_3, \text{🐘}_5\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">}</span></span></span></span></td>
</tr>
</tbody>
</table>
<p>These groupings work because all elephants appear in at least 2 groups which have no shared items besides the elephant
in question. This means that for all possible 1st and 2nd place pairs
that Charlie can give, Bob can give the number of the group containing
only the 1st place elephant.</p>
<h3 id="a-better-representation"><a href="#a-better-representation">A Better Representation</a></h3>
<p>Now let's try to generalize this to larger groups of elephants.
Instead of explicitly showing the groups, let's assume <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> groups
and give each elephant an <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> length encoding that says what
groups they are a part of. For position <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6595em;"></span><span class="mord mathnormal">i</span></span></span></span> of the encoding, let 1
signal that the elephant is part of group <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6595em;"></span><span class="mord mathnormal">i</span></span></span></span> and 0 that the
elephant is not in group <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6595em;"></span><span class="mord mathnormal">i</span></span></span></span>.</p>
<figure><!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->

<!-- Generated by graphviz version 14.1.1 (20251213.1925)
 -->
<!-- Title: G Pages: 1 -->
<svg width="230pt" height="144pt" viewBox="0.00 0.00 230.00 144.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(0.682464 0.682464) rotate(0) translate(4 207)">
<title>G</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-207 332.87,-207 332.87,4 -4,4"></polygon>
<g id="clust1" class="cluster">
<title>cluster_0</title>
</g>
<g id="clust2" class="cluster">
<title>cluster_1</title>
</g>
<!-- A -->
<g id="node1" class="node">
<title>A</title>
<polygon fill="#e0f2fe" stroke="black" points="161.75,-145.6 16,-145.6 16,-16.4 161.75,-16.4 161.75,-145.6"></polygon>
<text xml:space="preserve" text-anchor="start" x="30.4" y="-120.4" font-family="system-ui, -apple-system, sans-serif" font-size="12.00" fill="#0c4a6e">Num Elephants = 5</text>
<text xml:space="preserve" text-anchor="start" x="30.4" y="-106" font-family="system-ui, -apple-system, sans-serif" font-size="12.00" fill="#0c4a6e">Num Groups = 4</text>
<text xml:space="preserve" text-anchor="start" x="30.4" y="-77.6" font-family="system-ui, -apple-system, sans-serif" font-size="12.00" fill="#0c4a6e">G₁ = {🐘₁, 🐘₂, 🐘₃}</text>
<text xml:space="preserve" text-anchor="start" x="30.4" y="-63.2" font-family="system-ui, -apple-system, sans-serif" font-size="12.00" fill="#0c4a6e">G₂ = {🐘₁, 🐘₄, 🐘₅}</text>
<text xml:space="preserve" text-anchor="start" x="30.4" y="-48.8" font-family="system-ui, -apple-system, sans-serif" font-size="12.00" fill="#0c4a6e">G₃ = {🐘₂, 🐘₄}</text>
<text xml:space="preserve" text-anchor="start" x="30.4" y="-34.4" font-family="system-ui, -apple-system, sans-serif" font-size="12.00" fill="#0c4a6e">G₄ = {🐘₃, 🐘₅}</text>
</g>
<!-- B -->
<g id="node2" class="node">
<title>B</title>
<polygon fill="#dcfce7" stroke="black" points="312.87,-145.6 197.75,-145.6 197.75,-16.4 312.87,-16.4 312.87,-145.6"></polygon>
<text xml:space="preserve" text-anchor="start" x="212.15" y="-120.4" font-family="system-ui, -apple-system, sans-serif" font-size="12.00" fill="#166534">Binary Encodings</text>
<text xml:space="preserve" text-anchor="middle" x="255.31" y="-92" font-family="system-ui, -apple-system, sans-serif" font-size="12.00" fill="#166534">🐘₁ → 1100</text>
<text xml:space="preserve" text-anchor="middle" x="255.31" y="-77.6" font-family="system-ui, -apple-system, sans-serif" font-size="12.00" fill="#166534">🐘₂ → 1010</text>
<text xml:space="preserve" text-anchor="middle" x="255.31" y="-63.2" font-family="system-ui, -apple-system, sans-serif" font-size="12.00" fill="#166534">🐘₃ → 1001</text>
<text xml:space="preserve" text-anchor="middle" x="255.31" y="-48.8" font-family="system-ui, -apple-system, sans-serif" font-size="12.00" fill="#166534">🐘₄ → 0110</text>
<text xml:space="preserve" text-anchor="middle" x="255.31" y="-34.4" font-family="system-ui, -apple-system, sans-serif" font-size="12.00" fill="#166534">🐘₅ → 0101</text>
</g>
<!-- A&#45;&gt;B -->
<g id="edge1" class="edge">
<title>A->B</title>
<path fill="none" stroke="#6b7280" d="M162,-81C170,-81 178.13,-81 186.08,-81"></path>
<polygon fill="#6b7280" stroke="#6b7280" points="186.05,-84.5 196.05,-81 186.05,-77.5 186.05,-84.5"></polygon>
</g>
</g>
</svg>
</figure>
<h4 id="using-the-representation"><a href="#using-the-representation">Using the Representation</a></h4>
<p>To determine if any 1st and 2nd place elephant pair Charlie can give is valid,
we can now just compare each elephant's encoding to see if there is a position
where 1st place has a 1 and 2nd place has a zero.</p>
<p>Below is an example of how you could use the above encoding to determine:</p>
<ul>
<li><strong>1st Place</strong> = <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>3</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> and <strong>2nd Place</strong> = <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>5</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_5</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></li>
<li><strong>Encodings:</strong>
<ul>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>3</mn></msub><mo>=</mo><mn>1001</mn></mrow><annotation encoding="application/x-tex">\text{🐘}_3 = 1001</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5169em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1001</span></span></span></span></li>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>5</mn></msub><mo>=</mo><mn>0101</mn></mrow><annotation encoding="application/x-tex">\text{🐘}_5 = 0101</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5169em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0101</span></span></span></span></li>
</ul>
</li>
<li>Since Position 1 for 1st place elephant is 1 while 0 for 2nd place elephant, we know Group 1 contains 1st place elephant and not 2nd place elephant. Therefore Bob will answer Group 1.</li>
<li>There are 2 numbers that Charlie can give you:
<ul>
<li>If Charlie gives you the 1st place elephant (<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>3</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>), we see from <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>3</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>'s encoding (<strong>1</strong>001) that it is in Group 1 and therefore must be the 1st place elephant.</li>
<li>If Charlie gives you the 2nd place elephant (<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>5</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_5</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>), we see from <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>5</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_5</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>'s encoding (<strong>0</strong>101) that it isn't in Group 1 and therefore must be the 2nd place elephant.</li>
</ul>
</li>
</ul>
<h3 id="the-underlying-pattern"><a href="#the-underlying-pattern">The Underlying Pattern</a></h3>
<p>If you look closely you'll also notice that each elephant encoding has exactly
2 1s in its encoding of length 4. An interesting property of this representation
is that as long as every elephant is in exactly <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span> groups (when a 1 appears <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span> times in the elephants encoding),
then for any 2 elephants <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mi>a</mi></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{a}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.3014em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">a</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mi>b</mi></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{b}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4861em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> there will be a position in the encoding such that elephant <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mi>a</mi></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{a}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.3014em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">a</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>
will have value 1 while elephant <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mi>b</mi></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{b}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4861em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> has value 0. In the original solution, each elephant appeared in exactly 3 different groups out of the 30 total showing it also follows this pattern.</p>
<p>What are the rules for picking the number of groups (<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span>) and number of 1s (<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>) allowed for
each encoding? With <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> groups and a fixed <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>, we can derive the number of unique encodings
with <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">(</mo><mfrac linethickness="0px"><mi>n</mi><mi>k</mi></mfrac><mo fence="true">)</mo></mrow><annotation encoding="application/x-tex">\binom{n}{k}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.2em;vertical-align:-0.35em;"></span><span class="mord"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7454em;"><span style="top:-2.355em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span style="top:-3.144em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span></span></span></span>. So for our example above when <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>4</mn></mrow><annotation encoding="application/x-tex">n=4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">4</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">k=2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span></span></span></span>, we can uniquely represent a
max of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mo fence="true">(</mo><mfrac linethickness="0px"><mn>4</mn><mn>2</mn></mfrac><mo fence="true">)</mo></mrow><mo>=</mo><mn>6</mn></mrow><annotation encoding="application/x-tex">\binom{4}{2}=6</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.2451em;vertical-align:-0.35em;"></span><span class="mord"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8951em;"><span style="top:-2.355em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.144em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">4</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">6</span></span></span></span> elephants.</p>
<p>We now need to find the optimal <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span> such that we can minimize <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> for 900 elephants. To do this,
we need to find the minimum <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> such that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">∃</mi><mi>k</mi><mo>:</mo><mrow><mo fence="true">(</mo><mfrac linethickness="0px"><mi>n</mi><mi>k</mi></mfrac><mo fence="true">)</mo></mrow><mo>≥</mo><mn>900</mn></mrow><annotation encoding="application/x-tex">\exists k: \binom{n}{k} \geq 900</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord">∃</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.2em;vertical-align:-0.35em;"></span><span class="mord"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7454em;"><span style="top:-2.355em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span style="top:-3.144em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">≥</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">900</span></span></span></span>. Before we try to solve
that directly<sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref aria-describedby="footnote-label">2</a></sup>, let's try and simplify the problem a little more.</p>
<h3 id="optimizing-the-pattern"><a href="#optimizing-the-pattern">Optimizing the Pattern</a></h3>
<p>You may notice when you plug in <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">(</mo><mfrac linethickness="0px"><mi>n</mi><mi>k</mi></mfrac><mo fence="true">)</mo></mrow><annotation encoding="application/x-tex">\binom{n}{k}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.2em;vertical-align:-0.35em;"></span><span class="mord"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7454em;"><span style="top:-2.355em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span style="top:-3.144em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span></span></span></span> with different <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span> values, it tends to be maximal for a given <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> when
we choose a <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span> that is about <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mi mathvariant="normal">/</mi><mn>2</mn></mrow><annotation encoding="application/x-tex">n/2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">n</span><span class="mord">/2</span></span></span></span>. This can be formalized with the below theorem:</p>
<blockquote>
<p><strong><a href="https://en.wikipedia.org/wiki/Sperner%27s_theorem">Sperner's Theorem:</a></strong>
The largest possible family of non-overlapping subsets for an <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> sized set can
be calculated as:</p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">∣</mi><mi>S</mi><mi mathvariant="normal">∣</mi><mo>≤</mo><mrow><mo fence="true">(</mo><mfrac linethickness="0px"><mi>n</mi><mrow><mo fence="true">⌊</mo><mi>n</mi><mi mathvariant="normal">/</mi><mn>2</mn><mo fence="true">⌋</mo></mrow></mfrac><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">|S| \leq \binom{n}{\left\lfloor n/2 \right\rfloor}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">∣</span><span class="mord mathnormal" style="margin-right:0.05764em;">S</span><span class="mord">∣</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">≤</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.37em;vertical-align:-0.52em;"></span><span class="mord"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7454em;"><span style="top:-2.355em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="minner mtight"><span class="mopen mtight delimcenter" style="top:0em;"><span class="mtight">⌊</span></span><span class="mord mathnormal mtight">n</span><span class="mord mtight">/2</span><span class="mclose mtight delimcenter" style="top:0em;"><span class="mtight">⌋</span></span></span></span></span></span><span style="top:-3.144em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.52em;"><span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span></span></span></span></p>
<p>If and only if each subset has size <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>=</mo><mrow><mo fence="true">⌊</mo><mfrac><mi>n</mi><mn>2</mn></mfrac><mo fence="true">⌋</mo></mrow></mrow><annotation encoding="application/x-tex">k = \left\lfloor \frac{n}{2} \right\rfloor</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.2em;vertical-align:-0.35em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">⌊</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.6954em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">⌋</span></span></span></span></span></span> or <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>=</mo><mrow><mo fence="true">⌈</mo><mfrac><mi>n</mi><mn>2</mn></mfrac><mo fence="true">⌉</mo></mrow></mrow><annotation encoding="application/x-tex">k = \left\lceil \frac{n}{2} \right\rceil</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.2em;vertical-align:-0.35em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">⌈</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.6954em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">⌉</span></span></span></span></span></span></p>
</blockquote>
<p>We can now use this theorem to more simply represent the problem. Let's start by testing values <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> with the equation <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>900</mn><mo>≤</mo><mrow><mo fence="true">(</mo><mfrac linethickness="0px"><mi>n</mi><mrow><mo fence="true">⌊</mo><mi>n</mi><mi mathvariant="normal">/</mi><mn>2</mn><mo fence="true">⌋</mo></mrow></mfrac><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">900 \leq \binom{n}{\left\lfloor n/2 \right\rfloor}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7804em;vertical-align:-0.136em;"></span><span class="mord">900</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">≤</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.37em;vertical-align:-0.52em;"></span><span class="mord"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7454em;"><span style="top:-2.355em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="minner mtight"><span class="mopen mtight delimcenter" style="top:0em;"><span class="mtight">⌊</span></span><span class="mord mathnormal mtight">n</span><span class="mord mtight">/2</span><span class="mclose mtight delimcenter" style="top:0em;"><span class="mtight">⌋</span></span></span></span></span></span><span style="top:-3.144em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.52em;"><span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span></span></span></span> on different values until we find the minimum
number of groups that work.</p>
<p>If we try with <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>11</mn></mrow><annotation encoding="application/x-tex">n=11</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">11</span></span></span></span>, we get <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mo fence="true">(</mo><mfrac linethickness="0px"><mn>11</mn><mrow><mo fence="true">⌊</mo><mn>11</mn><mi mathvariant="normal">/</mi><mn>2</mn><mo fence="true">⌋</mo></mrow></mfrac><mo fence="true">)</mo></mrow><mo>=</mo><mrow><mo fence="true">(</mo><mfrac linethickness="0px"><mn>11</mn><mn>5</mn></mfrac><mo fence="true">)</mo></mrow><mo>=</mo><mn>462</mn></mrow><annotation encoding="application/x-tex">\binom{11}{\left\lfloor 11/2 \right\rfloor} = \binom{11}{5} = 462</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.4151em;vertical-align:-0.52em;"></span><span class="mord"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8951em;"><span style="top:-2.355em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="minner mtight"><span class="mopen mtight delimcenter" style="top:0em;"><span class="mtight">⌊</span></span><span class="mord mtight">11/2</span><span class="mclose mtight delimcenter" style="top:0em;"><span class="mtight">⌋</span></span></span></span></span></span><span style="top:-3.144em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">11</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.52em;"><span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.2451em;vertical-align:-0.35em;"></span><span class="mord"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8951em;"><span style="top:-2.355em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">5</span></span></span></span><span style="top:-3.144em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">11</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">462</span></span></span></span>.
This shows us we need more than 11 groups as <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>462</mn><mo>&#x3C;</mo><mn>900</mn></mrow><annotation encoding="application/x-tex">462 &#x3C; 900</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6835em;vertical-align:-0.0391em;"></span><span class="mord">462</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&#x3C;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">900</span></span></span></span>.</p>
<p>If we try with <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>12</mn></mrow><annotation encoding="application/x-tex">n=12</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">12</span></span></span></span>, we get <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mo fence="true">(</mo><mfrac linethickness="0px"><mn>12</mn><mrow><mo fence="true">⌊</mo><mn>12</mn><mi mathvariant="normal">/</mi><mn>2</mn><mo fence="true">⌋</mo></mrow></mfrac><mo fence="true">)</mo></mrow><mo>=</mo><mrow><mo fence="true">(</mo><mfrac linethickness="0px"><mn>12</mn><mn>6</mn></mfrac><mo fence="true">)</mo></mrow><mo>=</mo><mn>924</mn></mrow><annotation encoding="application/x-tex">\binom{12}{\left\lfloor 12/2 \right\rfloor} = \binom{12}{6} = 924</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.4151em;vertical-align:-0.52em;"></span><span class="mord"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8951em;"><span style="top:-2.355em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="minner mtight"><span class="mopen mtight delimcenter" style="top:0em;"><span class="mtight">⌊</span></span><span class="mord mtight">12/2</span><span class="mclose mtight delimcenter" style="top:0em;"><span class="mtight">⌋</span></span></span></span></span></span><span style="top:-3.144em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">12</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.52em;"><span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.2451em;vertical-align:-0.35em;"></span><span class="mord"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8951em;"><span style="top:-2.355em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span><span style="top:-3.144em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">12</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">924</span></span></span></span>.
As <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>924</mn><mo>></mo><mn>900</mn></mrow><annotation encoding="application/x-tex">924 > 900</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6835em;vertical-align:-0.0391em;"></span><span class="mord">924</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">900</span></span></span></span> we know this is a valid number of groupings. Additionally, since we know <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>11</mn></mrow><annotation encoding="application/x-tex">n=11</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">11</span></span></span></span> doesn't work
and we need to use whole numbers for numbers of groups, the minimum upper bound Bob can give is <strong><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>12</mn></mrow><annotation encoding="application/x-tex">n=12</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">12</span></span></span></span></strong> <sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref aria-describedby="footnote-label">3</a></sup>.</p>
<p>We can generalize this to different sized elephant races by using a binary search from 2 to the size of the race
to find the minimum number of groups using the above equation. I created a <a href="https://elephant-race.pages.dev">handy little visualization tool</a>
to help create visualizations for generating the optimal groups below:</p>
<p><img src="/elephant_race/demo_site.png" alt="Visualization Tool"></p>
<h2 id="conclusion"><a href="#conclusion">Conclusion</a></h2>
<p>In this post, we first determined a way to distinguish any 2 elephants of a 900 elephant race from a set of 30 possible answers
based on the digits of the elephants' numbers. We then discovered we can lower the set of possible answers to 20 by using a different
number system such as binary instead of decimal. After this we dug deeper into why this trick worked and used the intuition to calculate
the smallest possible set of answers<sup><a href="#user-content-fn-3" id="user-content-fnref-3-2" data-footnote-ref aria-describedby="footnote-label">3</a></sup> which turned out to be <strong>12</strong>.</p>
<p>The next time you're at an elephant race and have an annoying friend named Charlie who loves giving cryptic answers, make sure
you use this strategy when you talk to Bob!</p>
<section data-footnotes class="footnotes"><h2 class="sr-only" id="footnote-label"><a href="#footnote-label">Footnotes</a></h2>
<ol>
<li id="user-content-fn-1">
<p>We're including <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mtext>🐘</mtext><mn>000</mn></msub></mrow><annotation encoding="application/x-tex">\text{🐘}_{000}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4511em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord text"><span class="mord">🐘</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">000</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> and any elephant above 900 in these calculations despite them not being in the race. This is because
you can use this strategy for races of up to 1000 elephants. <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩︎</a> <a href="#user-content-fnref-1-2" data-footnote-backref="" aria-label="Back to reference 1-2" class="data-footnote-backref">↩︎</a> <a href="#user-content-fnref-1-3" data-footnote-backref="" aria-label="Back to reference 1-3" class="data-footnote-backref">↩︎</a> <a href="#user-content-fnref-1-4" data-footnote-backref="" aria-label="Back to reference 1-4" class="data-footnote-backref">↩︎</a></p>
</li>
<li id="user-content-fn-2">
<p>You can plug this in to <a href="https://www.desmos.com/calculator">Desmos</a> to solve <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to reference 2" class="data-footnote-backref">↩︎</a></p>
</li>
<li id="user-content-fn-3">
<p>This is the minimum bound with this method, there may or may not be an even lower bound <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to reference 3" class="data-footnote-backref">↩︎</a> <a href="#user-content-fnref-3-2" data-footnote-backref="" aria-label="Back to reference 3-2" class="data-footnote-backref">↩︎</a></p>
</li>
</ol>
</section>]]></content:encoded>
    </item>
    <item>
      <title>Enter the (Gluck) Arena</title>
      <description>Build yourself an arcade of multiplayer party games!</description>
      <pubDate>Wed, 21 May 2025 00:00:00 GMT</pubDate>
      <link>https://adamgluck.com/posts/gluck_arena</link>
      <guid isPermaLink="true">https://adamgluck.com/posts/gluck_arena</guid>
      <content:encoded><![CDATA[<p><img src="/gluck_arena/cover.png" alt="Blog Cover"></p>
<h2 id="background"><a href="#background">Background</a></h2>
<p>One of my favorite party games is <a href="https://www.jackboxgames.com/games/quiplash">Quiplash</a> from <a href="https://www.jackboxgames.com/">Jackbox Games</a>.
Jackbox games are unique because they leverage the fact that (almost) everyone has a smartphone to create a unique game experience. However, it still requires a computer/console
and a display to play, which makes it hard to use when traveling. In 2024, me and my wrestling club teammates tried to set up a game after our national tournament, but weren't
able to get it set up in our hotel room due to the previously mentioned issues. We ended up finding a russian cards against humanity clone to play, but it planted the seed for me to
create <a href="https://games.adamgluck.com/">Gluck Arena</a>, a jackbox style website that doesn't need a computer and display combo to play games. In this blog, I'll go over how Gluck Arena works along with an overview of its signature game: Quizzer.</p>
<h2 id="how-gluck-arena-works"><a href="#how-gluck-arena-works">How Gluck Arena Works</a></h2>
<h3 id="technical-architecture"><a href="#technical-architecture">Technical Architecture</a></h3>
<p><img src="/gluck_arena/high_level.png" alt="High Level Architecture"></p>
<p>Gluck Arena is mobile first website designed for arbitrary multiplayer party games. It was designed for party games and doesn't require players to create accounts. At a high level, it was built
with the following technologies:</p>
<ul>
<li><strong>Typescript</strong>: A typed superset of Javascript with <a href="https://en.wikipedia.org/wiki/Type_system#Static_type_checking">static typing</a></li>
<li><strong><a href="https://pages.cloudflare.com/">Cloudflare Pages</a></strong>: A platform that is able to host serverless <a href="https://nextjs.org/">NextJS</a> applications</li>
<li><strong><a href="https://www.convex.dev/">Convex</a></strong>: A real-time backend as a service (BaaS) platform</li>
</ul>
<p>The multiplayer features leverage Convex's <a href="https://www.convex.dev/realtime">sync engine</a>, which ensures all players see the most recent game state. This architecture allows for a seamless multiplayer experience without complex state management,
as long as the games don't require extremely frequent and complex updates to specific rows of data.</p>
<h2 id="key-components"><a href="#key-components">Key Components</a></h2>
<h3 id="player-management"><a href="#player-management">Player Management</a></h3>
<p><img src="/gluck_arena/player.png" alt="Player Design"></p>
<p>When a player first enters Gluck Arena, a unique ID is created for them as their "account" and stored in a browser's <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage">session storage</a>. This will allow them to refresh their page without losing their account, while also allowing me to test games by making new tabs in a single browser.
Once an account is created, the below form then appears asking to enter a username that will be used for their time in Gluck Arena.</p>
<p><img src="/gluck_arena/user_prompt.png" alt="Username Prompt"></p>
<p>Once a username is chosen the player ID and username are added to the "players" table in the Convex database. The username can be changed anytime using the "change name" form in The
navigation bar. If a player refreshes the page or leaves and re-enters the browser session, the unique ID from the session will then be used to check the database for a corresponding player.
If there is no ID in a user's session storage or if their ID isn't found in the player table, a new ID is created and the player is assigned to the new account.</p>
<h3 id="game-management"><a href="#game-management">Game Management</a></h3>
<p><img src="/gluck_arena/game.png" alt="Game Design"></p>
<p>Each game instance in Gluck Arena is stored as a single row in the "games" table. A game consists of three properties: a join code to allow players to enter a game, a type to represent what type of game is being played, a status to show if a game is joinable/in-progress/completed, and a state that contains the information needed to play the game. There is also a "game-player" table used to track which players are in which games.</p>
<p>Convex allows documents, or "rows" in a table <a href="https://docs.convex.dev/production/state/limits">to contain a maximum of 1 mebibyte (MiB, which is slightly bigger than a megabyte) of data, 16 layers of nesting for objects, and 8192 objects per array</a>. This makes it easy to store all the  game logic in a single row in the "games" table. In addition, the game logic is typed using a <a href="https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html">Typescript union type</a> to ensure type safety even though rows can represent different games. However, for games like Quizzer, an additional table is needed to store available questions.</p>
<p>To ensure the table doesn't get filled with expired games and old players, a <a href="https://en.wikipedia.org/wiki/Cron">Cron Job</a> is configured to delete each once they've reached predefined
"oldness" thresholds based on activity and age. Once a game or player is deleted, a <a href="https://en.wikipedia.org/wiki/Database_trigger">database trigger</a> is activated to delete rows in the
"game-player" table that reference it.</p>
<h3 id="quizzer-implementation"><a href="#quizzer-implementation">Quizzer Implementation</a></h3>
<p><img src="/gluck_arena/quizzer.png" alt="Quizzer Design"></p>
<p>To implement a game in Gluck Arena, there are 5 requirements: a type to represent the game logic, backend functions to allow game actions, and a <a href="https://react.dev/">React</a> page for each of the game statuses (lobby, active, and finished). The lobby page is shown when a game is created, but waiting for all players to join. There are also typically settings in this page shown to the game creator for configuring the game for things such as number of rounds to play. The active page is used to play the game and the finished page shows the leaderboard of who won. Because implementing a game is so standardized, AI tools like <a href="https://www.cursor.com/">Cursor</a> can be used to implement a lot of these requirements.</p>
<p>The rules of Quizzer are simple. Each round, players answer questions assigned to them such that each question is answered by exactly 2 players. Then, players vote on which answer was better
for each question (except for the answer writers) and players get points depending on how many votes their answer got. At the end of the game, whichever player gets the most points wins the game.</p>
<p>There are 2 types of questions in Quizzer: the default questions (which I put in the database) and AI generated questions (which are dynamically generated per game). Before each game,
the game creator has the option to allow AI questions and enter in a prompt to give a theme to the question if entered. The creator can also specify how many questions they need, allowing
a mix of AI and non-AI questions. The creator can also add custom questions by hand through a UI in the lobby page.</p>
<p>For each Quizzer game, there are <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> questions per round where n is the number of players. When a game is created, it randomly selects <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>n</mi><mo>∗</mo><mtext>num rounds</mtext><mo>−</mo><mo stretchy="false">(</mo><mtext>num AI Generated</mtext><mo>+</mo><mtext>num custom questions</mtext><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(n*\text{num rounds} - (\text{num AI Generated} + \text{num custom questions}))</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.0833em;"></span><span class="mord text"><span class="mord">num rounds</span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord text"><span class="mord">num AI Generated</span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">num custom questions</span></span><span class="mclose">))</span></span></span></span> from the question database and starts the game. It then divides the questions up into <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> rounds and assigns each question to 2 players. At the start of each round, players then go into "question answering mode" where they answer their assigned questions. If players are taking too long to answer questions, the game creator has the ability to end this mode early and AI generate answers to unanswered questions. After this mode is over, players vote on prompts with the game creator controlling the speed at which the game is played. This is repeated for each of the rounds in the game.</p>
<h2 id="conclusion"><a href="#conclusion">Conclusion</a></h2>
<p>One thing that makes Gluck Arena stand out from my other projects is in how it's based on the features/limits of Convex. Without Convex, the multiplayer features would be significantly more complex to implement and likely more expensive as well. This project reminded me of <a href="https://www.warpstream.com">Warpstream</a>, a <a href="https://kafka.apache.org">Apache Kafka</a> compatible product that simplifies and cheapens <a href="https://en.wikipedia.org/wiki/Stream_processing">stream processing</a> by leveraging
the features/limits of <a href="https://en.wikipedia.org/wiki/Object_storage">object storage</a>. I recently wrote <a href="/assets/legal-topics.pdf">a report on the patentability of Warpstream</a> for a class that goes into more detail if you'd like to learn more.</p>
<p>Overall, I believe that the biggest takeaway from this project is the power of designing projects around specific technologies. I feel there is a lot of unneeded pressure in
software engineering to make projects backend agnostic and infinitely scalable. However, designing projects around a technology like Convex or Object Storage often has tangible benefits.
This is more obvious in Warpstream's case as it was acquired for <a href="https://pitchbook.com/profiles/company/534965-14">$220 million</a> 13 months after it was released for essentially rebuilding Kafka from the ground up around modern technologies. I suspect this trend will continue as technology gets better and platforms give stronger guarantees.</p>]]></content:encoded>
    </item>
    <item>
      <title>Finding Food with an Inverted Index</title>
      <description>Implementing fast full text search on menus so you can eat like a king!</description>
      <pubDate>Fri, 07 Mar 2025 00:00:00 GMT</pubDate>
      <link>https://adamgluck.com/posts/fast_food</link>
      <guid isPermaLink="true">https://adamgluck.com/posts/fast_food</guid>
      <content:encoded><![CDATA[<p><img src="/fast_food/cover.png" alt="Blog Cover"></p>
<h2 id="background"><a href="#background">Background</a></h2>
<p>Ohio State University has a lot of students (60k+). Students often get hungry, so OSU has a lot of dining halls, each with a lot
of different food options. Finding a dining hall to eat at can be tricky, especially if a student has dietary restrictions or nutritional
goals (bulking or losing weight). This blog post goes over how I made <a href="https://ohiostate.food/">OhioState.food</a> to make it easier to browse OSU food options and how I used an inverse index to make it fast.</p>
<h2 id="project-structure"><a href="#project-structure">Project Structure</a></h2>
<p><img src="/fast_food/osu_diagram.png" alt="OhioState.food Diagram"></p>
<p><a href="https://ohiostate.food/">OhioState.food</a> is a <a href="https://nextjs.org/">Nextjs</a> deployed using <a href="https://pages.cloudflare.com/">Cloudflare Pages</a>.
It uses <a href="https://developers.cloudflare.com/pages/framework-guides/nextjs/ssr/">Cloudflares's Nextjs adapter</a> to work with Cloudflare and has the drawback
of only supporting <a href="https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes">the edge runtime for Nextjs</a>
(<a href="https://workers.cloudflare.com/">Cloudflare Workers</a> acts as the server). <a href="https://developers.cloudflare.com/d1/">Cloudflare D1</a> is used for persistence
(essentially a hosted sqlite database).</p>
<p>The data is sourced from <a href="https://osu.nutrislice.com/">Nutrislice's</a> API, which has menu information for every dining hall on OSU campus.
Every morning, a <a href="https://en.wikipedia.org/wiki/Cron">cron job</a> on <a href="https://github.com/features/actions">Github Actions</a> is used to run a script that updates the
database with the latest menu items using the "populate" endpoint on the site. Once the data is uploaded,
I use <a href="https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations">Nextjs Server Actions</a> to query the
database with the <a href="https://orm.drizzle.team/">Drizzle ORM</a> for type safety.</p>
<h2 id="food-searching"><a href="#food-searching">Food Searching</a></h2>
<p>The easiest way to choose a dining hall to eat at is to start with the food you want to eat and work backwards.
Lets start with a simple query that queries the "food" table in my database based on food name, dietary restrictions, and nutritional information.</p>
<pre class="shiki solarized-light" style="background-color:#FDF6E3;color:#657B83" tabindex="0"><code><span class="line"><span style="color:#93A1A1;font-style:italic">-- Simplified Query</span></span>
<span class="line"></span>
<span class="line"><span style="color:#93A1A1;font-style:italic">-- Get all columns from foods table, aliased as f</span></span>
<span class="line"><span style="color:#859900">SELECT</span><span style="color:#859900"> *</span><span style="color:#859900"> FROM</span><span style="color:#657B83"> foods </span><span style="color:#859900">AS</span><span style="color:#657B83"> f</span></span>
<span class="line"><span style="color:#93A1A1;font-style:italic">-- Filter foods where name contains the search query</span></span>
<span class="line"><span style="color:#859900">WHERE</span><span style="color:#CB4B16"> f</span><span style="color:#657B83">.</span><span style="color:#CB4B16">name</span><span style="color:#859900"> LIKE</span><span style="color:#2AA198"> '%{query}%'</span></span>
<span class="line"><span style="color:#93A1A1;font-style:italic">-- Filter by dietary restrictions</span></span>
<span class="line"><span style="color:#859900">AND</span><span style="color:#CB4B16"> f</span><span style="color:#657B83">.</span><span style="color:#CB4B16">dietary_info</span><span style="color:#859900"> ==</span><span style="color:#657B83"> {dietary_filter} </span></span>
<span class="line"><span style="color:#93A1A1;font-style:italic">-- Filter by nutritional requirements</span></span>
<span class="line"><span style="color:#859900">AND</span><span style="color:#CB4B16"> f</span><span style="color:#657B83">.</span><span style="color:#CB4B16">nutrition</span><span style="color:#859900"> ==</span><span style="color:#657B83"> {nutrition_filter} </span></span></code></pre>
<p>This query takes around 10-15 seconds to run on the foods table with 1k+ foods.
I found this to be slow, especially since I wanted to display food results on the
site live as the user was typing.</p>
<p>The traditional way to speed up a SQL query is to add <a href="https://en.wikipedia.org/wiki/Database_index">indexes</a> to frequently read columns in a table. This slightly slows down
write speed and increases table storage size, but speeds up queries significantly as the database no
longer needs to do a <a href="https://en.wikipedia.org/wiki/Linear_search">linear scan</a> on the entire table. Dietary and nutrition information are easy to index on as they only need
equality and range comparison for queries. However, indexing on <a href="https://en.wikipedia.org/wiki/Full-text_search">full text search</a> with conditions <span class="shiki solarized-light" style="background-color:#FDF6E3;color:#657B83" tabindex="0"><code><span class="line"><span style="color:#CB4B16">f</span><span style="color:#657B83">.</span><span style="color:#CB4B16">name</span><span style="color:#859900"> LIKE</span><span style="color:#2AA198"> '%{query}%'</span></span></code></span> requires a bit more effort than simply adding
a built in <a href="https://www.sqlite.org/lang_createindex.html">sqlite index</a>. This is where inverted indexes come in handy.</p>
<h2 id="inverted-indexes"><a href="#inverted-indexes">Inverted Indexes</a></h2>
<p><a href="https://en.wikipedia.org/wiki/Inverted_index">Inverted indexes</a> are a special data structure made to speed up full text searching. They work by creating a mapping of tokens (processed words) to documents. I'll demonstrate how they work by showing
what happens when a food document is added to an already existing inverted index.</p>
<h3 id="step-1-get-tokens-from-document"><a href="#step-1-get-tokens-from-document">Step 1: Get Tokens From Document</a></h3>
<p><img src="/fast_food/tokenize.png" alt="&#x22;Seasoned Fries&#x22; getting tokenized"></p>
<p>The first step to adding a document to the index is to get a list of all words
in the document. This is called <a href="https://en.wikipedia.org/wiki/Lexical_analysis#Tokenization">tokenization</a>. <a href="https://en.wikipedia.org/wiki/Lemmatization">Lemmatization</a>
or <a href="https://en.wikipedia.org/wiki/Stemming">stemming</a> is also typically done here to ensure
words like "steak" and "steaks" are map to the same documents.</p>
<h3 id="step-2-construct-or-add-to-inverted-index"><a href="#step-2-construct-or-add-to-inverted-index">Step 2: Construct or Add to Inverted Index</a></h3>
<p><img src="/fast_food/inverted_index.png" alt="&#x22;Seasoned Fries&#x22; added to inverted index"></p>
<p>Once the tokens are retrieved from the document, a check is done to see if there
is an entry in the inverted index for that token. If there is, a reference to the document
(typically its ID) is added to the structure. If there is not, a new entry in the index is made with the document reference as its initial value.</p>
<h3 id="step-3-querying-the-index"><a href="#step-3-querying-the-index">Step 3: Querying the Index</a></h3>
<p><img src="/fast_food/query.png" alt="Querying Seasoned Fries&#x22;"></p>
<p>There are many ways to handle full text queries with an inverted index, but a simple
way is to tokenize the query the same way the document was tokenized, get relevant documents
using the inverted index, and ranking them on relevancy using an algorithm like <a href="https://en.wikipedia.org/wiki/Okapi_BM25">BM25</a>. There are many possible optimizations here,
such as using data structures like <a href="https://en.wikipedia.org/wiki/Trie">tries</a> to enable searching on prefixes or by tokenizing the index on <a href="https://en.wikipedia.org/wiki/Trigram">trigrams</a> to allow substring matching. Overall though any of these techniques should make full text queries drastically faster than a linear scan with string comparisons.</p>
<h2 id="implementing-a-fast-full-text-search"><a href="#implementing-a-fast-full-text-search">Implementing a Fast Full Text Search</a></h2>
<p>Implementing an inverted index and effectively using it for full text search is a lot of work. Luckily, there are many ready to use database extensions that allow you to leverage these structures without the hassle. <a href="https://www.sqlite.org/fts5.html">FTS5</a> is a sqlite extension that handles full text search with inverted indexes for you.</p>
<p>FTS5 works by allowing you to create <a href="https://www.sqlite.org/vtab.html">virtual tables</a> (essentially code that pretends to be a table) backed by an efficient full text search engine (which uses inverted indexes). It also includes additional features like <a href="https://en.wikipedia.org/wiki/Proximity_search_(text)">proximity</a> and <a href="https://en.wikipedia.org/wiki/Phrase_search">phrase</a> search.
I've attached the FTS5 setup from <a href="https://ohiostate.food/">OhioState.food</a> below.</p>
<pre class="shiki solarized-light" style="background-color:#FDF6E3;color:#657B83" tabindex="0"><code><span class="line"><span style="color:#93A1A1;font-style:italic">-- Create FTS5 virtual table on name field in food table</span></span>
<span class="line"><span style="color:#859900">CREATE</span><span style="color:#657B83"> VIRTUAL </span><span style="color:#859900">TABLE</span><span style="color:#859900"> IF</span><span style="color:#859900"> NOT</span><span style="color:#859900"> EXISTS</span><span style="color:#657B83"> foods_fts </span></span>
<span class="line"><span style="color:#859900">USING</span><span style="color:#657B83"> fts5(</span><span style="color:#859900">name</span><span style="color:#657B83">, content</span><span style="color:#859900">=</span><span style="color:#657B83">foods, content_rowid</span><span style="color:#859900">=</span><span style="color:#657B83">id);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#93A1A1;font-style:italic">-- Create triggers to keep FTS table in sync</span></span>
<span class="line"><span style="color:#859900">CREATE</span><span style="color:#859900"> TRIGGER</span><span style="color:#268BD2"> IF</span><span style="color:#859900"> NOT</span><span style="color:#859900"> EXISTS</span><span style="color:#657B83"> foods_ai </span><span style="color:#859900">AFTER</span><span style="color:#859900"> INSERT</span><span style="color:#859900"> ON</span><span style="color:#657B83"> foods </span><span style="color:#859900">BEGIN</span></span>
<span class="line"><span style="color:#859900">    INSERT INTO</span><span style="color:#657B83"> foods_fts(rowid, </span><span style="color:#859900">name</span><span style="color:#657B83">)</span></span>
<span class="line"><span style="color:#859900">    VALUES</span><span style="color:#657B83"> (</span><span style="color:#CB4B16">new</span><span style="color:#657B83">.</span><span style="color:#CB4B16">id</span><span style="color:#657B83">, </span><span style="color:#CB4B16">new</span><span style="color:#657B83">.</span><span style="color:#CB4B16">name</span><span style="color:#657B83">);</span></span>
<span class="line"><span style="color:#859900">END</span><span style="color:#657B83">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#859900">CREATE</span><span style="color:#859900"> TRIGGER</span><span style="color:#268BD2"> IF</span><span style="color:#859900"> NOT</span><span style="color:#859900"> EXISTS</span><span style="color:#657B83"> foods_ad </span><span style="color:#859900">AFTER</span><span style="color:#859900"> DELETE</span><span style="color:#859900"> ON</span><span style="color:#657B83"> foods </span><span style="color:#859900">BEGIN</span></span>
<span class="line"><span style="color:#859900">    INSERT INTO</span><span style="color:#657B83"> foods_fts(foods_fts, rowid, </span><span style="color:#859900">name</span><span style="color:#657B83">)</span></span>
<span class="line"><span style="color:#859900">    VALUES</span><span style="color:#657B83">(</span><span style="color:#2AA198">'delete'</span><span style="color:#657B83">, </span><span style="color:#CB4B16">old</span><span style="color:#657B83">.</span><span style="color:#CB4B16">id</span><span style="color:#657B83">, </span><span style="color:#CB4B16">old</span><span style="color:#657B83">.</span><span style="color:#CB4B16">name</span><span style="color:#657B83">);</span></span>
<span class="line"><span style="color:#859900">END</span><span style="color:#657B83">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#859900">CREATE</span><span style="color:#859900"> TRIGGER</span><span style="color:#268BD2"> IF</span><span style="color:#859900"> NOT</span><span style="color:#859900"> EXISTS</span><span style="color:#657B83"> foods_au </span><span style="color:#859900">AFTER</span><span style="color:#859900"> UPDATE</span><span style="color:#859900"> ON</span><span style="color:#657B83"> foods </span><span style="color:#859900">BEGIN</span></span>
<span class="line"><span style="color:#859900">    INSERT INTO</span><span style="color:#657B83"> foods_fts(foods_fts, rowid, </span><span style="color:#859900">name</span><span style="color:#657B83">)</span></span>
<span class="line"><span style="color:#859900">    VALUES</span><span style="color:#657B83">(</span><span style="color:#2AA198">'delete'</span><span style="color:#657B83">, </span><span style="color:#CB4B16">old</span><span style="color:#657B83">.</span><span style="color:#CB4B16">id</span><span style="color:#657B83">, </span><span style="color:#CB4B16">old</span><span style="color:#657B83">.</span><span style="color:#CB4B16">name</span><span style="color:#657B83">);</span></span>
<span class="line"><span style="color:#859900">    INSERT INTO</span><span style="color:#657B83"> foods_fts(rowid, </span><span style="color:#859900">name</span><span style="color:#657B83">) </span></span>
<span class="line"><span style="color:#859900">    VALUES</span><span style="color:#657B83"> (</span><span style="color:#CB4B16">new</span><span style="color:#657B83">.</span><span style="color:#CB4B16">id</span><span style="color:#657B83">, </span><span style="color:#CB4B16">new</span><span style="color:#657B83">.</span><span style="color:#CB4B16">name</span><span style="color:#657B83">);</span></span>
<span class="line"><span style="color:#859900">END</span><span style="color:#657B83">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#93A1A1;font-style:italic">-- Populate FTS table with existing data</span></span>
<span class="line"><span style="color:#859900">INSERT</span><span style="color:#859900"> OR</span><span style="color:#859900"> IGNORE</span><span style="color:#859900"> INTO</span><span style="color:#657B83"> foods_fts(rowid, </span><span style="color:#859900">name</span><span style="color:#657B83">)</span></span>
<span class="line"><span style="color:#859900">SELECT</span><span style="color:#657B83"> id, </span><span style="color:#859900">name</span><span style="color:#859900"> FROM</span><span style="color:#657B83"> foods; </span></span></code></pre>
<p>The virtual table can now act as a full text search index that can be used to match a search
query for a food item much faster than before. For more details on how FTS5 works, check out <a href="https://darksi.de/13.sqlite-fts5-structure/">this blog</a>. Below is an example of a SQL query that uses the table to do a search on food name, with dietary and nutrition restrictions.</p>
<pre class="shiki solarized-light" style="background-color:#FDF6E3;color:#657B83" tabindex="0"><code><span class="line"><span style="color:#93A1A1;font-style:italic">-- Simplified FTS Query</span></span>
<span class="line"></span>
<span class="line"><span style="color:#93A1A1;font-style:italic">-- Get all columns from foods table</span></span>
<span class="line"><span style="color:#859900">SELECT</span><span style="color:#657B83"> f.</span><span style="color:#859900">*</span><span style="color:#859900"> FROM</span><span style="color:#657B83"> foods </span><span style="color:#859900">AS</span><span style="color:#657B83"> f</span></span>
<span class="line"><span style="color:#93A1A1;font-style:italic">-- Join with the FTS virtual table</span></span>
<span class="line"><span style="color:#859900">JOIN</span><span style="color:#657B83"> foods_fts </span><span style="color:#859900">AS</span><span style="color:#657B83"> fts </span><span style="color:#859900">ON</span><span style="color:#CB4B16"> f</span><span style="color:#657B83">.</span><span style="color:#CB4B16">id</span><span style="color:#859900"> =</span><span style="color:#CB4B16"> fts</span><span style="color:#657B83">.</span><span style="color:#CB4B16">rowid</span></span>
<span class="line"><span style="color:#93A1A1;font-style:italic">-- Use FTS MATCH instead of LIKE for faster search</span></span>
<span class="line"><span style="color:#859900">WHERE</span><span style="color:#657B83"> fts </span><span style="color:#859900">MATCH</span><span style="color:#2AA198"> '{query}'</span></span>
<span class="line"><span style="color:#93A1A1;font-style:italic">-- Filter by dietary restrictions</span></span>
<span class="line"><span style="color:#859900">AND</span><span style="color:#CB4B16"> f</span><span style="color:#657B83">.</span><span style="color:#CB4B16">dietary_info</span><span style="color:#859900"> ==</span><span style="color:#657B83"> {dietary_filter}</span></span>
<span class="line"><span style="color:#93A1A1;font-style:italic">-- Filter by nutritional requirements</span></span>
<span class="line"><span style="color:#859900">AND</span><span style="color:#CB4B16"> f</span><span style="color:#657B83">.</span><span style="color:#CB4B16">nutrition</span><span style="color:#859900"> ==</span><span style="color:#657B83"> {nutrition_filter}</span></span>
<span class="line"><span style="color:#93A1A1;font-style:italic">-- FTS tables automatically provide ranking</span></span>
<span class="line"><span style="color:#859900">ORDER BY</span><span style="color:#657B83"> rank;</span></span></code></pre>
<p>Our new query now has a full text index on food name along with the existing indexes on dietary nutrition information, bringing down our search delay to &#x3C;1 second<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref aria-describedby="footnote-label">1</a></sup>.
<a href="https://ohiostate.food/search">Try it live here</a>!</p>
<p><img src="/fast_food/osu-food.png" alt="OhioState.food Search Page"></p>
<h2 id="conclusion"><a href="#conclusion">Conclusion</a></h2>
<p>In this post we</p>
<ul>
<li>Walked through the design of a food search app for Ohio State Dining halls.</li>
<li>Explored how inverted indexes can be used to speed up full text search.</li>
<li>Implemented the FTS5 extension into a sqlite database.</li>
</ul>
<p>The next time you are trying to design a system with full text search, remember that you will likely need a specialized system like an inverted index if you expect any scale at all.</p>
<section data-footnotes class="footnotes"><h2 class="sr-only" id="footnote-label"><a href="#footnote-label">Footnotes</a></h2>
<ol>
<li id="user-content-fn-1">
<p>Measured against a local sqlite database. <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩︎</a></p>
</li>
</ol>
</section>]]></content:encoded>
    </item>
    <item>
      <title>Wrestling with WebRTC</title>
      <description>How I built a real-time scoreboard using WebRTC</description>
      <pubDate>Wed, 05 Feb 2025 00:00:00 GMT</pubDate>
      <link>https://adamgluck.com/posts/webrtc</link>
      <guid isPermaLink="true">https://adamgluck.com/posts/webrtc</guid>
      <content:encoded><![CDATA[<p><img src="/webrtc-blog/wrestleRTC.png" alt="Wrestler vs. WebRTC"></p>
<p><a href="https://wrestle-time.com">Live demo</a></p>
<h2 id="the-wrestling-backstory"><a href="#the-wrestling-backstory">The Wrestling Backstory</a></h2>
<p>Not too long ago, I helped my club wrestling team host a competition across three schools. To <a href="https://en.wikipedia.org/wiki/Scholastic_wrestling#Match_scoring">score a college
wrestling match</a>, you need a scoreboard,
a timer to track how much time is left in a period, and a special clock to track the riding time for the match.
Riding time is simple to calculate: while a wrestler has control of their opponent, they gain riding time. The riding time of a match
is shown as the absolute value of the difference of both wrestlers total time in control with an indicator of who has more. Below is an example of a
wrestling scoreboard:</p>
<p><img src="/webrtc-blog/example-time.png" alt="Wrestling Scoreboard"></p>
<p>The gym we used to host the competition already scoreboard that could handle the first three criteria, but we needed a way to track riding time. The timer we needed was simple, in fact it was simple enough to create a <a href="https://claude.site/artifacts/9ee4431e-f6f6-454f-9ee6-8ae03ad8dea7">Claude Artifact</a> last minute to score the event. However, I decided
to create a better version of this site which led me down the rabbit hole that is WebRTC.</p>
<h2 id="building-a-better-timer"><a href="#building-a-better-timer">Building a Better Timer</a></h2>
<p>While the Claude Artifact was good enough for the event, I decided to build a better one. There were 2 pain points I had while using the old version:</p>
<ol>
<li>No way to manually adjust the riding time.</li>
<li>No way to simultaneously control the timer and show it to the ref.</li>
</ol>
<p>Pain point 1 was trivial to implement (reset the timer with an offset for each adjustment).
Pain point 2 turned out to be a lot more interesting. During the match, we only had a single computer set aside to control the clock, so only the operator of the clock could
see the riding time of the match, making it hard for the ref to verify it was running correctly.</p>
<p>There were two approaches that came to mind to solve the problem:</p>
<ol>
<li>Mirror the computer's screen to a separate display (ex. tv, external monitor)</li>
<li>Extend website with a page that displays the riding time from another browser's clock</li>
</ol>
<p>Approach 1 is inconvenient as it requires platform specific technology (ex. airplay) or extra hardware (ex. tv, hdmi cord, and a power supply). Approach 2 is more flexible as it only requires two devices with modern browsers (ex. smartphones). Approach 2 is also a more interesting problem to work on so I went to work on designing a way to sync 2 instances of my site.</p>
<h2 id="approaches-to-sync"><a href="#approaches-to-sync">Approaches To Sync</a></h2>
<p>While brainstorming, I came up with three approaches to how to sync the instances:</p>
<ol>
<li>Use a managed synchronization service like <a href="https://www.convex.dev/">Convex</a> or <a href="https://zero.rocicorp.dev/">Zero</a></li>
<li>Use <a href="https://developers.cloudflare.com/durable-objects/">Cloudflare Durable Objects</a> to store clock sync and have both sites connect via <a href="https://en.wikipedia.org/wiki/WebSocket">WebSockets</a></li>
<li>Connect the two websites directly via a peer to peer protocol (<a href="https://en.wikipedia.org/wiki/WebRTC">WebRTC</a>)</li>
</ol>
<p>One of my goals was to make this run for as cheap as possible, crossing out approach one. Approach two was/is viable but I needed a Cloudflare paid plan to use durable objects. This led me to start with implementing approach three, which didn't need (as many) costly cloud servers.</p>
<h2 id="the-webrtc-protocol"><a href="#the-webrtc-protocol">The WebRTC protocol</a></h2>
<p>Before we go into my implementation, it's important to understand what <a href="https://en.wikipedia.org/wiki/WebRTC">WebRTC</a> is and how it works. At its core, WebRTC is a protocol built into most browsers that allows peer to peer connections. I'll be mainly using it to send data across devices but it can also be used to implement phone calls, video streaming and more.</p>
<p>Despite being peer to peer, a server is still needed to setup the connection. Available peers and their connection information are stored on <a href="https://antmedia.io/webrtc-signaling-servers-everything-you-need-to-know/">Signaling servers</a>. <a href="https://en.wikipedia.org/wiki/STUN">STUN servers</a> are used to attempt setup the connection. If setting up a direct connection is impossible (likely due to <a href="https://en.wikipedia.org/wiki/Network_address_translation">NAT</a> issues), a <a href="https://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT">TURN server</a> is used as a bridge to connect the two peers.</p>
<h2 id="implementation"><a href="#implementation">Implementation</a></h2>
<p><img src="/webrtc-blog/diagram.png" alt="Wrestle-Time Design"></p>
<p>My final design for Wrestle-Time consists of 4 elements:</p>
<ul>
<li>A "controller" to control the riding time tracker</li>
<li>A "receiver" to display the current riding time</li>
<li>A key-value database with WebRTC session metadata</li>
<li><a href="https://developers.cloudflare.com/calls/turn/generate-credentials/">Cloudflare Calls</a> (WebRTC <a href="https://getstream.io/blog/what-is-a-selective-forwarding-unit-in-webrtc/">SFU</a> platform)
<ul>
<li>A Selective Forwarding Unit (SFU) routes WebRTC connections between multiple participants instead of requiring each peer to connect to each other directly (helpful at scale)</li>
</ul>
</li>
</ul>
<p>Here's how it works:</p>
<ol>
<li>Browser chosen to control riding timer enters site and generates a controller with a unique code and WebRTC Session.</li>
<li>Controller writes the WebRTC session metadata to database with generated code as key.</li>
<li>Browser chosen to display riding time enters <span class="shiki solarized-light" style="background-color:#FDF6E3;color:#657B83" tabindex="0"><code><span class="line"><span>/receive/${code}</span></span></code></span> path on site.</li>
<li>Receiver fetches session data from database and creates a connection to Controller via Cloudflare Calls</li>
<li>Whenever riding time controller updates, updates are sent to the receiver in real time.</li>
</ol>
<p>Currently all of this is run on Cloudflare infrastructure under the free plan. This means that I am limited to creating 1,000 sessions per day unless I upgrade to the $5/month<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref aria-describedby="footnote-label">1</a></sup> paid plan where it is then 1,000,000 sessions.</p>
<p>Additionally using Cloudflare TURN servers and SFU's cost $0.05/gigabyte for outbound traffic. TURN servers are free when using Cloudflare SFU's and the first 1,000 gigabytes/month used towards either are free. Cloudflare STUN servers are free to use and public. This led me to use the SFU service as it cost the same while also scaling better for most cases.</p>
<h2 id="final-results"><a href="#final-results">Final Results</a></h2>
<p><img src="/webrtc-blog/wrestle-time.png" alt="Wrestle-Time Demo"></p>
<p>With WebRTC, I was able to create a scalable, simple to use riding time tracker for wrestling officials. All an official needs to do is enter the <a href="https://wrestle-time.com">Wrestle-Time.com</a> site and copy the displayed code onto another device. Both devices will then be synced to display the same data with the original device being able to make manual changes.</p>
<h2 id="caveats"><a href="#caveats">Caveats</a></h2>
<p>WebRTC has some downsides I wanted to address. The first being that the implementation of the protocol can vary from browser to browser, making it less reliable than other protocols like websockets. There are <a href="https://www.npmjs.com/package/webrtc-adapter">adapters</a> that help mitigate this problem, but I occasionally have difficulty connecting devices together.</p>
<p>Another downside is lack of mature tooling around the WebRTC protocol. The most popular libraries I saw were either unmaintained (<a href="https://github.com/simplewebrtc/SimpleWebRTC">SimpleRTC</a>) paid services (<a href="https://www.twilio.com/en-us/webrtc">Twilio</a>), or required  separate servers(<a href="https://peerjs.com/">PeerJS</a>). Luckily, learning the <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API">WebRTC Browser API</a> didn't turn out to be too bad.</p>
<h2 id="reflection"><a href="#reflection">Reflection</a></h2>
<p>Overall, I'm pretty happy with the cost and performance of my little riding time app.
I'll likely continue to add functionality until it can replace a wrestling scoreboard.
As I continue to work on it, I think it's important to point out that WebRTC may not be the
best option if I ever decide to monetize the project. Using a central server or solution like Cloudflare Durable Objects to track state would likely be more reliable at a not much higher cost<sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref aria-describedby="footnote-label">2</a></sup> (especially at my scale). While I enjoy playing with shiny new tech like peer to peer WebRTC, projects like these remind me that "old-fashioned" approaches are often simpler, better documented, and can offer similar if not better performance when optimized.</p>
<h2 id="update"><a href="#update">Update</a></h2>
<p><img src="/webrtc-blog/new-score.png" alt="New Scoreboard"></p>
<p>I ended up implementing a full wrestling scoreboard located at <a href="https://score.wrestle-time.com">score.wrestle-time.com</a>.
New features include:</p>
<ul>
<li>An adjustable timer for tracking wrestling periods</li>
<li>A buzzer that goes off when a period is over</li>
<li>Point tracking</li>
</ul>
<section data-footnotes class="footnotes"><h2 class="sr-only" id="footnote-label"><a href="#footnote-label">Footnotes</a></h2>
<ol>
<li id="user-content-fn-1">
<p>Not including tax or usage fees after plan limits are reached. <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩︎</a></p>
</li>
<li id="user-content-fn-2">
<p>This is because I'm using Cloudflare SFU servers to relay connections, which while cheaper than a websocket server isn't free. <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to reference 2" class="data-footnote-backref">↩︎</a></p>
</li>
</ol>
</section>]]></content:encoded>
    </item>
    <item>
      <title>An Opinionated Guide to Leetcode</title>
      <description>Various techniques to make algorithmic technical interviews easier</description>
      <pubDate>Fri, 01 Nov 2024 00:00:00 GMT</pubDate>
      <link>https://adamgluck.com/posts/leetcode</link>
      <guid isPermaLink="true">https://adamgluck.com/posts/leetcode</guid>
      <content:encoded><![CDATA[<p><img src="/leetcode/leetcode-diagram.png" alt="Leetcode Flow Chart"></p>
<h2 id="motivations"><a href="#motivations">Motivations</a></h2>
<p>If you're reading this, there's a high chance that I've recently did a mock interview with you.
This guide covers my personal opinions on how to pass a <a href="https://en.wikipedia.org/wiki/LeetCode">leetcode</a> style interview based
on my experience as an interviewee and mock interviewer.</p>
<h2 id="format-of-the-interview"><a href="#format-of-the-interview">Format of the Interview</a></h2>
<p>A technical interview will typically have the following stages:</p>
<ol>
<li>Introductions</li>
<li>Leetcode Problems</li>
<li>Opportunity To Ask Questions</li>
</ol>
<h3 id="introductions"><a href="#introductions">Introductions</a></h3>
<p>Both you and the interviewer(s) will go back and forth giving quick intros about yourselves.
Its important to practice this as it sets the tone for the interview. I recommend writing down
your intro as it will typically not vary much from between interviews.</p>
<p>The rough structure of my intro is below. You should try to match how in-depth you go
based on how your interviewer does his intro.</p>
<ul>
<li>Name and current position</li>
<li>Overview of recent experiences</li>
<li>Overview of relevant project (if you have one)</li>
<li>Mention of a hobby or two (what you do outside of work/school)</li>
<li>What you're looking for (Why that company?)</li>
</ul>
<h3 id="problems"><a href="#problems">Problems</a></h3>
<p>The interview will then give you 1+ leetcode problem(s) to solve with
your language of choice. New questions can expand on previous questions, requiring you to modify your old solution.
You will likely solve the question on a platform such as <a href="https://www.hackerrank.com/products/interview/">Hackerrank</a>
or <a href="https://codesubmit.io/codepair">CodePair</a>. Depending on the company, you may or may not have the ability to run code, use a debugger, or use Google.
You'll also get varying amounts of information on the problem so its up to you to clarify.</p>
<p>I recommend structuring your approach to solving the problem using the <strong>GLUCK</strong> method<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref aria-describedby="footnote-label">1</a></sup>.</p>
<ul>
<li><strong>G</strong>: Grasp understanding
<ul>
<li>Ask questions about inputs/outputs</li>
<li>Run through a simple case with the interviewer</li>
<li>Jot down notes as comments</li>
</ul>
</li>
<li><strong>L</strong>: Link to underlying patterns
<ul>
<li>Identify the applicable patterns for the problem</li>
<li>Mention your observations to the interviewer</li>
</ul>
</li>
<li><strong>U</strong>: Unveil your plan
<ul>
<li>Verbally go over your solution as a high level</li>
<li>Verify that the approach matches input/output criteria</li>
</ul>
</li>
<li><strong>C</strong>: Code and debug
<ul>
<li>Start writing code based on your plan</li>
<li>Talk through what you're doing with your interviewer</li>
</ul>
</li>
<li><strong>K</strong>: Know your solution
<ul>
<li>Go over <a href="https://en.wikipedia.org/wiki/Time_complexity">Time Complexity</a></li>
<li>Mention <a href="https://en.wikipedia.org/wiki/Bottleneck">Bottle Necks</a></li>
<li>Go Over Future improvements (if necessary)</li>
</ul>
</li>
</ul>
<h3 id="questions"><a href="#questions">Questions</a></h3>
<p>Assuming you solve the above problems in a timely matter, you will have time
at the end of the interview to ask questions about the company and your interviewer(s).</p>
<p>I recommend treating this section as an opportunity to gauge if the company is a good fit for you. This is typically the
least practiced of all the sections despite its importance as it will be used to help your interviewer(s) gauge your
interest in the company, personality, and curiosity.
I like to prepare a few questions about the company before the interview, as well as come up with a few
questions specific for your interviewer based on their intro.</p>
<p>Here are some topics you can ask about. I try to make this more of a conversation by asking follow-ups.</p>
<ul>
<li>Interviewers background (if they didn't mention in intro)
<ul>
<li>Follow up with technical questions if you have relevant experience</li>
<li>What made them join the company?</li>
</ul>
</li>
<li>Day to day in the company
<ul>
<li>I try to figure out if interviewer enjoys their day to day</li>
</ul>
</li>
<li>Company growth/future
<ul>
<li>You probably don't want to join a struggling company</li>
</ul>
</li>
<li>Career growth/scope of role
<ul>
<li>How long do promotions take</li>
<li>What kind of work will you do as an engineer</li>
</ul>
</li>
</ul>
<h2 id="solving-a-leetcode-problem"><a href="#solving-a-leetcode-problem">Solving A Leetcode Problem</a></h2>
<p>Solving a leetcode problem requires 4 things</p>
<ul>
<li>You need to know a programming language</li>
<li>You need to know how to use key data structures for that language</li>
<li>You need to have a toolbox of general purpose algorithms (<a href="https://hackernoon.com/14-patterns-to-ace-any-coding-interview-question-c5bb3357f6ed">ex. 14 common patterns</a>)</li>
<li>You need to know how efficient your algorithms are</li>
</ul>
<h3 id="choosing-a-language"><a href="#choosing-a-language">Choosing a language</a></h3>
<p>If you have an interview with short notice, I recommend using whatever language
you're currently most comfortable with. Otherwise Python will make your life easier.</p>
<p>I recommend Python for the following reasons</p>
<ul>
<li>Your interviewer likely knows it
<ul>
<li>If they don't its still easy to read</li>
</ul>
</li>
<li>Most data structures <strong>don't</strong> require imports
<ul>
<li>Exceptions include <a href="https://docs.python.org/3/library/heapq.html">heaps</a>
and the <a href="https://docs.python.org/3/library/collections.html">collections library</a> (alternatives to the built-in data structures)</li>
</ul>
</li>
<li>Lots of tricks to keep your solutions simple and succinct (<a href="https://github.com/amirgamil/Python-Interview-Tricks/blob/main/README.md">examples</a>)
<ul>
<li>My favorite trick is using <span class="shiki solarized-light" style="background-color:#FDF6E3;color:#657B83" tabindex="0"><code><span class="line"><span style="color:#657B83">dict_obj.get(key, default_value)</span></span></code></span> to query a Python dictionary (Python's version of a hashmap)</li>
</ul>
</li>
</ul>
<h3 id="mastering-data-structures"><a href="#mastering-data-structures">Mastering Data Structures</a></h3>
<p>A lot of leetcode problems involve changing the state of your input into a
data structure. At a minimum, you should known the following (or their equivalents for a specific language). Mastering them is ideal but knowing the
purpose and <a href="https://en.wikipedia.org/wiki/Time_complexity">time complexity</a> for each is usually enough.</p>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Array_(data_structure)">Array</a></li>
<li><a href="https://en.wikipedia.org/wiki/Queue_(abstract_data_type)">Queue</a></li>
<li><a href="https://en.wikipedia.org/wiki/Stack_(abstract_data_type)">Stack</a></li>
<li><a href="https://en.wikipedia.org/wiki/Hash_table">HashMap</a></li>
<li><a href="https://en.wikipedia.org/wiki/Heap_(data_structure)">Heap/PriorityQueue</a></li>
<li><a href="https://en.wikipedia.org/wiki/Graph_(abstract_data_type)">Linked List/Tree/Graphs</a> (They're all technically graphs)</li>
</ul>
<p>Some others that are good to know about are:</p>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Self-balancing_binary_search_tree">Self Balancing Trees</a></li>
<li><a href="https://en.wikipedia.org/wiki/Trie">Trie</a></li>
<li><a href="https://en.wikipedia.org/wiki/Skip_list">Skip list</a></li>
<li><a href="https://en.wikipedia.org/wiki/Bloom_filter">Bloom Filters</a></li>
<li><a href="https://en.wikipedia.org/wiki/Segment_tree">Segment Tree</a> and <a href="https://www.baeldung.com/cs/tree-segment-interval-range-binary-indexed">related</a></li>
</ul>
<p>I also recommend learning approaches to <a href="https://en.wikipedia.org/wiki/Concurrency_(computer_science)">Concurrency</a> for your language of choice.</p>
<h3 id="building-your-algorithm-toolbox"><a href="#building-your-algorithm-toolbox">Building your Algorithm Toolbox</a></h3>
<p>Leetcode questions tend to fall into one of the following categories:</p>
<ul>
<li>Simple usage of a data structure</li>
<li>Using a common pattern with minimal modification</li>
<li>Using a pattern with modifications to fit the problem</li>
<li>Using multiple patterns with modifications</li>
</ul>
<p>To be able to solve problems efficiently, you should learn the following
for at least the <a href="https://hackernoon.com/14-patterns-to-ace-any-coding-interview-question-c5bb3357f6ed">14 patterns</a></p>
<ul>
<li>How the pattern works</li>
<li>When to use the pattern (ex. sorted array -> binary search)</li>
<li>Bottle necks for the pattern</li>
</ul>
<p>Use these resources to learn:</p>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Introduction_to_Algorithms">Intro to Algorithms (CLRS)</a></li>
<li><a href="https://glucknotes.com/assets/compsci/EPI_2016.pdf">Elements of Programming Interviews</a></li>
<li><a href="https://glucko.github.io/codeprep/">Grokking the Coding Interview</a></li>
</ul>
<p>And these to practice</p>
<ul>
<li><a href="https://leetcode.com/">Leetcode</a></li>
<li><a href="https://neetcode.io/practice">Neetcode</a></li>
<li><a href="https://seanprashad.com/leetcode-patterns/">Sean Prashad Patterns</a></li>
</ul>
<h3 id="evaluating-your-algorithms"><a href="#evaluating-your-algorithms">Evaluating Your Algorithms</a></h3>
<p>After you solve a leetcode problem, you will likely to be
asked to evaluate your solution in terms of <a href="https://en.wikipedia.org/wiki/Computational_complexity">time and memory complexity</a>.</p>
<p>The trick for this section learn the time complexities of the previously mentioned patterns and
other common operations (ex. popping from a queue) and combining them together. Also be sure to clearly define what the <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span><sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref aria-describedby="footnote-label">2</a></sup> in <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="script">O</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathcal" style="margin-right:0.02778em;">O</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">)</span></span></span></span> is referring to when describing complexity.</p>
<p>Here are some tricks to know</p>
<ul>
<li>Sorting will take <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="script">O</mi><mo stretchy="false">(</mo><mi>n</mi><mo>∗</mo><mi>log</mi><mo>⁡</mo><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n*\log(n))</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathcal" style="margin-right:0.02778em;">O</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mop">lo<span style="margin-right:0.01389em;">g</span></span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">))</span></span></span></span> time
<ul>
<li>An exception to this is  <a href="https://en.wikipedia.org/wiki/Counting_sort">Counting Sort</a> being "linear" time</li>
</ul>
</li>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> recursive calls will require <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="script">O</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathcal" style="margin-right:0.02778em;">O</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">)</span></span></span></span> memory at minimum due to the <a href="https://en.wikipedia.org/wiki/Call_stack">Call Stack</a></li>
<li>Adding/Removing an item from a heap takes <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="script">O</mi><mo stretchy="false">(</mo><mi>log</mi><mo>⁡</mo><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log(n))</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathcal" style="margin-right:0.02778em;">O</span><span class="mopen">(</span><span class="mop">lo<span style="margin-right:0.01389em;">g</span></span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">))</span></span></span></span> where <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> is the size of the heap</li>
</ul>
<h2 id="debugging-in-interviews"><a href="#debugging-in-interviews">Debugging In Interviews</a></h2>
<p>Often times the hardest part of solving a leetcode problem is fixing your mistakes
in your solution on the spot. While the best way to avoid bugs is to take your time
while coding, the time crunch of the interview can make you rush and overlook details.
This section goes over some strategies to track down errors for different interview types.</p>
<h3 id="whiteboardtext-editor"><a href="#whiteboardtext-editor">Whiteboard/Text Editor</a></h3>
<p>These types of interviews tend to focus more on
your thought process over writing 100% correct code. However
you may still have errors in your thought process and will need to
identify where in your algorithm you went wrong.</p>
<p>The way I think about debugging is that you're trying to find the line of code
doesn't do what you think it does. Sometimes you can track this down with just intuition, but
it's important to have a structured approach in case you don't.</p>
<p>What I like to do is to create a simple input and trace its state in the code using comments.
I usually use an input I went over with the interviewer at the start of the problem unless you
have a specific input that you know fails.
Below is an example with the <a href="https://leetcode.com/problems/two-sum/description/">Two-Sum Problem</a>:</p>
<pre class="shiki solarized-light" style="background-color:#FDF6E3;color:#657B83" tabindex="0"><code><span class="line"><span style="color:#268BD2">input</span><span style="color:#859900"> =</span><span style="color:#657B83"> [</span><span style="color:#D33682">1</span><span style="color:#657B83">,</span><span style="color:#D33682">2</span><span style="color:#657B83">,</span><span style="color:#D33682">3</span><span style="color:#657B83">,</span><span style="color:#D33682">4</span><span style="color:#657B83">]</span></span>
<span class="line"><span style="color:#657B83">expected_output </span><span style="color:#859900">=</span><span style="color:#657B83"> [</span><span style="color:#D33682">1</span><span style="color:#657B83">,</span><span style="color:#D33682">3</span><span style="color:#657B83">]</span></span>
<span class="line"></span>
<span class="line"><span style="color:#586E75;font-weight:bold">def</span><span style="color:#268BD2"> two_sum</span><span style="color:#657B83">(nums, target):</span></span>
<span class="line"><span style="color:#657B83">    seen </span><span style="color:#859900">=</span><span style="color:#657B83"> {}</span></span>
<span class="line"><span style="color:#859900">    for</span><span style="color:#657B83"> i, num </span><span style="color:#859900">in</span><span style="color:#268BD2"> enumerate</span><span style="color:#657B83">(nums):</span></span>
<span class="line"><span style="color:#657B83">        complement </span><span style="color:#859900">=</span><span style="color:#657B83"> target </span><span style="color:#859900">-</span><span style="color:#657B83"> num</span></span>
<span class="line"><span style="color:#657B83">        seen[num] </span><span style="color:#859900">=</span><span style="color:#657B83"> i</span></span>
<span class="line"><span style="color:#859900">        if</span><span style="color:#657B83"> complement </span><span style="color:#859900">in</span><span style="color:#657B83"> seen:</span></span>
<span class="line"><span style="color:#859900">            return</span><span style="color:#657B83"> [seen[complement], i]</span></span>
<span class="line"><span style="color:#859900">    return</span><span style="color:#657B83"> []</span></span>
<span class="line"></span>
<span class="line"><span style="color:#93A1A1;font-style:italic"># Example trace</span></span>
<span class="line"><span style="color:#93A1A1;font-style:italic"># nums=[1,2,3,4], target=6</span></span>
<span class="line"><span style="color:#93A1A1;font-style:italic"># i=0: num=1, complement=5, seen={1:0}</span></span>
<span class="line"><span style="color:#93A1A1;font-style:italic"># i=1: num=2, complement=4, seen={1:0, 2:1} </span></span>
<span class="line"><span style="color:#93A1A1;font-style:italic"># i=2: num=3, complement=3, seen={1:0, 2:1, 3:2}</span></span>
<span class="line"><span style="color:#93A1A1;font-style:italic"># complement is in seen, output is [2,2]</span></span>
<span class="line"><span style="color:#93A1A1;font-style:italic"># Bug: value is added to seed before complement is checked in seen,</span></span>
<span class="line"><span style="color:#93A1A1;font-style:italic">#   allowing for an index to be returned twice</span></span></code></pre>
<p>The level of details in the comments will vary based on the problem. For Two-Sum,
I only tracked the state of the program at the if statement as the solution was relatively simple.
For more complicated problems, you may want to track the state per line by putting comments
next to each line of code instead.</p>
<h3 id="online-idecompiler"><a href="#online-idecompiler">Online IDE/Compiler</a></h3>
<p>If your interviewer allows you to execute code during the interview,
they likely value having a working solution more than the previous situation. Luckily, being able to run code gives
you a few tricks that can help narrow down your bugs.</p>
<h3 id="tracing-with-print-statements"><a href="#tracing-with-print-statements">Tracing with print statements</a></h3>
<p>This is essentially the same as the whiteboard strategy with print statements instead of comments.
I recommend labeling the variables you're tracking in the below style.</p>
<pre class="shiki solarized-light" style="background-color:#FDF6E3;color:#657B83" tabindex="0"><code><span class="line"><span style="color:#268BD2">print</span><span style="color:#657B83">(</span><span style="color:#586E75;font-weight:bold">f</span><span style="color:#2AA198">"Var1:</span><span style="color:#CB4B16">{</span><span style="color:#657B83">var1</span><span style="color:#CB4B16">}</span><span style="color:#2AA198">, Var2:</span><span style="color:#CB4B16">{</span><span style="color:#657B83">var1</span><span style="color:#CB4B16">}</span><span style="color:#2AA198">)</span></span></code></pre>
<h3 id="testing-out-small-parts-of-the-code"><a href="#testing-out-small-parts-of-the-code">Testing out small parts of the code</a></h3>
<p>For more complicated problems, it may be tricky to find problems by tracing.
One approach that may help is factoring out the different parts of your program into
smaller functions and verifying that each of them work as intended. This is known as <a href="https://en.wikipedia.org/wiki/Unit_testing">Unit</a>
Testing<sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref aria-describedby="footnote-label">3</a></sup>.</p>
<h3 id="ide-with-debugger"><a href="#ide-with-debugger">IDE with Debugger</a></h3>
<p>If the interviewer gives you a <a href="https://en.wikipedia.org/wiki/Debugger">debugger</a>, its useful to know how to use one. All you need to do is set a <a href="https://en.wikipedia.org/wiki/Breakpoint">breakpoint</a> where you think the code is wrong, and <a href="https://en.wikipedia.org/wiki/Stepping_(debugging)">step through</a> the code.</p>
<p>Keep in mind the above approaches are still applicable and could be better choices
depending on the situation.</p>
<h2 id="miscellaneous"><a href="#miscellaneous">Miscellaneous</a></h2>
<p>Even if you master every aspect of acing a leetcode style technical interview,
it may not be enough get you the job. The two things I recommend that can help
you stand out as a candidate is honing your communication skills and learning about system design.</p>
<h3 id="communication"><a href="#communication">Communication</a></h3>
<p>Being able to communicate clearly and confidently can make you a
much stronger candidate. The best way to practice this is to do mock interviews
with a wide variety of people. Also practice tailoring your communication style
towards your specific interviewer. There is no one size fits all for communication.</p>
<h3 id="system-design"><a href="#system-design">System Design</a></h3>
<p>Companies are hiring you for your ability to generate value for them, not
based on your ability to solve leetcode problems. Understanding how the underlying tech works for large scale systems along with the tradeoffs of different technologies can come in handy when talking to your interviewer, even
if the interview is not strictly a system design interview.</p>
<ul>
<li><a href="https://www.techinterviewhandbook.org/">Tech Interview Handbook</a>
<ul>
<li>In depth resource to technical and behavioral interviews</li>
</ul>
</li>
<li><a href="https://dataintensive.net/">Designing Data Intensive Systems</a>
<ul>
<li>Recommended for learning about system design</li>
</ul>
</li>
<li><a href="https://github.com/donnemartin/system-design-primer">System Design Primer</a> and <a href="https://www.hellointerview.com/learn/system-design/in-a-hurry/introduction">Hello Interview</a>
<ul>
<li>Useful for practicing system design interview questions</li>
</ul>
</li>
</ul>
<h3 id="other-tips"><a href="#other-tips">Other Tips</a></h3>
<ul>
<li>Ensure you clarify any assumptions you're making
<ul>
<li>"Can we assume the input fits in main memory?"</li>
</ul>
</li>
<li>Knowing the target time complexity for the solution can be a hint
<ul>
<li>For example, if you know that the time complexity should be <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="script">O</mi><mo stretchy="false">(</mo><mi>log</mi><mo>⁡</mo><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log(n))</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathcal" style="margin-right:0.02778em;">O</span><span class="mopen">(</span><span class="mop">lo<span style="margin-right:0.01389em;">g</span></span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">))</span></span></span></span> the answer is likely a form of binary search</li>
</ul>
</li>
<li>Listen for hints/suggestions from the interviewer
<ul>
<li>They'll often nudge you towards the right data structure or away from bad solutions</li>
</ul>
</li>
<li>Name variables based on what they're used for
<ul>
<li>Avoid overusing one letter names like "x" or "y"</li>
</ul>
</li>
<li>Be confident when asking/answering questions
<ul>
<li>Interviewers <strong>may</strong> try to get you to second guess your answer even if it's optimal (the answer may just be incorrect so be careful)</li>
</ul>
</li>
</ul>
<h2 id="concluding-thoughts"><a href="#concluding-thoughts">Concluding Thoughts</a></h2>
<p>While technical interviews can be intimidating, it's important
to remember that you wouldn't have gotten an interview if the company
didn't believe you can handle it. Interviews in general are expensive due to
it requiring both recruiter and engineer time (the latter being especially pricy). Stay confident and you'll crush your interviews!</p>
<section data-footnotes class="footnotes"><h2 class="sr-only" id="footnote-label"><a href="#footnote-label">Footnotes</a></h2>
<ol>
<li id="user-content-fn-1">
<p>May or may not be based off <a href="https://guides.codepath.com/compsci/UMPIRE-Interview-Strategy">UMPIRE</a> from codepath <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩︎</a></p>
</li>
<li id="user-content-fn-2">
<p>This is usually the size of the input. For example, if the problem is to sort a list, the number of elements in that list is <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span>. <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to reference 2" class="data-footnote-backref">↩︎</a></p>
</li>
<li id="user-content-fn-3">
<p>Some other useful strategies to know for when you land your job are <a href="https://en.wikipedia.org/wiki/Integration_testing">integration</a>, <a href="https://en.wikipedia.org/wiki/Property_testing">property</a>, and <a href="https://en.wikipedia.org/wiki/A/B_testing">A/B</a> testing. <a href="https://antithesis.com/blog/is_something_bugging_you/">Deterministic simulation testing</a> is also gaining popularity. <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to reference 3" class="data-footnote-backref">↩︎</a></p>
</li>
</ol>
</section>]]></content:encoded>
    </item>
    <item>
      <title>Building The Grade Guide</title>
      <description>The story of how I made The Grade Guide (and how you can too!)</description>
      <pubDate>Wed, 16 Oct 2024 00:00:00 GMT</pubDate>
      <link>https://adamgluck.com/posts/grade_guide</link>
      <guid isPermaLink="true">https://adamgluck.com/posts/grade_guide</guid>
      <content:encoded><![CDATA[<p><img src="/gradeblog/architecture.png" alt="Grade Guide Architecture">
<em>The Grade Guide's Architecture</em></p>
<h3 id="why-im-making-this"><a href="#why-im-making-this">Why I'm Making This</a></h3>
<p>Around this time last year, I launched the first public version of <a href="https://thegradeguide.com">TheGradeGuide.com</a>.
Now that I'm about done with this project, I wanted to share the journey of why and how I made this site! My goal with this
writeup is to reflect on my wins and mistakes while making this and to inspire other students to create their own Grade Guides for their colleges.</p>
<h2 id="part-1-building-the-dataset"><a href="#part-1-building-the-dataset">Part 1: Building the Dataset</a></h2>
<h3 id="realizing-grade-guide-was-possible"><a href="#realizing-grade-guide-was-possible">Realizing Grade Guide was Possible</a></h3>
<p>I was sitting in my data structures and algorithms class when my friend showed me <a href="https://gradetier.com/">GradeTier</a>: a site that showed
<a href="https://gradetier.com/osu/6549">anonymized past grade distributions for OSU class</a>.
I found this more interesting than learning about the <a href="https://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm">Ford-Fulkerson algorithm</a> and started down a rabbit hole. I began investigating how they got the data and found two reddit posts: one about <a href="https://www.reddit.com/r/OSU/comments/gljeqv/see_past_grade_distributions_for_the_ohio_state/">GradeTier</a> and one about <a href="https://www.reddit.com/r/OSU/comments/tj345f/instructor_ratings_for_scheduling/">OSUProfs (student survey result site)</a>. I then started wondering if there was a way to combine these sites to figure out which professors give the best grades</p>
<h3 id="acquiring-the-data"><a href="#acquiring-the-data">Acquiring The Data</a></h3>
<p>I started my investigation by sending a Reddit DM to the account the created the GradeTier post
asking about how they sourced the data. They directed me to <a href="https://codes.ohio.gov/ohio-revised-code/section-149.43">The Ohio Public Records Act</a>, which prompted me to email <a href="https://compliance.osu.edu/public-records">Ohio State's Public Records Division</a> asking for grade distribution data by professor. Unfortunately I was denied under the <a href="https://studentprivacy.ed.gov/ferpa">Federal Family Educational Rights and Privacy Act (FERPA)</a>. However, I found that requesting for anonymized grade distribution data and student survey results for professors separately was compliant.</p>
<h3 id="making-the-data-useful"><a href="#making-the-data-useful">Making the Data Useful</a></h3>
<p>The first set of data I received was a excel sheet of anonymized grade distributions by class. The shape of the (messy) data was roughly as follows:</p>
<pre class="shiki solarized-light" style="background-color:#FDF6E3;color:#657B83" tabindex="0"><code><span class="line"><span style="color:#657B83">Cleaned_Excel_Row = {</span></span>
<span class="line"><span style="color:#DC322F">  Term_Code,</span></span>
<span class="line"><span style="color:#DC322F">  Campus,</span></span>
<span class="line"><span style="color:#DC322F">  Subject,</span></span>
<span class="line"><span style="color:#DC322F">  Catalog,</span></span>
<span class="line"><span style="color:#DC322F">  Class_Number,</span></span>
<span class="line"><span style="color:#DC322F">  Title,</span></span>
<span class="line"><span style="color:#DC322F">  Total_Students,</span></span>
<span class="line"><span style="color:#DC322F">  A_Count,</span></span>
<span class="line"><span style="color:#DC322F">  A_Minus_Count,</span></span>
<span class="line"><span style="color:#DC322F">  ...</span></span>
<span class="line"><span style="color:#DC322F">  E_Count,</span></span>
<span class="line"><span style="color:#657B83">}</span></span></code></pre>
<p>While I was waiting for the student survey data I spent my time cleaning up the Excel sheet into a clean <a href="https://en.wikipedia.org/wiki/Comma-separated_values">csv</a> with <a href="https://pandas.pydata.org/">Pandas</a>. I also noticed that the "Class_Number" seemed to be a unique identifier (at least for the semester) for a class and was shown to students in <a href="https://www.instructure.com/canvas">Canvas</a>.</p>
<p>Eventually I received an (also messy) Excel sheet for the student survey data<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref aria-describedby="footnote-label">1</a></sup> with the below shape:</p>
<pre class="shiki solarized-light" style="background-color:#FDF6E3;color:#657B83" tabindex="0"><code><span class="line"><span style="color:#657B83">Cleaned_Excel_Row = {</span></span>
<span class="line"><span style="color:#DC322F">  Last_Name,</span></span>
<span class="line"><span style="color:#DC322F">  First_Name,</span></span>
<span class="line"><span style="color:#DC322F">  Subject,</span></span>
<span class="line"><span style="color:#DC322F">  Catalog,</span></span>
<span class="line"><span style="color:#DC322F">  Class_Number,</span></span>
<span class="line"><span style="color:#DC322F">  Term,</span></span>
<span class="line"><span style="color:#DC322F">  SEI_Responses,</span></span>
<span class="line"><span style="color:#DC322F">  SEI_Rating,</span></span>
<span class="line"><span style="color:#657B83">}</span></span></code></pre>
<p>Right away I noticed that each dataset has 4 matching keys: Subject (ex. MATH), Catalog (ex. 3341), Class Number (ex. 13169) and Term/Term Code (ex. "Fall 2020"/1242). I then opened up Pandas and looked to see whether this data could join together and if it was accurate. I discovered 3 things:</p>
<ol>
<li>Many classes have grade distributions but no student survey results</li>
<li>Some classes have survey results but no grade distributions</li>
<li>Classes with multiple parts (ex. lecture, lab, recitation) didn't always have their (Canvas) Class_Code in the grade distribution excel</li>
</ol>
<p>After some manual verification and email exchanges with the public records office I made the following discoveries:</p>
<ul>
<li>Survey results for PhD or Masters students were intentionally excluded by OSU due to FERPA</li>
<li>Grade Distributions for classes with under 10 students were also intentionally excluded by due to FERPA</li>
<li>For classes with multiple parts (ex. lecture, lab, recitation), each part will have its own class code with only one used in the grade distribution excel</li>
</ul>
<p>I then had to make some tradeoffs with how I joined the data: use grade distributions as a source of truth (left join), use student surveys as a source of truth (right join), keep all the data with missing gaps on either side (outer join). I decided that the grade distributions were the most important data to me and that I didn't care about survey results on their own, so I chose to do a left join. This led to a dataset that had grade distributions for every class taught for the past 5 years with student survey results (and professor info) if it existed.</p>
<h2 id="part-2-from-notebook-to-website"><a href="#part-2-from-notebook-to-website">Part 2: From Notebook to Website</a></h2>
<p><img src="/gradeblog/jupyter-profs.png" alt="Sample of the original Grade Guide Jupyter notebook">
<em>Early version of Grade Guide</em></p>
<h3 id="grade-guide-v0-the-prequel"><a href="#grade-guide-v0-the-prequel">Grade Guide v0: The Prequel</a></h3>
<p>By the time Autumn scheduling came around, I was determined to leverage (at the time) personal dataset to help me schedule classes. As Javascript scared me at the time, I whipped up a quick <a href="https://jupyter.org/">jupyter notebook</a> and made some <a href="https://plotly.com/python/">Plotly</a> charts. The notebook had 3 main uses:</p>
<ol>
<li>See past instances of a class being taught and a bar graph showing how many As, Bs, Cs, etc for each</li>
<li>See a bar graph of the average GPAs for a class by which professors taught it (shown in pic above)</li>
<li>See a bar graph on how what grades a professor gives based on which classes they teach</li>
</ol>
<p>At this point I was likely the only student who knew that it was possible to compare classes and professors based on historical grade data at Ohio State, so I felt like a wizard whenever I showed it to my friends. Eventually, I started getting enough requests where I began considering making Grade Guide a site and monetizing.</p>
<h3 id="grade-guide-v05-an-over-engineered-mess"><a href="#grade-guide-v05-an-over-engineered-mess">Grade Guide v0.5: An Over-engineered Mess</a></h3>
<p>When I officially decided I wanted to make Grade Guide a website, I had two major roadblocks: I knew nothing about how to make a website and I also disliked UI/UX design.
This made my attempts at making a webapp that met my standards tricky.</p>
<p>I ended up putting Grade Guide on hold until I got back from my internship at Amazon where I did full stack web dev (and conquered my fear of Javascript in the process). Once I got back I had both the knowledge of how to make the Grade Guide and the motivation to grind out building it solo (I was pretty bored at the time).</p>
<p>My approach to making Grade Guide was to start by modeling what kind of data views I wanted to see, and then
making a fronted to show the data in nice to use way. This let me focus on function instead of spending my time making mockups. I was optimizing for developer speed and ended up choosing <a href="https://www.convex.dev/">Convex</a> as a <a href="https://en.wikipedia.org/wiki/Backend_as_a_service">BaaS platform</a> since I had a poor experience in the past with Firebase and also got good vibes from one of the
company representatives from a past <a href="https://2022f.pennapps.com/">Hackathon</a> I attended. I also decided to use the <a href="https://nextjs.org/">Next.js</a> with the <a href="https://nextui.org/">NextUI</a> component library for the frontend.</p>
<p>Working with Convex was easy, in fact I would argue it was a bit too easy. After adding the core functionality to the site, I added a login, then reviews, and then upvotes/downvotes on the reviews. I would likely have kept adding new features (namely the ability to upload study materials to a class) to the site until I started sending early versions of my site to friends. Once I heard their feedback and saw them using it, I realized a lot of these extra features were distracting from Grade Guides core purpose: informing students with data, not opinions. I then began to work on stripping away everything but the core functionality.</p>
<h3 id="grade-guide-v075-turns-out-ui-mattered"><a href="#grade-guide-v075-turns-out-ui-mattered">Grade Guide v0.75: Turns Out UI Mattered</a></h3>
<p>For the next version of Grade Guide, I spent the majority of my time on website polish and providing new insights on the data I had. I also added Google Analytics as I needed a way to track usage as I removed user accounts. My mistake at this stage  was trying to salvage my UI components from the last version instead of creating from scratch with a clear goal in mind from the start. This led to me spending too much time trying to tweak my NextUI components instead of focusing on the actual user experience.</p>
<p>On the backend side of things it was around this stage where I started to optimize my data <a href="https://en.wikipedia.org/wiki/Database_schema">schema</a> for the site. The first update was making my data more <a href="https://en.wikipedia.org/wiki/Graph">graph</a>-like. By allowing a class to link to the professors that teach it (and vice-versa), exploring the site suddenly became much more natural for a user. I also spent time doing various optimizations to keep my data under Convex's free limits (removing redundant fields and indexes mainly)</p>
<p>At the end of this stage I started to get improved feedback from my friends, though realized I neglected something crucial: the mobile experience. I mainly tested my site on my laptop, which  led to the site looking sloppy on mobile devices. At this stage I became frustrated with NextUI and decided to cut my losses and rebuild my UI from the ground up.</p>
<h3 id="grade-guide-v10-the-final-remake"><a href="#grade-guide-v10-the-final-remake">Grade Guide v1.0: The Final Remake</a></h3>
<p>This version of the site had one goal: mobile friendliness from the ground up. I ended up choosing a new library called <a href="https://ui.shadcn.com/">Shadcn</a>, which promised a sleek but easy to customize components. I was also able to beta test <a href="https://v0.dev/">v0</a>, an AI platform to make UI components with Shadcn underneath. As this was my third attempt making the site, I was able to learn from my mistakes of adding too much functionality and not having a clear vision of what I building.</p>
<p>Two other key features I worked on was a universal professor/course search bar at the top of my screen and keeping the storage under the free limit after adding 2 new semesters. The search feature was easy as Convex had recently added a text search index feature, so adding a universal search only required creating a custom text field to search for my course and professor tables, searching both whenever the search box is updated, and showing the more relevant search result on top.</p>
<p>Optimizing my memory usage proved to be an interesting tradeoff. I had 3 main tables in my database: courses, professors, and instances. The first 2 tables are self explanatory while the instances table represent a specific section of a class being taught (ex. CSE 2221 by Professor Bucci from 12pm-1pm). This table had 2 compound indexes: subject-catalog for class lookups (CSE 2221) or first-last name of professor (Paolo Bucci) which were used for quickly getting relevant data for each course and professor page (among other things). However, this index used the majority of the free tier of my memory limits so it had to go. I ended up opting to storing the <a href="https://en.wikipedia.org/wiki/Primary_key">primary key</a> of each instance directly in their corresponding class or professor row. While this saved me storage space, it came at the cost of doing N database lookups for each class page where N is the number of instances for the class. I also used the index for subject level "explore" pages which led me to create a new table "departments" that had a list of all class and professor primary keys for each subject (ex. CSE, Math, Psych).</p>
<p>I also discovered that there was a <a href="https://classes.osu.edu/#/">public OSU site</a> that could be used to get some interesting data for classes like descriptions and number of units. I wanted to add this data to my site but also wanted to launch soon. To achieve this I used an API used internally on the OSU site and updated my database each first time a user view a class page.</p>
<h2 id="part-3-mission-accomplished"><a href="#part-3-mission-accomplished">Part 3: Mission Accomplished?</a></h2>
<p><img src="/gradeblog/homepage.png" alt="Current Grade Guide Home Page">
<em>Current Grade Guide Home Page</em></p>
<h3 id="my-first-launch"><a href="#my-first-launch">My First Launch</a></h3>
<p>Once I was happy with how the site looked, I launched with a <a href="https://www.reddit.com/r/OSU/comments/1855ja8/the_grade_guide_discover_the_best_professors/">reddit post</a> and discord message in OSU's CSE discord. To track feedback, I created a site email and google form and added it to my site's footer.</p>
<p>Most of my time at this page was listening to feedback and making slight visual tweaks. My original plan to monetize was to get around 5k monthly users. The idea was to reach out to local business on OSU's campus and charged them a bunch of money for non-intrusive ad space on my site. However once I reached 1k monthly users<sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref aria-describedby="footnote-label">2</a></sup> I decided that I would rather spend on my time on making cool stuff over marketing or managing other people to market for me.</p>
<h3 id="expansion-and-why-i-didnt"><a href="#expansion-and-why-i-didnt">Expansion (and why I didn't)</a></h3>
<p>Once I saw the positive reception I started to think about expanding to other schools. UT Austin was the first to come to mind as they were public, were subject to similar <a href="https://www.foia.gov/">Freedom of Information</a> as OSU was, and had a huge student population. I started with an email to their records department but unlike OSU, they would have charged me around $100 for the data! Luckily, they had recent <a href="https://reports.utexas.edu/spotlight-data/ut-course-grade-distributions">anonymized grade distribution data</a> and <a href="https://utexas.bluera.com/utexas/rpvl.aspx?rid=ef4a3ea5-e930-4005-9466-93cb6d23b424&#x26;regl=en-US">student evaluation reports</a> publicly available, though in unideal formats. With some python scripting I was able to download all of this data automatically and then parse it into a nice csv using some <a href="https://developer.mozilla.org/en-US/docs/Web/XPath">xpath</a> and <a href="https://en.wikipedia.org/wiki/Regular_expression">regex</a> expressions. Then with some Pandas, I was able to get the data almost identical to my OSU dataset for free (though only for the past 2 years).</p>
<p>Armed with this data, I began working on expanding my database to work with multiple schools. I ended up deciding on adding new indexed attributes on my department, course, and professor tables to identify which school they belonged to. Then, I would use decide which index depending on whether the site had the url param /OSU or /AUSTIN as a prefix.</p>
<p>While planning my launch, I came across a linkedin post advertising <a href="https://www.utgradesplus.com/">UT Grades Plus</a>. While I believed my site was better, I didn't want to spend my free time marketing my site at a school I didn't go to (if I wanted to market something I would rather start at OSU). I decided to just keep making my site focussed on OSU which also let me work on some other side projects.</p>
<h2 id="side-quests"><a href="#side-quests">Side Quests</a></h2>
<p>This section will discuss the new features I've gradually over the past year along with some other stories. The boring features I've added were new charts and metrics to show grade data such medians gpa, and how it changes over time (line graph). I chose to precalculate averages and medians for classes/professors tables and update whenever I add new instances. This led to the ability to sort classes and professors by GPA, making it easy to sort them "easiest and hardest". I also spent a lot of time tweaking my Plotly graphs to make them suitable for phones (removed the capture button and dragging).</p>
<h3 id="adding-in-ratemyprofessor"><a href="#adding-in-ratemyprofessor">Adding in RateMyProfessor</a></h3>
<p>My biggest upgrade was integrating <a href="https://www.ratemyprofessors.com/">RateMyProfessor</a> into Grade Guide. This turned out to be trivial as there was a unauthenticated graphql endpoint I was able to reverse engineer to get data from the site programmatically. To try and not upset the company, data from RateMyProfessor is never stored in my database, their endpoint is only called when a user presses a button, and I link to their webpage from my site. I currently show a professors scores, most common review tags, and a wordcloud of their 50 most recent reviews. The wordcloud uses <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers">webworkers</a> to ensure quick loading. Strangely a few people complained about this feature seemingly because it made their favorite professors look bad.</p>
<h3 id="making-the-worst-data-pipeline"><a href="#making-the-worst-data-pipeline">Making The Worst Data Pipeline</a></h3>
<p>Once the site was public, I had to make a data pipeline to update my database incrementally. My first attempt at this added data one instance at time, resulting in an extremely slow and bandwidth expensive operation. Additionally I did the operation multiple times on my dev database with attempts at speeding up the process via concurrent API requests to Convex. This led to race conditions that led certain uploads to fail which led me to go back to the slow, single threaded way. This process all in all cost 40-50 gigabytes of bandwidth for 2 semesters while my current pipeline is about 100-300 megabytes for ~15 semesters (each request now uploads a class instead of an instance).</p>
<h3 id="fixing-an-inefficient-search"><a href="#fixing-an-inefficient-search">Fixing an Inefficient Search</a></h3>
<p>When I was still on the Convex free tier, I had issues keeping my database bandwidth under the limits once I got past ~600 monthly users. Upon a bit of investigation, I realized that my search functions were using the majority of my bandwidth so reached out on the Convex Discord to try and find ways to optimize. After some discussion with their team, I realized the issues was actually quite trivial: I was calling the search functions on every key press in the search, which messed up the built in caching features of Convex. After adding a delay to the search calls in the form of a <a href="https://www.geeksforgeeks.org/debouncing-in-javascript/#">Debounce Filter</a>, my usage drastically went down.</p>
<h3 id="getting-a-sponsor"><a href="#getting-a-sponsor">Getting a Sponsor</a></h3>
<p>I eventually stopped actively working on Grade Guide and wanted to avoid paying for a site I was making $0 off of. At that point my only recurring cost was my BaaS provider (Convex) and my usage was only slightly above the free tier limits. After a few email exchanges, Convex (shoutout to <a href="https://www.linkedin.com/in/jamwt/">Jamie Turner</a>) generously offered to give me a better free plan in exchange for putting their logo in my sites footer. Though there are cheaper options to Convex (like <a href="https://pages.cloudflare.com/">Cloudflare Pages</a>): the developer experience, built in functionality, and customer support have been unmatched (at least in my short career).</p>
<h2 id="takeaways"><a href="#takeaways">Takeaways</a></h2>
<p>Looking back, this had been one of my favorite project for 3 reasons: I still use it, my friends use it, and random people (including professors) also use it. Having people get value out of your work is very motivating and makes the programming more fun. Here are some key takeaways from working on Grade Guide:</p>
<ul>
<li>Start with the core features of your app before adding extras
<ul>
<li>Even if they seem easy quality control becomes harder</li>
</ul>
</li>
<li>Move fast but make sure the developer experience stays good
<ul>
<li>BaaS providers like Convex help a lot with this</li>
</ul>
</li>
<li>It never hurts to ask for things (both data, help, or more)</li>
<li>If you go to a public university, you can likely follow my steps in this article to make a Grade Guide for your university</li>
</ul>
<section data-footnotes class="footnotes"><h2 class="sr-only" id="footnote-label"><a href="#footnote-label">Footnotes</a></h2>
<ol>
<li id="user-content-fn-1">
<p>Ohio State University was beginning to test a new survey at the time of writing so this may no longer be accurate. <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩︎</a></p>
</li>
<li id="user-content-fn-2">
<p>Measured from Google Analytics dashboard <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to reference 2" class="data-footnote-backref">↩︎</a></p>
</li>
</ol>
</section>]]></content:encoded>
    </item>
  </channel>
</rss>