<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://mteoh.com//feed.xml" rel="self" type="application/atom+xml" /><link href="https://mteoh.com//" rel="alternate" type="text/html" /><updated>2026-01-26T04:08:36+00:00</updated><id>https://mteoh.com//feed.xml</id><title type="html">mteoh.com</title><subtitle>Machine learning engineer and data scientist. Also Canadian. I work on systems that help people find things.</subtitle><author><name>Mathew Teoh</name></author><entry><title type="html">A tiny proof for a tiny LLM</title><link href="https://mteoh.com//blog/a-tiny-proof-for-a-tiny-llm.html" rel="alternate" type="text/html" title="A tiny proof for a tiny LLM" /><published>2026-01-25T17:00:00+00:00</published><updated>2026-01-25T17:00:00+00:00</updated><id>https://mteoh.com//blog/a-tiny-proof-for-a-tiny-llm</id><content type="html" xml:base="https://mteoh.com//blog/a-tiny-proof-for-a-tiny-llm.html"><![CDATA[<p>In this post, I’ll show you a tiny proof I used to convince myself I was using an API correctly.</p>

<style>
p, li, td, th {
  text-align: left;
}
img {
  max-width: 100%;
  height: auto;
}
</style>

<p>While working through <a href="https://skyzh.github.io/tiny-llm/" target="_blank">Tiny LLM - LLM Serving in a Week</a>, I ran into the following question:</p>
<blockquote>
  <p>If a sampling API accepts logits, is it OK to pass in log-probabilities instead?</p>
</blockquote>

<p>For my use case, the answer was yes! The proof in this post shows that:</p>
<ul>
  <li>Greedy decoding gives the same result from both logits and log-probabilities</li>
  <li>MLX’s categorical sampling behaves identically in both cases.</li>
</ul>

<p>More formally, given:</p>
<ul>
  <li><span class="margin-comment">Logits<span class="comment-text">If you’re new and are unsure about what logits are, scroll down and I’ll walk you through it.</span></span> vector: \(\vec{z}=\{z_1, \ldots, z_n\}\)</li>
  <li>Probability distribution: \(\vec{p}=\text{softmax}(\vec{z})\) with \(p_i = \frac{e^{z_i}}{\sum_{j}e^{z_j}}\)</li>
  <li>Logprobs \(\vec{\ell}=\log(\vec{p})\)</li>
</ul>

<p>We’ll prove the two statements below:</p>
<ol>
  <li>Greedy decoding using either logits \(\vec{z}\) or logprobs \(\vec{\ell}\) as input will produce the same result. That is, \(\underset{i}{\arg\max}{\space\vec{z}} = \underset{i}{\arg\max}{\space\vec{\ell}}\)</li>
  <li>The function <code class="language-plaintext highlighter-rouge">mlx.core.random.categorical</code> (<a href="https://ml-explore.github.io/mlx/build/html/python/_autosummary/mlx.core.random.categorical.html" target="_blank">Apple’s documentation</a>) takes logits \(\vec{z}\) as input, then:
    <ol>
      <li>Normalizes these logits into probabilities (via softmax), then</li>
      <li>Samples from these probabilities.</li>
    </ol>

    <p>Suppose you only had access to \(\vec{\ell}\) and <em>not</em> \(\vec{z}\). Show that applying <code class="language-plaintext highlighter-rouge">mlx.core.random.categorical</code> to \(\vec{\ell}\) is equivalent.</p>
  </li>
</ol>

<h2 id="proof">Proof</h2>
<p>If you’ve seen the derivation of a numerically stable softmax, this proof will look familiar. We’ll isolate a constant component and reason about what’s left.</p>

<p>For (1), given logprobs \(\vec{\ell}=\log(\vec{p})\), we have that:</p>

\[\ell_i = \log{p_i} = \log{\frac{e^{z_i}}{\sum_{j=1}^ne^{z_j}}} = z_i-\log{\sum_{j=1}^ne^{z_j}}\]

<p>The second term, \(\log{\sum_{j=1}^ne^{z_j}}\), is constant for all values of \(i\), so we can set \(M=\log{\sum_{j=1}^ne^{z_j}}\), giving us \(\ell_i = z_i -M\).</p>

<p>Then:</p>

\[\begin{aligned}
\underset{i}{\arg\max}{\space\vec{\ell}} &amp;= \underset{i}{\arg\max}\{\ell_1,\ldots,\ell_n\}\\
&amp; = \underset{i}{\arg\max}\{z_1-M,\ldots,z_n - M\} &amp;&amp; \small\text{(from above 👆)}\\
&amp; = \underset{i}{\arg\max}\{z_1,\ldots,z_n\} &amp;&amp; \substack{\text{(Adding }M\text{ doesn't change} \\ \text{where the max is)}}\\
&amp; = \underset{i}{\arg\max}{\space\vec{z}} &amp;&amp; \blacksquare
\end{aligned}\]

<p>To prove (2), note that when applying <code class="language-plaintext highlighter-rouge">mlx.core.random.categorical</code> to logits \(\vec{z}\), it means we’re sampling from the probability distribution given by \(\vec{p}=\text{softmax}(\vec{z})\).</p>

<p>Suppose we instead use \(\vec{\ell}\) as input to <code class="language-plaintext highlighter-rouge">mlx.core.random.categorical</code>. This is equivalent to using \(\vec{z}\) <strong>if and only if</strong> their probability distributions are the same, \(\text{softmax}(\vec{z})=\text{softmax}(\vec{\ell})\).</p>

<p>Let \(\vec{p}\prime=\text{softmax}(\vec{\ell})\). Then:</p>

\[\begin{aligned}
p\prime_i &amp; = \frac{e^{\ell_i}}{\sum_{j=1}^ne^{\ell_j}} &amp;&amp; \small\text{(definition of softmax)}\\
&amp;= \frac{e^{z_i - M}}{\sum_{j=1}^ne^{z_j - M}} &amp;&amp; \small\text{(above, we had $\ell_i = z_i -M$)}\\
&amp;= \frac{e^M \cdot e^{z_i - M}}{e^M \cdot\sum_{j=1}^ne^{z_j - M}} &amp;&amp; \small\text{(multiply top and bottom by $e^M$)}\\
&amp;= \frac{e^{z_i}}{\sum_{j=1}^ne^{z_j}} &amp;&amp; \small\text{(simplify)}\\
&amp;= p_i &amp;&amp; \small\text{(definition of $p_i$)}
\end{aligned}\]

<p>This holds for all values of \(i\in\{1,\ldots,n\}\), which gives us \(\text{softmax}(\vec{z})=\text{softmax}(\vec{\ell})\). Thus, when you use <code class="language-plaintext highlighter-rouge">mlx.core.random.categorical</code> here, it doesn’t matter whether you use logits or logprobs. \(\blacksquare\)</p>

<p>If you came here just to read a proof, you can skip everything below.</p>

<hr />

<h2 id="how-did-i-get-here">How did I get here?</h2>
<p>Last summer, while stuck in prompt engineering purgatory at work, I got curious about how Large Language Models <em>really</em> worked on the inside.</p>

<p>I found <a href="https://skyzh.github.io/tiny-llm/" target="_blank">Tiny LLM - LLM Serving in a Week</a>, which features a “week long” (spoiler: it took me longer than a week) set of <span class="margin-comment">programming exercises<span class="comment-text">I later learned about Stanford’s CS336 “Language Modeling from Scratch”, which is packed with similarly good stuff and more. I look forward to going through that as well some time.</span></span> where you implement Qwen2 from scratch using Apple’s mlx library.</p>

<p>The last section of Week 1 involves a small implementation of different sampling methods for decoding. For temperature sampling, the suggestion was to use <code class="language-plaintext highlighter-rouge">mlx.core.random.categorical</code> and pass in logprobs. I was confused because the <a href="https://ml-explore.github.io/mlx/build/html/python/_autosummary/mlx.core.random.categorical.html" target="_blank">documentation</a> for this function says it accepts logits, so I spent a few minutes proving to myself that I could use either.</p>

<h2 id="are-you-out-of-the-loop-on-llms">Are you out of the loop on LLMs?</h2>
<p>I definitely was, and if you’re all the way down here reading this, you might be too. To put logits in context, it helps to zoom out and see where they come from in a modern LLM.</p>

<p>I found the diagram below to be helpful in visualizing how LLMs look on the inside. It comes from Sebastian Raschka’s blog post “<a href="https://magazine.sebastianraschka.com/p/the-big-llm-architecture-comparison" target="_blank">The Big LLM Architecture Comparison</a>”.</p>

<p><img src="/assets/20260125-tiny-proof/llm-architecture-comparison.png" alt="LLM Architecture Comparison" /></p>

<p>If you came here for an explanation of where logits come from, I’m going to make some generalizations about LLMs. LLMs take as input a sequence of tokens (which represents some text), and predict the next token that’s likely to follow. To accomplish this, most of the open source models follow a similar pattern:</p>
<ol>
  <li>From input tokens, get their embeddings</li>
  <li>Go through several rounds of the following
    <ol>
      <li>Some type of attention mechanism</li>
      <li>Normalization</li>
      <li>Feedforward layer
(Optionally: skip-connections, positional embeddings, and other optimizations)</li>
    </ol>
  </li>
  <li>More normalization</li>
  <li>Linear layer</li>
</ol>

<p>Qwen2 (from the Tiny LLM course), even though not mentioned in the blog above, follows the same pattern.</p>

<p>The output of step (4) includes logits \(\vec{z}\), an \(n\)-dimensional vector (\(n\) is the number of tokens in our vocabulary). Each component \(z_i\) is an unnormalized (\(z_i\in[-\infty,\infty]\)) value; higher values correspond to tokens that are predicted to be more likely next in the sequence of text.</p>

<p>From here, it’s typical to compute \(\vec{p}=\text{softmax}(\vec{z})\) with \(p_i = \frac{e^{z_i}}{\sum_{j}e^{z_j}}\) (from the top), which gives us a probability distribution to sample from to produce the next token.</p>]]></content><author><name>Mathew Teoh</name></author><category term="blog" /><summary type="html"><![CDATA[In this post, I’ll show you a tiny proof I used to convince myself I was using an API correctly.]]></summary></entry><entry><title type="html">I never stop learning</title><link href="https://mteoh.com//blog/dont-debug-while-tired.html" rel="alternate" type="text/html" title="I never stop learning" /><published>2026-01-11T17:00:00+00:00</published><updated>2026-01-11T17:00:00+00:00</updated><id>https://mteoh.com//blog/dont-debug-while-tired</id><content type="html" xml:base="https://mteoh.com//blog/dont-debug-while-tired.html"><![CDATA[<p>I never stop learning the same lesson, because I keep forgetting it: don’t debug while you’re tired.</p>

<p><strong>TLDR: I spent an hour in dependency hell only to realize that my version of Ruby was old and needed a <span class="margin-comment">version bump<span class="comment-text">This is what happens when you don’t document your setup steps!</span></span>.</strong></p>

<h2 id="what-did-i-waste-my-hour-on">What did I waste my hour on?</h2>

<p>This week, I wanted to add something new to my blog (not this post of course… lol). I hadn’t touched this blog since late 2024. Since then, I had replaced my machine and no longer had the dev environment set up, including whatever Ruby version I had back then. My blog runs on Jekyll, and to set this up, I followed the steps from the <a href="https://jekyllrb.com/docs/">Jekyll quickstart page</a>, which were simple and looked something like this:</p>

<ol>
  <li>Install Ruby:
    <ol>
      <li><code class="language-plaintext highlighter-rouge">brew install chruby ruby-install</code></li>
      <li><code class="language-plaintext highlighter-rouge">ruby-install ruby 3.4.1</code></li>
    </ol>
  </li>
  <li>Install Jekyll: <code class="language-plaintext highlighter-rouge">gem install jekyll bundler</code></li>
  <li>Install more stuff: <code class="language-plaintext highlighter-rouge">bundle install</code></li>
  <li>Run the blog: <code class="language-plaintext highlighter-rouge">bundle exec jekyll serve</code></li>
</ol>

<details>
<summary>Click here to see the error I got.</summary>
<pre style="background-color: #f6f8fa; padding: 16px; border-radius: 6px; overflow-x: auto;"><code>% bundle exec jekyll serve
...
Generating...
Remote Theme: Using theme aterenin/minima-reboot
jekyll 3.9.3 | Error: SSL_connect returned=1 errno=0 peeraddr=140.82.116.10:443 state=error: certificate verify failed (unable to get certificate CRL)
/Users/mat/.rubies/ruby-3.4.1/lib/ruby/3.4.0/net/protocol.rb:46:in 'OpenSSL::SSL::SSLSocket#connect_nonblock': SSL_connect returned=1 errno=0 peeraddr=140.82.116.10:443 state=error: certificate verify failed (unable to get certificate CRL) (OpenSSL::SSL::SSLError)
from /Users/mat/.rubies/ruby-3.4.1/lib/ruby/3.4.0/net/protocol.rb:46:in 'Net::Protocol#ssl_socket_connect'
...
</code></pre>
</details>
<p><br />
Never seen this before. I should have created a README with the exact steps I used back then. After several tired exchanges with Codex, I thought I was getting somewhere: Ruby could not load my theme of choice.</p>

<div class="language-yml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># _config.yml</span>
<span class="na">remote_theme</span><span class="pi">:</span> <span class="s">aterenin/minima-reboot</span>
</code></pre></div></div>

<p>Since I was using a <code class="language-plaintext highlighter-rouge">remote_theme</code>, Ruby has to download that theme from somewhere remote. Doing so required Ruby to have SSL verification from Github. My version of Ruby apparently did not have that. What to do?</p>

<p>It was getting late, and I didn’t want to ruin my sleep by thinking too hard about this. I asked Codex to run some commands to fix this for me. That was a mistake, not because the suggestions were bad, but because I was too tired to evaluate them properly.</p>

<p>Codex tried many things, most of which felt increasingly desperate. Here are three I dug up.</p>

<details style="margin-bottom: 1em;">
<summary>Configuring my SSL certificates</summary>
<pre style="background-color: #f6f8fa; padding: 16px; border-radius: 6px; overflow-x: auto;"><code class="language-bash">export SSL_CERT_FILE=/opt/homebrew/etc/ca-certificates/cert.pem</code></pre>
</details>
<details style="margin-bottom: 1em;">
<summary>Rebuilding Ruby against Homebrew SSL</summary>
<pre style="background-color: #f6f8fa; padding: 16px; border-radius: 6px; overflow-x: auto;"><code class="language-bash">brew update
brew upgrade openssl@3 ca-certificates
brew postinstall ca-certificates
openssl s_client -connect codeload.github.com:443 -CAfile /opt/homebrew/etc/ca-certificates/cert.pem
RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl@3)" ruby-install ruby 3.4.1</code></pre>
</details>
<details style="margin-bottom: 1em;">
<summary>Running Jekyll with a custom OpenSSL config</summary>
<pre style="background-color: #f6f8fa; padding: 16px; border-radius: 6px; overflow-x: auto;"><code class="language-bash">cat &gt; /tmp/openssl_nocrl.cnf &lt;&lt;'EOF'
openssl_conf = openssl_init
[openssl_init]
ssl_conf = ssl_sect
[ssl_sect]
system_default = system_default_sect
[system_default_sect]
VerifyFlags = -CRL_CHECK
EOF
OPENSSL_CONF=/tmp/openssl_nocrl.cnf bundle exec jekyll serve</code></pre>
</details>

<p>The majority of this hour was me looking up what each of these approaches was actually doing, since I was not comfortable letting Codex run things I didn’t understand. By the end of the hour, none of these worked, and I don’t think my brain absorbed much that late at night. Off to bed.</p>

<h2 id="sleep-is-the-best-debugger">Sleep is the best debugger</h2>

<p>I woke up the next day and realized that <code class="language-plaintext highlighter-rouge">ruby-install ruby 3.4.1</code> looked similar to the command I ran the last time I worked on this blog. Maybe I should be on a newer version?</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ruby-install ruby 3.4.8
</code></pre></div></div>

<p>And a minute later, the rest of the steps:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gem <span class="nb">install </span>jekyll bundler
bundle <span class="nb">install
</span>bundle <span class="nb">exec </span>jekyll serve
</code></pre></div></div>

<p>It worked! Sleep is the best debugger! Pour one out for the hour of my life I will never get back.</p>

<p>Lesson learned, until next time… probably at 11:47pm.</p>]]></content><author><name>Mathew Teoh</name></author><category term="blog" /><summary type="html"><![CDATA[I never stop learning the same lesson, because I keep forgetting it: don’t debug while you’re tired.]]></summary></entry><entry><title type="html">Nerd-sniped by beatboxers</title><link href="https://mteoh.com//blog/nerd-sniped-by-beatboxers.html" rel="alternate" type="text/html" title="Nerd-sniped by beatboxers" /><published>2023-03-06T17:00:00+00:00</published><updated>2023-03-06T17:00:00+00:00</updated><id>https://mteoh.com//blog/nerd-sniped-by-beatboxers</id><content type="html" xml:base="https://mteoh.com//blog/nerd-sniped-by-beatboxers.html"><![CDATA[<p><strong>TLDR: If you scored 25th in the first round of wildcard solos, it’s still mathematically possible for you to make it to GBB (Top 11 overall), but impossible for you to get 1st place overall (after the 2 rounds of wildcards). If your first round was at least as good as 24th, 1st place overall is possible. No comments about probability… yet.</strong></p>

<h2 id="grand-beatbox-battle-is-here">Grand Beatbox Battle is here</h2>

<p>For beatboxing, it’s that time of year again. SwissBeatbox (SBX) has released the wildcard rankings for this year’s Grand Beatbox Battle (GBB) 2023 solos (<a href="https://www.instagram.com/p/CpN5CgPN64x/">full post</a>). If you’re not familiar, SwissBeatbox is a beatboxing YouTube channel that organizes one of the largest beatboxing competitions in the world.</p>

<p>(They had to update these rankings because they apparently <a href="https://www.reddit.com/r/beatbox/comments/11gv8ki/solo_wildcard_ranking_seems_to_be_incorrect/">messed up their spreadsheet</a>, but that’s another story!)</p>

<p>Here’s how GBB usually works:</p>

<ol>
  <li>Beatboxers submit a wildcard (i.e. an entry video) before some deadline.</li>
  <li>A team of judges evaluate each video based on things like originality, musicality, execution, etc.</li>
  <li>Beatboxers get a score for the video they sent, based on the judging.</li>
  <li>Some people get (reasonably) upset about the ranking, and I hold back the urge to tell everyone that the only acceptable ranking is the one where my favourites are on top. (Actually, why not try <a href="https://predictive-optimization.cs.princeton.edu/">predictive optimization</a>? 🤣)</li>
  <li>The top ranked beatboxers (usually ≈8) go to GBB to compete!</li>
</ol>

<h2 id="with-a-twist">With a twist</h2>

<p>This year, SBX added a second round of wildcard rankings. I’ll spare you the lengthy quote (<a href="https://swissbeatbox.com/newsfeed/gbb-2023-wildcard-competition/">page</a>). Here’s the gist:</p>

<ol>
  <li>Top 25 from the first round (above) submit a second wildcard video</li>
  <li>The judges rank these videos</li>
  <li>Your final score (??) is the average of your rank from the first and second rounds.</li>
  <li>Your final <em>rank</em> comes from this final score</li>
  <li>Top 11 make it to the GBB 23 event</li>
</ol>

<p>Here’s a small table for an example:</p>

<table class="table-bordered">
  <thead>
    <tr>
      <th>Beatboxer name</th>
      <th>Round 1 rank</th>
      <th>Round 2 rank</th>
      <th>Final score <br />(Average rank, smaller number is better)</th>
      <th>Final rank</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>a</td>
      <td>1</td>
      <td>2</td>
      <td>1.5</td>
      <td>1 🥇</td>
    </tr>
    <tr>
      <td>b</td>
      <td>2</td>
      <td>3</td>
      <td>2.5</td>
      <td>3 🥉</td>
    </tr>
    <tr>
      <td>c</td>
      <td>3</td>
      <td>1</td>
      <td>2</td>
      <td>2 🥈</td>
    </tr>
  </tbody>
</table>
<p><br /></p>

<div style="display: flex; flex-wrap: wrap;">
  <div style="flex: 1">
    <p>SBX conflates scores with ranks here (which I do not like), so I’ve assumed that:</p>
    <ul>
        <li>The final “score” comes from averaging the literal rank numbers from rounds 1 and 2.</li>
        <li>A lower “final score” is better (i.e. if your average is 1, you’re in first place).</li>
    </ul>
    <p>I’ll also assume that ties in the final ranks are valid, as long as it’s still clear who makes top 11 overall. For example, a 25-way tie doesn’t count (see the picture on the right), and we won’t consider that here.
</p>
  </div>
  <div style="flex: 1; padding: 10px; padding-left: 20px;">
    <figure>
    <img src="/assets/20230306beatbox-nerdsnipe/0001-25tie.png" alt="A 25-way tie. Who’s in the top 11? No one knows." style="max-width: 100%; height: auto;" />
    <figcaption style="color: #555; font-style: italic;">
    A 25-way tie. Who’s in the top 11? No one knows.
    </figcaption>
    </figure>
  </div>
</div>

<h2 id="if-you-came-25th-in-round-1-can-you-still-make-it-to-gbb">If you came 25th in Round 1, can you still make it to GBB?</h2>

<p>For solos, we really just care about the top 25 beatboxers, since they’re the only ones who submit a second wildcard.</p>

<p>If you came 25th in the first round, do you still have a chance to make it to GBB? <strong>In other words: if you placed 25th in Round 1, is it possible to score well enough in Round 2, so that your average places you in the Top 11 over all?</strong></p>

<p><strong>TLDR: yes.</strong></p>

<h5 id="case-study-1-everyones-performance-including-yours-is-exactly-the-same-between-rounds-1-and-2">❌ <strong>Case study 1: Everyone’s performance (including yours) is exactly the same between Rounds 1 and 2</strong></h5>

<p>This one’s pretty self-explanatory.</p>
<figure>
    <img src="/assets/20230306beatbox-nerdsnipe/0002-noChange.png" alt="Everyone performs the same between Rounds, so your position remains the same." style="max-width: 40%; height: auto;" />
    <figcaption style="color: #555; font-style: italic;">
    Everyone performs the between Rounds, so your position remains the same.
    </figcaption>
</figure>

<p>Let’s see what else could happen to you, based on what happens in Round 2.</p>

<h5 id="case-study-2-you-comes-1st-in-round-2-but-everyone-else-is-relatively-the-same">❌ <strong>Case study 2: You comes 1st in Round 2, but everyone else is relatively the same</strong></h5>

<p>By “relatively the same”, I mean that <code class="language-plaintext highlighter-rouge">a</code> scores 2nd in Round 2, <code class="language-plaintext highlighter-rouge">b</code> scores 3rd, and so on. Your final score is 14, and so is the final rank, so you don’t make it 😟.</p>

<figure>
    <img src="/assets/20230306beatbox-nerdsnipe/0003-1stRound2.png" alt="You placed 1st in Round 2, but didn’t make it to the top 11 overall." style="max-width: 40%; height: auto;" />
    <figcaption style="color: #555; font-style: italic;">
    You placed 1st in Round 2, but didn’t make it to the top 11 overall.
    </figcaption>
</figure>

<p>We can also see that your <strong>best possible final score</strong> after Round 2 is 13. This happens when you place 1st in Round 2. With this best possible score, was there any hope for you to make top 11 to begin with, provided that others place in <strong>just the right (wrong) way</strong>? Yes!</p>

<h5 id="case-study-3-you-place-1st-in-round-2-and-folks-k-to-x-have-a-bad-day">✅ <strong>Case study 3: You place 1st in Round 2, and folks <code class="language-plaintext highlighter-rouge">k</code> to <code class="language-plaintext highlighter-rouge">x</code> have a bad day.</strong></h5>

<p>For you to place top 11 overall, it depends on everyone performing in a very specific way during Round 2:</p>

<ol>
  <li>You rank 1st, giving your best final score of 13.</li>
  <li>Beatboxers <code class="language-plaintext highlighter-rouge">a</code>-<code class="language-plaintext highlighter-rouge">j</code> do (almost) just as well. <code class="language-plaintext highlighter-rouge">a</code> gets 2nd place, <code class="language-plaintext highlighter-rouge">b</code> gets 3rd, and so on. This gives each of them a final <em>score</em> smaller (i.e. better) than your 13, and a <em>rank</em> that looks identical to Round 1.</li>
  <li>Beatboxers <code class="language-plaintext highlighter-rouge">k</code>-<code class="language-plaintext highlighter-rouge">x</code> perform roughly <em>inversely</em> to how they did in Round 1. <code class="language-plaintext highlighter-rouge">k</code> places 25th (last), <code class="language-plaintext highlighter-rouge">l</code> places 24th, and so on. This gives them each a final score of 18, which is larger (i.e. worse) than your 13, and a 14-way tie for 12th place overall.</li>
</ol>

<figure>
    <img src="/assets/20230306beatbox-nerdsnipe/0004-youMake11th.png" alt="You placed 1st in Round 2, but didn’t make it to the top 11 overall." style="max-width: 40%; height: auto;" />
    <figcaption style="color: #555; font-style: italic;">
    You placed 1st in Round 2, and made it into the top 11 overall!
    </figcaption>
</figure>

<h2 id="11th-why-stop-there">11th? Why stop there?</h2>

<p>We’ve shown that placing 25th in Round 1 is not hopeless. You have hope: there exists a Round 2 ranking where you do well enough to place 11th overall, and make it to GBB.</p>

<p><strong>Next question: what’s the limit to this? Is there hope to make 10th place overall? 9th? What about 1st?</strong></p>

<p>We know two things so far:</p>

<ol>
  <li>You have hope to score <em>as least as well as</em> 11th overall. We showed this in the previous result.</li>
  <li>You can’t score 1st overall.</li>
</ol>

<p>To see why (2) is true, remember that your best final score is 13. Beatboxer <code class="language-plaintext highlighter-rouge">a</code>’s <em>worst overall score</em> is also 13 (this happens when they place 25th in Round 2), which means you can never score better than them.</p>

<p>Here’s the short answer: your best possible (overall) rank after Round 2 is 2nd place overall.</p>

<p>Here’s the slightly longer, math-y version:</p>
<ul>
  <li>To produce this outcome, beatboxers <code class="language-plaintext highlighter-rouge">b</code>-<code class="language-plaintext highlighter-rouge">x</code> need to have a final score that’s worse (i.e. larger) than your final score of 13.</li>
  <li>Beatboxer <code class="language-plaintext highlighter-rouge">b</code> achieves this only if their Round 2 rank is 25, giving a final score of 13.5</li>
  <li>Anything better than 25th in Round 2 gives a final score better than your 13.</li>
</ul>

<p>You can apply the same reasoning for the remainder of the list.</p>

<figure>
    <img src="/assets/20230306beatbox-nerdsnipe/0005-secondPlace.png" alt="It’s possible for you to score 2nd place overall." style="max-width: 40%; height: auto;" />
    <figcaption style="color: #555; font-style: italic;">
    It’s possible for you to score 2nd place overall.
    </figcaption>
</figure>

<h2 id="when-can-you-get-1st-overall">When can you get 1st overall?</h2>

<p>We showed that you can’t get 1st overall if you placed 25th in Round 1. How well do you have to do in Round 1 to have any hope of getting 1st overall?</p>

<p>We showed above that you can’t get 1st overall if you placed 25th in Round 1. This was because your <em>best</em> overall score, and <code class="language-plaintext highlighter-rouge">a</code>’s <em>worst</em> overall score, were both 13, so you couldn’t beat that. How well do you have to do in Round 1 (it has to be better than 25th, only way is up!) to have any hope of getting 1st overall?</p>

<p><strong>In other words: what needs to happen in Round 1 so that an overall score less (i.e. better) than 13 is possible?</strong></p>

<p>Short answer: placing 24th is good enough.</p>

<p>Long answer:</p>
<ul>
  <li>The final score is an average of your ranks from Rounds 1 and 2.</li>
  <li>Your best rank in Round 2 is 1st place, so we need an outcome (i.e. rank) in Round 1 that brings the average below 13 (beatboxer <code class="language-plaintext highlighter-rouge">a</code>’s best score).</li>
  <li>This can happen if you place 24th in Round 1, because the average of 24 and 1 is 12.5 &lt; 13.</li>
</ul>

<figure>
    <img src="/assets/20230306beatbox-nerdsnipe/0006-howFirst.png" alt="You get 1st place overall." style="max-width: 40%; height: auto;" />
    <figcaption style="color: #555; font-style: italic;">
    You get 1st place overall.
    </figcaption>
</figure>

<h2 id="final-thoughts">Final thoughts</h2>

<p>The math in this problem was not complicated at all, and the fun of this exercise lies mostly in reasoning about monotonic properties. For example, when we asked about you making top 11 overall, it was good enough to analyze what happened if you scored 1st place in Round 2.</p>

<p>Why? If we found that it was impossible, even after scoring 1st in Round 2, then no other outcome of Round 2 (you scoring 2nd, 3rd, etc.) would have helped you get to top 11 overall, <em>because they’re all strictly worse</em> than scoring 1st in Round 2! In fact, this is the reasoning we used to say that scoring 1st overall was impossible.</p>

<p>Finally, I gave examples to demonstrate that ranking 11th or 2nd overall was possible, but I haven’t thought long enough to say whether those examples are unique.</p>

<p>For example, maybe there are other Round 2 outcomes that would give you 11th overall, besides the one I shared. I also showed that these outcomes were <em>possible</em>, but did not say whether they were <em>probable</em>. That needs enough analysis (and assumptions) to make a second blog post.</p>

<hr />
<h2 id="addendum-mar-22-2023">Addendum Mar 22, 2023</h2>
<p>I posted this on the r/beatbox subreddit (<a href="https://www.reddit.com/r/beatbox/comments/11ynz2k/getting_nerd_sniped_by_gbb/">link</a>), and people got more excited about this than I expected.</p>

<h3 id="whats-the-worst-you-can-do-in-round-2-and-still-have-a-shot-at-getting-into-gbb">What’s the worst you can do in Round 2, and still have a shot at getting into GBB?</h3>
<p>User <code class="language-plaintext highlighter-rouge">Speek1Wif2Mee3</code> asked a great question (<a href="https://www.reddit.com/r/beatbox/comments/11ynz2k/comment/jd8yt55/">link</a>) that I really liked:</p>
<blockquote>
  <p>What is the lowest possible rank Remix can get in order to be in. First round he was 20th.</p>
</blockquote>

<p>And user <code class="language-plaintext highlighter-rouge">bjallen619</code> gave a great answer (<a href="https://www.reddit.com/r/beatbox/comments/11ynz2k/comment/jd9m7xg/">link</a>) that I also really liked:</p>
<blockquote>
  <p>I don’t know if this exactly answers what you’re asking, but I have a strong feeling that the answer is: 15th.</p>

  <p>Since we’re wondering the lowest score possible, then we don’t really care about the competitors ranked 1-10 after the first round—just the beatboxer ranked 11th (Stitch).</p>

  <p>Hypothetically if the beatboxer ranked #11 after round 1 was given 25th place in round 2, his average “score” would be (11+25)/2=18.</p>

  <p>At worst, Remix would need to beat that average “score”. (20+X)/2&lt;18 ; 20+X&lt;36 ; X&lt;16, hence 15th.</p>
</blockquote>

<p>Seems pretty good to me! To give you a sense of what that looks like, everyone else (11th-19th, and 21st-25th in the Round 1) would have to score a certain way.</p>

<figure>
    <img src="/assets/20230306beatbox-nerdsnipe/0007-remix.png" alt="If you scored 20th in Round 1, what's the bare minimum to make it to GBB?" style="max-width: 40%; height: auto;" />
    <figcaption style="color: #555; font-style: italic;">
    If you scored 20th in Round 1, what's the bare minimum to make it to GBB?
    </figcaption>
</figure>

<p>We can generalize this for any beatboxer who scored a rank of \(r_1\) in Round 1, \(r_2\) in Round 2, and final score \(r_{\text{final}}=\frac{r_1 + r_2}{2}\).</p>

<p>The question is: “Given your \(r_1\), what is the worst \(r_2\) you can get while still having a chance to make it to GBB?”</p>

<p><strong>TLDR</strong>: \(\boxed{r_2=\text{min}(35-r_1, 25)}\)</p>

<p>We can break this down into 3 cases.</p>
<style>
.details-section {
  background-color: #f5f5f5; /* change this to the desired color */
  padding: 10px; /* add padding for better readability */
}
</style>

<p>Case 1: \(r_1 \leq 10\).</p>
<details>
  <summary>👈 Click here for the Case 1 proof:</summary>
  <p></p>

  <div class="details-section">
  <div class="tip">
      <p>Consider a beatboxer \(c\) (your “competitor”) who scored 11th in Round 1. Assume everyone else who ranked above \(c\) (in Round 1) ranked the same in Round 2, which puts at most 9 beatboxers above you that you can’t beat.</p>

      <p>If you can beat \(c\) in Round 2, then you have a spot in GBB. With \(c_1=11\), we have that:
  \[
    c_{\text{final}}=\frac{11 + c_2}{2}.
  \]</p>

      <p>Since \(c_2 \in [1, 25]\) (i.e. our competitor can score anywhere from 1-25 in Round 2), then</p>

      <p>\[
    c_{\text{final}}\in[11.5, 18].
  \]</p>

      <p>The left boundary occurs when \(c_2=1\), and the right occurs when \(c_2=25\).</p>

      <p>If you scored \(r_2=25\), then</p>
      <ul>
        <li>\(c\)’s worst score is \(c_2=24\implies c_{\text{final}}=\frac{11 + 24}{2}=17.5\)</li>
        <li>Your final score is \(r_{\text{final}}=\frac{r_1 + 25}{2}\)</li>
      </ul>

      <p>Since \(r_1\leq10\), then \(r_{\text{final}}\leq\frac{10 + 25}{2}=17.5\). This means that if you score 25th in Round 2, it’s still possible to stay above \(c\) overall and make it to GBB: \(c\) just needs to score 24th in Round 2. (At the boundary of \(r_{\text{final}} =17.5\), you tie with \(c\), but this is not a problem. With 9 other beatboxers who ranked above you, there’s enough room for you and \(c\) in the top 11.)</p>

      <p>For this case, your worst possible Round 2 score (while still having a chance to make it to GBB) is 25th, which satisfies that claim that \(r_2=\text{min}(35-r_1, 25)\). (We have to use \(\text{min}\) here to cap the final number, because your \(r_2\) might go out of bounds, e.g. when \(r_1=1\).)</p>
    </div>
  </div>
</details>
<p><br />
Case 2: \(r_1=11\).</p>
<details>
  <summary>👈 Click here for the Case 2 proof:</summary>
  <p></p>

  <div class="details-section">
  <div class="tip">
      <p>You ranked 11th in Round 1, which puts 10 people ahead of you. The next in line to take your place is your competitor \(c\), who ranked 12th in Round 1 (\(c_1=12\)). How poorly can you do in Round 2 and still have a shot?</p>

      <p>What happens if you place 25th in Round 2? If we apply the logic from Case 1, we get a tie between you and \(c\).</p>
      <ul>
        <li>\(r_2=25\implies r_{\text{final}}=\frac{11+25}{2}=18\).</li>
        <li>In the best case, \(c_2=24\implies c_{\text{final}}=\frac{12+24}{2}=18\).</li>
      </ul>

      <p>Since there are 10 beatboxers ahead of you, this tie creates ambiguity on who makes 11th, so we can’t have it.</p>

      <p>If you rank 24th in Round 2 (\(r_2=24\)), then your best shot is when \(c_2=25\), which gives:</p>
      <ul>
        <li>\(r_{\text{final}}=\frac{11+24}{2}=17.5\), and</li>
        <li>\(c_{\text{final}}=\frac{12+25}{2}=18.5\).</li>
      </ul>

      <p>Thus, your worst possible Round 2 score (while still having a chance to make it to GBB) is 24th, which satisfies the claim that \(r_2=\text{min}(35-r_1, 25)\).</p>
    </div>
  </div>
</details>
<p><br />
Case 3: \(r_1&gt;11\).</p>
<details>
  <summary>👈 Click here for the Case 3 proof:</summary>
  <p></p>

  <div class="details-section">
  <div class="tip">
      <p>This is a straightforward application of the original reddit comment. Let’s consider again your competitor \(c\) who scored \(c_1=11\) in Round 1.</p>

      <p>Similar to the proof in Case 1, we have that: \(c_{\text{final}}\in[11.5, 18]\); \(c_{\text{final}}=18\) when \(c_2=25\).</p>

      <p>If \(c\) does poorly in Round 2 and gets \(c_2=25\), your final score needs to be \(r_{\text{final}}=\frac{r_1 + r_2}{2} &lt; 18\) for you to beat them and get top 11 overall.</p>

      <p>We can rearrange this give: \(r_2&lt;36-r_1\), which gives \(r_2\leq 35-r_1\). This means that if \(c_2=25\), you can score \(r_2=35-r_1\) and get 11th overall, which satisifies \(r_2=\text{min}(35-r_1, 25)\).</p>
    </div>
  </div>
</details>
<p><br /></p>]]></content><author><name>Mathew Teoh</name></author><category term="blog" /><summary type="html"><![CDATA[TLDR: If you scored 25th in the first round of wildcard solos, it’s still mathematically possible for you to make it to GBB (Top 11 overall), but impossible for you to get 1st place overall (after the 2 rounds of wildcards). If your first round was at least as good as 24th, 1st place overall is possible. No comments about probability… yet.]]></summary></entry></feed>