<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="atom.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://kb.buildingbetterteams.de/blog</id>
    <title>Knowledge Base Blog</title>
    <updated>2026-04-03T12:56:56.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://kb.buildingbetterteams.de/blog"/>
    <subtitle>Knowledge Base Blog</subtitle>
    <icon>https://kb.buildingbetterteams.de/img/favicon.webp</icon>
    <entry>
        <title type="html"><![CDATA[About Brian Graham]]></title>
        <id>https://kb.buildingbetterteams.de/blog/about-brian</id>
        <link href="https://kb.buildingbetterteams.de/blog/about-brian"/>
        <updated>2026-04-03T12:56:56.000Z</updated>
        <summary type="html"><![CDATA[I've been in your shoes. Solo developer, 10-person startup, 1000+ person maze—I've worked across company sizes from individual contributor to manager-of-managers. Started programming at seven, spent over a decade in the trenches.]]></summary>
        <content type="html"><![CDATA[<p>I've been in your shoes. Solo developer, 10-person startup, 1000+ person maze—I've worked across company sizes from individual contributor to manager-of-managers. Started programming at seven, spent over a decade in the trenches.</p>
<p>The technical problems are rarely the real problems. The real challenges are sociotechnical: building software with humans, creating teams that work together instead of against each other, aligning what we build with what actually matters.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-building-better-teams">Why Building Better Teams<a href="https://kb.buildingbetterteams.de/blog/about-brian#why-building-better-teams" class="hash-link" aria-label="Direct link to Why Building Better Teams" title="Direct link to Why Building Better Teams" translate="no">​</a></h2>
<p>In 2022, I moved to Berlin to challenge myself and started consulting. Most product engineering organizations are stuck in unsustainable processes—chasing aggressive growth, dropping in methodologies without understanding constraints, treating people like resources. I bring the human factor into the productivity equation with methodical, practical solutions that lead strategically to profitability.</p>
<p>People often mistake me for a product manager because I think about customer needs and bring product techniques into daily work. I'm also often assumed to have a business role because I bring business frameworks like Theory of Constraints into engineering contexts. This systemic vision lets me intervene where others haven't looked: understanding the whole system, not just the code.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-i-write-about">What I Write About<a href="https://kb.buildingbetterteams.de/blog/about-brian#what-i-write-about" class="hash-link" aria-label="Direct link to What I Write About" title="Direct link to What I Write About" translate="no">​</a></h2>
<p>Team dynamics, organizational design, scaling patterns, and the practical reality of building software with humans. Industry and tech-stack agnostic because the fundamental problems of coordination and value creation are universal.</p>
<p>You'll also find hobby projects, code tinkering, and perspectives from outside the business world.</p>
<p>Based in Berlin, working with teams globally. If you're dealing with Team Topologies, Conway's Law, breaking down silos, or figuring out how to ship software that matters, I write for people who've been there and want to build something better.</p>]]></content>
        <author>
            <name>Brian Graham</name>
            <uri>/blog/about-brian</uri>
        </author>
        <category label="about" term="about"/>
        <category label="author" term="author"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[The right way to email a git repository]]></title>
        <id>https://kb.buildingbetterteams.de/blog/git-bundle-email</id>
        <link href="https://kb.buildingbetterteams.de/blog/git-bundle-email"/>
        <updated>2020-01-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[How to use git bundles for code challenges and repository sharing]]></summary>
        <content type="html"><![CDATA[<p>You're tasked with reviewing the code challenge of another candidate. You download the <em>project.zip</em> file, extract it, and it doesn't run. You can't tell what part of the code is auto-generating scaffolding, or what part is the complex part. You can't really get an idea of if the code would work, or was even written by the candidate. You don't even know if they did the entire project in one big commit or not. As long as there's nothing horribly wrong, you'll pass them.</p>
<p>Most companies have some kind of code challenge in their interview process. While you may like or dislike this practice for different reasons, one thing that can easily remove a bunch of headaches here is to stop asking for zip-files of that project.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="git-bundle-a-better-solution">Git Bundle: A Better Solution<a href="https://kb.buildingbetterteams.de/blog/git-bundle-email#git-bundle-a-better-solution" class="hash-link" aria-label="Direct link to Git Bundle: A Better Solution" title="Direct link to Git Bundle: A Better Solution" translate="no">​</a></h2>
<p>Git already provides a wonderful feature called a "<strong>git bundle</strong>". It is a way to package a git repository into single file which contains the entire git repository, and even branches. Generating one is the easiest thing imaginable. If your present working directory is inside a repository, you can simply run this command:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">git bundle create your_name.bundle --all</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>File Naming Convention</div><div class="admonitionContent_BuS1"><p>There's no real convention for the file name. I personally just prefer receiving interview challenges with the name of the candidate and a meaningful extension.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-to-use-the-bundle">How to Use the Bundle<a href="https://kb.buildingbetterteams.de/blog/git-bundle-email#how-to-use-the-bundle" class="hash-link" aria-label="Direct link to How to Use the Bundle" title="Direct link to How to Use the Bundle" translate="no">​</a></h2>
<p>Ask the candidate to send you the file (I haven't had any spam issues with gmail so far). On your side simply download the file and clone it to a new folder somewhere:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">git clone &lt;path_to_bundle_file&gt;</span><br></span></code></pre></div></div>
<p>This works exactly like doing any normal git clone: a new folder is created with the entire project, except the "origin" is a local file (the bundle) instead of a web address to something like GitHub.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="interactive-tutorial">Interactive tutorial<a href="https://kb.buildingbetterteams.de/blog/git-bundle-email#interactive-tutorial" class="hash-link" aria-label="Direct link to Interactive tutorial" title="Direct link to Interactive tutorial" translate="no">​</a></h2>
<div style="max-width:1200px;margin:0 auto;padding:24px;background-color:#f9fafb;border-radius:8px"><div style="margin-bottom:32px;text-align:center"><h2 style="font-size:24px;font-weight:bold;margin-bottom:8px;display:flex;align-items:center;justify-content:center;gap:8px">📦 Git Bundle Interactive Demo</h2><p style="color:#6b7280">See how git bundles work in practice</p></div><div style="display:grid;grid-template-columns:1fr 1fr;gap:24px;align-items:start"><div style="display:flex;flex-direction:column;gap:12px"><h3 style="font-weight:600;margin-bottom:16px;display:flex;align-items:center;gap:8px">🌳 Workflow Steps</h3><div style="padding:12px;border-radius:8px;border:1px solid;transition:all 0.2s;cursor:pointer;border-color:#3b82f6;background-color:#eff6ff"><div style="display:flex;align-items:center;gap:8px;margin-bottom:8px"><div style="width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;background-color:#3b82f6;color:white">1</div><span style="font-weight:500">Navigate to your repository</span></div><div style="margin-bottom:8px;padding:8px;background-color:#1f2937;border-radius:4px;color:#10b981;font-family:monospace;font-size:14px">cd /path/to/your/project</div><p style="font-size:14px;margin-left:32px;color:#6b7280">First, navigate to your git repository directory</p></div><div style="padding:12px;border-radius:8px;border:1px solid;transition:all 0.2s;cursor:not-allowed;border-color:#e5e7eb;background-color:#f9fafb;opacity:0.5"><div style="display:flex;align-items:center;gap:8px;margin-bottom:8px"><div style="width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;background-color:#f3f4f6">2</div><span style="font-weight:500;color:#9ca3af">Create the bundle</span></div><div style="margin-bottom:8px;padding:8px;background-color:#1f2937;border-radius:4px;color:#10b981;font-family:monospace;font-size:14px;opacity:0.5">git bundle create interview_challenge.bundle --all</div><p style="font-size:14px;margin-left:32px;color:#9ca3af">Package your entire git repository into a single file</p></div><div style="padding:12px;border-radius:8px;border:1px solid;transition:all 0.2s;cursor:not-allowed;border-color:#e5e7eb;background-color:#f9fafb;opacity:0.5"><div style="display:flex;align-items:center;gap:8px;margin-bottom:8px"><div style="width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;background-color:#f3f4f6">3</div><span style="font-weight:500;color:#9ca3af">Verify the file was created</span></div><div style="margin-bottom:8px;padding:8px;background-color:#1f2937;border-radius:4px;color:#10b981;font-family:monospace;font-size:14px;opacity:0.5">ls -lah interview_challenge.bundle</div><p style="font-size:14px;margin-left:32px;color:#9ca3af">Check that the bundle file was successfully created</p></div><div style="padding:12px;border-radius:8px;border:1px solid;transition:all 0.2s;cursor:not-allowed;border-color:#e5e7eb;background-color:#f9fafb;opacity:0.5"><div style="display:flex;align-items:center;gap:8px;margin-bottom:8px"><div style="width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;background-color:#f3f4f6">4</div><span style="font-weight:500;color:#9ca3af">Clone from bundle (recipient)</span></div><div style="margin-bottom:8px;padding:8px;background-color:#1f2937;border-radius:4px;color:#10b981;font-family:monospace;font-size:14px;opacity:0.5">git clone interview_challenge.bundle project_review</div><p style="font-size:14px;margin-left:32px;color:#9ca3af">The interviewer can now clone directly from the bundle. This is also a good way to verify the bundle is valid.</p></div></div><div style="background-color:#1f2937;border-radius:8px;overflow:hidden"><div style="background-color:#374151;padding:8px 16px;display:flex;align-items:center;gap:8px"><span>💻</span><span style="color:#d1d5db;font-size:14px">Terminal</span><div style="margin-left:auto;display:flex;gap:4px"><div style="width:12px;height:12px;border-radius:50%;background-color:#ef4444"></div><div style="width:12px;height:12px;border-radius:50%;background-color:#eab308"></div><div style="width:12px;height:12px;border-radius:50%;background-color:#22c55e"></div></div></div><div style="padding:16px;min-height:256px;max-height:800px;overflow-y:auto;font-family:monospace;font-size:14px;color:#10b981"><div style="color:#6b7280">Click "Run Step" to see the command execution...</div></div><div style="background-color:#4b5563;padding:8px 16px;display:flex;gap:8px"><button style="display:flex;align-items:center;gap:8px;padding:4px 12px;border-radius:4px;border:none;cursor:pointer;font-size:14px;background-color:#2563eb;color:white">▶️ Run Step</button><button style="display:flex;align-items:center;gap:8px;padding:4px 12px;border-radius:4px;border:none;cursor:pointer;font-size:14px;background-color:#4b5563;color:white">🔄 Reset</button></div></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="additional-resources">Additional Resources<a href="https://kb.buildingbetterteams.de/blog/git-bundle-email#additional-resources" class="hash-link" aria-label="Direct link to Additional Resources" title="Direct link to Additional Resources" translate="no">​</a></h2>
<p>Of course, there are many more use cases for this feature than simple code interview submissions, and additional features I haven't described. For more details, you can also review the <a href="https://git-scm.com/docs/git-bundle" target="_blank" rel="noopener noreferrer" class="">Git Bundle Documentation</a>.</p>]]></content>
        <author>
            <name>Brian Graham</name>
            <uri>/blog/about-brian</uri>
        </author>
        <category label="git" term="git"/>
        <category label="interview" term="interview"/>
        <category label="code-challenge" term="code-challenge"/>
        <category label="development" term="development"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Moneyball Teams]]></title>
        <id>https://kb.buildingbetterteams.de/blog/2017/05/07/moneyball</id>
        <link href="https://kb.buildingbetterteams.de/blog/2017/05/07/moneyball"/>
        <updated>2017-05-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[If you search "We only hire the best," you'll discover that literally everyone only hires the best. How can 100% of businesses hire from the top 5% of the talent pool? What happens to the other 95% of developers?]]></summary>
        <content type="html"><![CDATA[<p>If you search "We only hire the best," you'll discover that literally everyone only hires the best. How can 100% of businesses hire from the top 5% of the talent pool? What happens to the other 95% of developers?</p>
<p>The answer is simple: it's nonsense. Nobody hires exclusively the best, nor should they. We don't even have industry-wide objective metrics to measure developers consistently.</p>
<p>This post explores how to build strong teams focused on total throughput instead of hiring based on abstract criteria where you can only hope for the best.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="learning-from-baseball-economics">Learning from Baseball Economics<a href="https://kb.buildingbetterteams.de/blog/2017/05/07/moneyball#learning-from-baseball-economics" class="hash-link" aria-label="Direct link to Learning from Baseball Economics" title="Direct link to Learning from Baseball Economics" translate="no">​</a></h2>
<p>In 2002, a pathologically losing baseball team in California faced a death blow: losing their star player. The 2011 film "Moneyball" documents how this revenue-poor team completely changed their hiring strategy and started winning games, permanently changing how team managers think about talent acquisition.</p>
<p>Oakland's team budget was <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>44</mn><mi>m</mi><mi>i</mi><mi>l</mi><mi>l</mi><mi>i</mi><mi>o</mi><mi>n</mi><mo separator="true">,</mo><mi>r</mi><mi>e</mi><mi>g</mi><mi>u</mi><mi>l</mi><mi>a</mi><mi>r</mi><mi>l</mi><mi>y</mi><mi>c</mi><mi>o</mi><mi>m</mi><mi>p</mi><mi>e</mi><mi>t</mi><mi>i</mi><mi>n</mi><mi>g</mi><mi>a</mi><mi>g</mi><mi>a</mi><mi>i</mi><mi>n</mi><mi>s</mi><mi>t</mi><mi>t</mi><mi>e</mi><mi>a</mi><mi>m</mi><mi>s</mi><mi>s</mi><mi>p</mi><mi>e</mi><mi>n</mi><mi>d</mi><mi>i</mi><mi>n</mi><mi>g</mi><mi>o</mi><mi>v</mi><mi>e</mi><mi>r</mi></mrow><annotation encoding="application/x-tex">44 million, regularly competing against teams spending over </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em"></span><span class="mord">44</span><span class="mord mathnormal">mi</span><span class="mord mathnormal" style="margin-right:0.01968em">ll</span><span class="mord mathnormal">i</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em"></span><span class="mord mathnormal">re</span><span class="mord mathnormal">gu</span><span class="mord mathnormal" style="margin-right:0.01968em">l</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em">r</span><span class="mord mathnormal" style="margin-right:0.01968em">l</span><span class="mord mathnormal">yco</span><span class="mord mathnormal">m</span><span class="mord mathnormal">p</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">in</span><span class="mord mathnormal" style="margin-right:0.03588em">g</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em">g</span><span class="mord mathnormal">ain</span><span class="mord mathnormal">s</span><span class="mord mathnormal">tt</span><span class="mord mathnormal">e</span><span class="mord mathnormal">am</span><span class="mord mathnormal">ss</span><span class="mord mathnormal">p</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">d</span><span class="mord mathnormal">in</span><span class="mord mathnormal" style="margin-right:0.03588em">g</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em">v</span><span class="mord mathnormal" style="margin-right:0.02778em">er</span></span></span></span>100 million. They achieved the same results with a fraction of the resources by applying basic math and statistical analysis to player evaluation.</p>
<p>The movie is really about math and business management rather than sports. It demonstrates how focusing on the right metrics can overcome resource constraints through smarter decision-making.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="rethinking-the-goal-of-hiring">Rethinking the Goal of Hiring<a href="https://kb.buildingbetterteams.de/blog/2017/05/07/moneyball#rethinking-the-goal-of-hiring" class="hash-link" aria-label="Direct link to Rethinking the Goal of Hiring" title="Direct link to Rethinking the Goal of Hiring" translate="no">​</a></h2>
<p>Your company's ambitions eventually exceeded what your development teams could deliver, forcing you to hire. The ultimate goal should be helping your team match your business ambitions.</p>
<p>Hiring "the best" seems obvious, but reveals two hidden traps:</p>
<p><strong>The widening capability-vs-ambition gap</strong>: If business ambitions grow constantly, they'll be out of sync with team capabilities. More work enters the system than can be completed. Reducing business ambitions to match team throughput makes you less likely to grow your product or innovate.</p>
<p><strong>The Individual Excellence Trap</strong>: Team throughput fluctuates due to upstream product changes, unclear direction, technical challenges, debt, process issues, and focus dilution. Hiring a brilliant individual may not address these systemic problems. Your "10x developer" could have their productivity divided by 10 when placed on a dysfunctional team.</p>
<p>The traditional view treats developers as interchangeable units with different capability levels ("Senior" or "Junior"). This ignores the open secret that one Senior Developer may be capable of wildly different things than another. This mindset implies individual contributors act as teams of one, rather than members who set each other up for success.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-better-hiring-framework">A Better Hiring Framework<a href="https://kb.buildingbetterteams.de/blog/2017/05/07/moneyball#a-better-hiring-framework" class="hash-link" aria-label="Direct link to A Better Hiring Framework" title="Direct link to A Better Hiring Framework" translate="no">​</a></h2>
<p>Business success requires positive return on investment over time. If hiring aims to increase throughput, the correct investment should maximize total business throughput, not simply add individual capability.</p>
<p>The goal isn't increasing "lines of code per day" or tickets completed per week. It's improving overall business delivery capacity, which may require changing business processes themselves.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="skills-matrix-done-right">Skills Matrix Done Right<a href="https://kb.buildingbetterteams.de/blog/2017/05/07/moneyball#skills-matrix-done-right" class="hash-link" aria-label="Direct link to Skills Matrix Done Right" title="Direct link to Skills Matrix Done Right" translate="no">​</a></h3>
<p>Most teams have Frontend/Backend developers, and hiring often focuses on increasing role specialization. However, teams need non-discipline-specific skills to function effectively. These sometimes surface in culture interviews, but we can do better with stronger focus.</p>
<p>A skills matrix becomes powerful when used correctly, but degenerates into trivia contests about algorithms, data structures, and syntax when used poorly. Focus your matrix on things teams do regularly:</p>
<ul>
<li class=""><strong>Technical discussions</strong></li>
<li class=""><strong>Code review</strong></li>
<li class=""><strong>Architecture decisions</strong></li>
<li class=""><strong>Scaling solutions</strong></li>
<li class=""><strong>Testing practices</strong></li>
<li class=""><strong>Code quality maintenance</strong></li>
<li class=""><strong>Mentoring others</strong></li>
<li class=""><strong>Pragmatic problem-solving</strong></li>
<li class=""><strong>Collaboration and motivation</strong></li>
</ul>
<p>Not all of these are technical skills, reflecting the reality that software development involves human factors as much as code. Choose skills meaningful to your specific organization.</p>
<p>Map these skills against mastery levels:</p>
<ul>
<li class=""><strong>Developing</strong>: Uninformed but learning</li>
<li class=""><strong>Proficient</strong>: Consistently applies skill well</li>
<li class=""><strong>Expert</strong>: Mentors others and leads thinking</li>
</ul>
<p>This framework clarifies your next investment decisions. Should you hire to cover specific team weaknesses? Which team members need training? Can you run peer mentorship programs? Do you have unchallenged experts with no growth opportunities?</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-power-of-focused-thinking">The Power of Focused Thinking<a href="https://kb.buildingbetterteams.de/blog/2017/05/07/moneyball#the-power-of-focused-thinking" class="hash-link" aria-label="Direct link to The Power of Focused Thinking" title="Direct link to The Power of Focused Thinking" translate="no">​</a></h2>
<p>Consider typical brainstorming sessions. Someone (usually the boss) stands at a whiteboard asking for random ideas, makes on-the-spot judgments, and after four hours the consensus covers only obvious or undesirable options.</p>
<p>Edward de Bono's "Six Thinking Hats" system addresses this problem by focusing intellectual effort into specific modes that ensure multiple perspectives. Teams using this system generate more innovative solutions faster and understand exactly what skill balance various tasks require. A team of average people can achieve amazing results without requiring 150+ IQs.</p>
<p>Apply this focused, specialized thinking to team building. Look for lateral solutions rather than always hiring more developers. Demand for "top x%" talent is highly competitive, time-consuming, and expensive.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="scale-horizontally-not-vertically">Scale Horizontally, Not Vertically<a href="https://kb.buildingbetterteams.de/blog/2017/05/07/moneyball#scale-horizontally-not-vertically" class="hash-link" aria-label="Direct link to Scale Horizontally, Not Vertically" title="Direct link to Scale Horizontally, Not Vertically" translate="no">​</a></h2>
<p>Instead of always seeking individual excellence, consider:</p>
<ul>
<li class=""><strong>Process improvements</strong> that multiply team effectiveness</li>
<li class=""><strong>Tool investments</strong> that reduce friction</li>
<li class=""><strong>Training programs</strong> that elevate team capabilities</li>
<li class=""><strong>Collaboration structures</strong> that leverage diverse strengths</li>
<li class=""><strong>Clear communication</strong> that reduces rework and confusion</li>
</ul>
<p>The goal is building teams where the whole exceeds the sum of parts, rather than collecting individual superstars who may not work well together.</p>
<p>Focus on total team throughput. Measure what matters for business outcomes. Invest in the combinations of skills and people that will actually move your organization forward.</p>
<p>Sometimes the best hire isn't the most impressive individual contributor. Sometimes it's the person who makes everyone else more effective, or fills the gaps.</p>]]></content>
        <author>
            <name>Brian Graham</name>
            <uri>/blog/about-brian</uri>
        </author>
        <category label="hiring" term="hiring"/>
        <category label="teams" term="teams"/>
        <category label="management" term="management"/>
        <category label="productivity" term="productivity"/>
        <category label="skills-matrix" term="skills-matrix"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[What Slows Development Teams]]></title>
        <id>https://kb.buildingbetterteams.de/blog/2017/11/22/what-slows-teams</id>
        <link href="https://kb.buildingbetterteams.de/blog/2017/11/22/what-slows-teams"/>
        <updated>2017-05-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article was originally published as a guest post for GitPrime in 2017, during the height of the Agile movement and the rise of DevOps practices. At the time, many teams were struggling with the transition from waterfall to iterative development, and developer productivity tools were primarily focused on basic metrics like commit frequency and lines of code.]]></summary>
        <content type="html"><![CDATA[<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>Historical Context</div><div class="admonitionContent_BuS1"><p>This article was originally published as a guest post for GitPrime in 2017, during the height of the Agile movement and the rise of DevOps practices. At the time, many teams were struggling with the transition from waterfall to iterative development, and developer productivity tools were primarily focused on basic metrics like commit frequency and lines of code.</p><p>Since then, the industry has evolved significantly with the emergence of DORA metrics, platform engineering, and more sophisticated approaches to measuring developer experience. However, the core challenges identified here around communication gaps between managers and developers, context switching, and misaligned incentives remain relevant today.</p></div></div>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>GitPrime Background</div><div class="admonitionContent_BuS1"><p>GitPrime was a developer analytics platform that provided insights into software development teams' productivity and processes. The company was later acquired by Pluralsight and integrated into their Flow product offering before being discontinued. This article represents thinking from the earlier era of developer productivity tooling, when the focus was primarily on code-based metrics rather than today's more holistic developer experience approaches.</p></div></div>
<p><em>Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.</em> – Douglas Hofstadter</p>
<p>Developers and managers both want scope and delivery time to align, but despite working toward a common goal, they rarely do. The gap is often so large that deadlines are missed, products become irrelevant, and teams face burnout.</p>
<p>Three major schools of thought explain why Hofstadter's Law persists in software development.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="three-theories-of-software-delays">Three Theories of Software Delays<a href="https://kb.buildingbetterteams.de/blog/2017/11/22/what-slows-teams#three-theories-of-software-delays" class="hash-link" aria-label="Direct link to Three Theories of Software Delays" title="Direct link to Three Theories of Software Delays" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="software-is-art">Software is Art<a href="https://kb.buildingbetterteams.de/blog/2017/11/22/what-slows-teams#software-is-art" class="hash-link" aria-label="Direct link to Software is Art" title="Direct link to Software is Art" translate="no">​</a></h3>
<p>This perspective treats software development as an inherently unpredictable creative process. Since we lack centuries of established practices, we're prone to underestimating challenges and struggling to predict timelines accurately. While some claims in this school are debatable, they correctly identify that our industry struggles with measuring work, which is fundamental to measuring success.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="software-vs-entropy">Software vs. Entropy<a href="https://kb.buildingbetterteams.de/blog/2017/11/22/what-slows-teams#software-vs-entropy" class="hash-link" aria-label="Direct link to Software vs. Entropy" title="Direct link to Software vs. Entropy" translate="no">​</a></h3>
<p>This theory focuses on complexity accumulation. More moving parts make software harder to grow, maintain, understand, onboard new developers to, and ship quickly. As systems evolve, technical debt and interdependencies create friction that compounds over time.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="productivity-declines">Productivity Declines<a href="https://kb.buildingbetterteams.de/blog/2017/11/22/what-slows-teams#productivity-declines" class="hash-link" aria-label="Direct link to Productivity Declines" title="Direct link to Productivity Declines" translate="no">​</a></h3>
<p>This approach attributes slowdowns to talent, process, and environment factors. Great developers with mismatched processes, inadequate developers for specific needs, or environments that prevent focused work on mentally challenging tasks all contribute to declining throughput.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="research-perspectives-on-team-velocity">Research: Perspectives on Team Velocity<a href="https://kb.buildingbetterteams.de/blog/2017/11/22/what-slows-teams#research-perspectives-on-team-velocity" class="hash-link" aria-label="Direct link to Research: Perspectives on Team Velocity" title="Direct link to Research: Perspectives on Team Velocity" translate="no">​</a></h2>
<p>To understand these dynamics better, we surveyed 50 professional programmers and managers about their daily experiences. While the sample size was small, it revealed telling patterns about how different roles perceive development challenges.</p>
<p>We asked participants about:</p>
<ul>
<li class="">Software release frequency</li>
<li class="">Their role (manager, developer, or both)</li>
<li class="">How often specific issues slow them down</li>
<li class="">What improves or hinders their work</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="key-findings">Key Findings<a href="https://kb.buildingbetterteams.de/blog/2017/11/22/what-slows-teams#key-findings" class="hash-link" aria-label="Direct link to Key Findings" title="Direct link to Key Findings" translate="no">​</a></h3>
<p><strong>Perception Gaps</strong>: Developers and managers experience the same problems differently. When we ranked issues by perceived severity, clear patterns emerged:</p>
<ul>
<li class=""><strong>All groups</strong> identified interruption and lack of focus as major problems</li>
<li class=""><strong>Monthly+ shipping teams</strong> saw changing product requirements as their biggest challenge, with fewer technical debt issues</li>
<li class=""><strong>Daily shipping teams</strong> had minimal design change problems but frequent technical challenges</li>
<li class=""><strong>Weekly shipping teams</strong> struggled across all categories</li>
</ul>
<p><strong>Role-Based Biases</strong>: Developer-managers perceived all issues as more frequent than peers filling only one role. Managers focused on business-side bottlenecks, while developers emphasized technical constraints.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-communication-divide">The Communication Divide<a href="https://kb.buildingbetterteams.de/blog/2017/11/22/what-slows-teams#the-communication-divide" class="hash-link" aria-label="Direct link to The Communication Divide" title="Direct link to The Communication Divide" translate="no">​</a></h3>
<p>This reveals a fundamental disconnect. Developers constantly request time to refactor or rewrite systems, which could indicate either:</p>
<ul>
<li class="">Communication breakdowns about technology and product trade-offs</li>
<li class="">Biased memory toward familiar technical challenges</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="driving-vs-restraining-forces">Driving vs. Restraining Forces<a href="https://kb.buildingbetterteams.de/blog/2017/11/22/what-slows-teams#driving-vs-restraining-forces" class="hash-link" aria-label="Direct link to Driving vs. Restraining Forces" title="Direct link to Driving vs. Restraining Forces" translate="no">​</a></h2>
<p><strong>What Helps Teams Move Faster:</strong></p>
<ul>
<li class="">Agile methodologies (overwhelmingly supported across all roles)</li>
<li class="">New frameworks and design patterns (developer favorites)</li>
<li class="">Process automation, especially UI testing and build improvements</li>
<li class="">Clear communication and stable priorities</li>
</ul>
<p><strong>What Holds Teams Back:</strong></p>
<ul>
<li class=""><strong>Managers</strong>: Changing priorities, communication failures, constant meetings</li>
<li class=""><strong>Developer-Managers</strong>: Slow automated processes, poor culture, firefighting</li>
<li class=""><strong>Developers</strong>: Context switching, unclear processes, overloaded sprints, technical debt</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-theory-of-constraints-in-software">The Theory of Constraints in Software<a href="https://kb.buildingbetterteams.de/blog/2017/11/22/what-slows-teams#the-theory-of-constraints-in-software" class="hash-link" aria-label="Direct link to The Theory of Constraints in Software" title="Direct link to The Theory of Constraints in Software" translate="no">​</a></h2>
<p>These perception gaps reflect a deeper organizational challenge. The Theory of Constraints describes two approaches to improving throughput:</p>
<p><strong>Cost Accounting</strong>: Maximize individual step efficiency, keeping everyone at full capacity
<strong>Throughput Accounting</strong>: Optimize total system output, allowing individual steps to operate below capacity</p>
<p>Cost accounting feels intuitive but creates competition between teams rather than collaboration. This mindset has caused manufacturing plants to fail, and it's equally problematic in software development.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="human-bias-in-problem-identification">Human Bias in Problem Identification<a href="https://kb.buildingbetterteams.de/blog/2017/11/22/what-slows-teams#human-bias-in-problem-identification" class="hash-link" aria-label="Direct link to Human Bias in Problem Identification" title="Direct link to Human Bias in Problem Identification" translate="no">​</a></h2>
<p>Our research reveals a predictable pattern: managers blame business-side issues while developers blame technical problems. Both groups attribute challenges to what they're most exposed to.</p>
<p>This isn't malicious. It's human nature. Without objective data, correctly identifying problems requires perfect memory, unbiased reasoning, accurate interpretation, immunity to social influence, and complete objectivity about one's own performance.</p>
<p><strong>Loss Aversion</strong> compounds these biases. We feel stronger pain from losses than equivalent gains. In software terms, cutting quality control feels like gaining speed, while upfront design work feels like losing development time. NASA research shows how this creates exponentially expensive defects later in the process.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-data-imperative">The Data Imperative<a href="https://kb.buildingbetterteams.de/blog/2017/11/22/what-slows-teams#the-data-imperative" class="hash-link" aria-label="Direct link to The Data Imperative" title="Direct link to The Data Imperative" translate="no">​</a></h2>
<p>Individual perspectives are too narrow to identify true bottlenecks. We need broader, objective measurement to understand what's actually happening.</p>
<p>Consider our finding that daily-shipping developers complained about build processes. Are these safeguards slowing total business throughput, or preventing production bugs that are orders of magnitude more expensive? Without data, we're just guessing.</p>
<p><strong>Meaningful metrics</strong> should answer questions like:</p>
<ul>
<li class="">Did our process changes improve outcomes?</li>
<li class="">Are we over-polishing features at the cost of shipping?</li>
<li class="">How do all-hands meetings affect productivity?</li>
<li class="">Which engineers created the biggest impact?</li>
<li class="">How much effort went toward technical debt?</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="moving-forward">Moving Forward<a href="https://kb.buildingbetterteams.de/blog/2017/11/22/what-slows-teams#moving-forward" class="hash-link" aria-label="Direct link to Moving Forward" title="Direct link to Moving Forward" translate="no">​</a></h2>
<p>Software engineering is notoriously difficult to measure, and easy metrics are often vanity metrics or unfair comparisons. But difficulty doesn't justify giving up on measurement entirely.</p>
<p>As Peter Drucker observed, "If you can't measure it, you can't improve it." Without data, we're stuck with guesses, opinions, and office politics.</p>
<p>The solution isn't eliminating human judgment, but complementing it with objective measurement that cuts through bias and subjectivity. Only then can we identify true constraints and make improvements that actually matter for total team throughput.</p>
<p>Meaningful data transforms subjective debates into objective problem-solving, helping teams align around what actually drives results rather than what feels important to individual roles.</p>]]></content>
        <author>
            <name>Brian Graham</name>
            <uri>/blog/about-brian</uri>
        </author>
        <category label="development" term="development"/>
        <category label="teams" term="teams"/>
        <category label="productivity" term="productivity"/>
        <category label="management" term="management"/>
        <category label="hofstadters-law" term="hofstadters-law"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Serve a Static Website as a Unikernel]]></title>
        <id>https://kb.buildingbetterteams.de/blog/2015/07/14/static-website-unikernel</id>
        <link href="https://kb.buildingbetterteams.de/blog/2015/07/14/static-website-unikernel"/>
        <updated>2015-07-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Unikernels are specialized, single-purpose operating systems that package your application with only the minimal OS components it needs to run. Think of them as extremely lightweight VMs that boot in milliseconds and use a fraction of traditional server resources.]]></summary>
        <content type="html"><![CDATA[<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>What are Unikernels and Rump Kernels?</div><div class="admonitionContent_BuS1"><p><strong>Unikernels</strong> are specialized, single-purpose operating systems that package your application with only the minimal OS components it needs to run. Think of them as extremely lightweight VMs that boot in milliseconds and use a fraction of traditional server resources.</p><p><strong>Rump Kernels</strong> take a unique approach: they let you extract specific drivers and components from existing operating systems (like NetBSD) and run them in userspace or as unikernels. This means you can use proven, mature OS components without the overhead of a full operating system. Your application gets direct access to high-performance networking, file systems, and other kernel services while maintaining strong isolation.</p><p>The result is applications that start faster, use less memory, have smaller attack surfaces, and can be deployed more efficiently than traditional containerized or VM-based approaches.</p></div></div>
<p>You'll learn how to use the Rumprun toolchain to build a unikernel that hosts your static website served by Nginx. This tutorial focuses on giving application and web developers practical steps to get running with Rump Kernel-based unikernels.</p>
<p>This assumes you're on a GNU/Linux or BSD system and familiar with command line basics.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-well-build">What We'll Build<a href="https://kb.buildingbetterteams.de/blog/2015/07/14/static-website-unikernel#what-well-build" class="hash-link" aria-label="Direct link to What We'll Build" title="Direct link to What We'll Build" translate="no">​</a></h2>
<p>We'll create a complete unikernel-based web server by:</p>
<ol>
<li class="">Setting up the Rumprun toolchain for building Rump Kernels</li>
<li class="">Compiling Nginx to run as a unikernel on QEMU</li>
<li class="">Configuring networking so you can access your site</li>
<li class="">Adding your static content to the unikernel</li>
<li class="">Setting up HTTPS support</li>
</ol>
<p>This is experimental technology, so some troubleshooting may be required. We'll explain the tools in enough detail that you can debug issues if they arise.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-setting-up-rumprun">1. Setting Up Rumprun<a href="https://kb.buildingbetterteams.de/blog/2015/07/14/static-website-unikernel#1-setting-up-rumprun" class="hash-link" aria-label="Direct link to 1. Setting Up Rumprun" title="Direct link to 1. Setting Up Rumprun" translate="no">​</a></h2>
<p>The Rumprun repository provides everything needed to develop unikernels based on Rump Kernel: debugging scripts, compiler tools, and NetBSD drivers as dependencies.</p>
<p>First, download the repository and its dependencies:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">git clone https://github.com/rumpkernel/rumprun</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">cd rumprun</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">git submodule update --init</span><br></span></code></pre></div></div>
<p>You'll need GCC installed (Rumprun doesn't yet support Clang). The exact package varies by distribution.</p>
<p>Choose your target platform. We'll use "hw" (hardware) rather than "xen" because it's easier to get started with. Even though we're building for hardware, we can test using virtual machines.</p>
<p>Build the toolchain:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">./build-rr.sh hw</span><br></span></code></pre></div></div>
<p>If this fails, you may need to install <code>binutils</code> on your system.</p>
<p>This compilation takes time as you're building both C and C++ components. When complete (it will say "build-rr ran successfully"), add the tools to your PATH:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">export PATH=${PATH}:$(pwd)/rumprun/bin</span><br></span></code></pre></div></div>
<p>Note: This PATH assignment is temporary. You'll lose it when you close the terminal or open new windows.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-building-nginx-as-a-unikernel">2. Building Nginx as a Unikernel<a href="https://kb.buildingbetterteams.de/blog/2015/07/14/static-website-unikernel#2-building-nginx-as-a-unikernel" class="hash-link" aria-label="Direct link to 2. Building Nginx as a Unikernel" title="Direct link to 2. Building Nginx as a Unikernel" translate="no">​</a></h2>
<p>Now we'll build a Nginx unikernel using an existing Rump package:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">git clone https://github.com/rumpkernel/rumprun-packages</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">cd rumprun-packages/</span><br></span></code></pre></div></div>
<p>Configure the package builder to use your Rumprun toolchain. Copy the configuration template and update it:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">cp config.mk.dist config.mk</span><br></span></code></pre></div></div>
<p>Edit <code>config.mk</code> and set:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">RUMPRUN_TOOLCHAIN_TUPLE=x86_64-rumprun-netbsd</span><br></span></code></pre></div></div>
<p>(Don't add <code>-gcc</code> or other suffixes)</p>
<p>Now build Nginx:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">cd nginx</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">make</span><br></span></code></pre></div></div>
<p>You'll need <code>genisoimage</code> installed (often in a package called <code>cdrkit</code>) to build ISO files for bare metal deployment.</p>
<p>After the build completes, "bake" the unikernel. First, see available platforms:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">rumprun-bake list</span><br></span></code></pre></div></div>
<p>Use <code>hw_virtio</code> for cloud deployment. Bake your unikernel:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">rumprun-bake hw_virtio ./nginx.bin bin/nginx</span><br></span></code></pre></div></div>
<p>Test the basic functionality:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">rumprun qemu -M 128 -i \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    -b images/data.iso,/data \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    -- nginx.bin -c /data/conf/nginx.conf</span><br></span></code></pre></div></div>
<p>You should see QEMU launch with debugging text. Success means no "panic" messages (though "rumprun: call to sigaction ignored" is normal). Rump Kernel has a different understanding of signals than you would expect on an operating system.</p>
<p><img decoding="async" loading="lazy" alt="QEMU running nginx unikernel" src="https://kb.buildingbetterteams.de/assets/images/nginx_success-f12f278ed005be82866ede25277fb570.jpeg" width="640" height="378" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-setting-up-network-access">3. Setting Up Network Access<a href="https://kb.buildingbetterteams.de/blog/2015/07/14/static-website-unikernel#3-setting-up-network-access" class="hash-link" aria-label="Direct link to 3. Setting Up Network Access" title="Direct link to 3. Setting Up Network Access" translate="no">​</a></h2>
<p>To access your web server, we'll create a TAP network device. This provides more flexibility than simple port forwarding for complex applications.</p>
<p>Create and configure the TAP device (may require sudo):</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">ip tuntap add tap0 mode tap</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ip addr add 10.0.120.100/24 dev tap0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ip link set dev tap0 up</span><br></span></code></pre></div></div>
<p>Choose a network range that doesn't conflict with your existing network. Verify the device works:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">ping 10.0.120.100</span><br></span></code></pre></div></div>
<p>Now launch Nginx with network access:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">rumprun qemu -i -M 128 \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    -I if,vioif,'-net tap,script=no,ifname=tap0'\</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    -W if,inet,static,10.0.120.101/24 \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    -b images/data.iso,/data \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    -- ./nginx.bin -c /data/conf/nginx.conf</span><br></span></code></pre></div></div>
<p>This command:</p>
<ul>
<li class="">Runs QEMU as the emulator</li>
<li class="">(<code>-i</code>) Attaches guest console on startup</li>
<li class="">(<code>-M</code>) Sets memory limit to 128MB</li>
<li class="">(<code>-I</code>) Creates guest network interface with iftag</li>
<li class="">(<code>-W</code>) Configures VM network address (different from TAP interface)</li>
<li class="">(<code>-b</code>) Mounts data.iso as block device on <code>/data</code></li>
<li class="">(<code>--</code>) Starts nginx with specified config</li>
</ul>
<p>If successful, you can visit <code>http://10.0.120.101</code> in your browser to see the default page.</p>
<p><img decoding="async" loading="lazy" alt="Nginx running in browser" src="https://kb.buildingbetterteams.de/assets/images/nginx_browser-3e7cb9c1cf13dcee8cdb083ab8268f0f.jpeg" width="640" height="515" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-adding-your-static-content">4. Adding Your Static Content<a href="https://kb.buildingbetterteams.de/blog/2015/07/14/static-website-unikernel#4-adding-your-static-content" class="hash-link" aria-label="Direct link to 4. Adding Your Static Content" title="Direct link to 4. Adding Your Static Content" translate="no">​</a></h2>
<p>Your website files go in <code>./images/data/www</code> and Nginx configuration in <code>./images/data/conf</code>. Simply replace the www directory contents with your static site.</p>
<p>For static site generation, consider tools like Jekyll, Hugo, or Sculpin.</p>
<p>To see new content:</p>
<ol>
<li class="">Stop the running unikernel</li>
<li class="">Rerun <code>make</code> in the nginx directory</li>
<li class="">Re-bake with <code>rumprun-bake</code></li>
<li class="">Launch with <code>rumprun qemu</code></li>
</ol>
<p><strong>Important</strong>: Don't modify the filesystem image while the guest is running. Use different image names when building new versions.</p>
<p>If you have connection issues, verify your tap0 device hasn't lost its IP address or gone down when you killed the emulator.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="5-adding-https-support">5. Adding HTTPS Support<a href="https://kb.buildingbetterteams.de/blog/2015/07/14/static-website-unikernel#5-adding-https-support" class="hash-link" aria-label="Direct link to 5. Adding HTTPS Support" title="Direct link to 5. Adding HTTPS Support" translate="no">​</a></h2>
<p>Configure SSL in your <code>nginx.conf</code> under the <code>server {</code> section:</p>
<div class="language-nginx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-nginx codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">listen 443 ssl;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">listen [::]:443 ssl;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ssl_certificate /data/conf/ssl-cert.crt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ssl_certificate_key /data/conf/ssl-cert.key;</span><br></span></code></pre></div></div>
<p>Generate a self-signed certificate or use your production certificates. Place the certificate files in the conf directory.</p>
<p>After updating the configuration:</p>
<ol>
<li class="">Remove build artifacts in <code>./build/</code></li>
<li class="">Run <code>make</code></li>
<li class="">Re-bake with <code>rumprun-bake</code></li>
<li class="">Launch with <code>rumprun qemu</code></li>
</ol>
<p>Your site will now be available over HTTPS.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="6-what-youve-accomplished">6. What You've Accomplished<a href="https://kb.buildingbetterteams.de/blog/2015/07/14/static-website-unikernel#6-what-youve-accomplished" class="hash-link" aria-label="Direct link to 6. What You've Accomplished" title="Direct link to 6. What You've Accomplished" translate="no">​</a></h2>
<p>You now have the fundamentals to host unikernel applications based on Rump Kernel. This approach offers several advantages:</p>
<ul>
<li class=""><strong>Fast scaling</strong>: Unikernels boot in milliseconds, enabling rapid scale-up and scale-down</li>
<li class=""><strong>Resource efficiency</strong>: Minimal memory and CPU overhead compared to traditional VMs</li>
<li class=""><strong>Security</strong>: Reduced attack surface with only necessary OS components</li>
<li class=""><strong>Deployment flexibility</strong>: Can run on cloud hypervisors or directly on hardware</li>
</ul>
<p>You can build on these basics to create more interactive applications, run PHP applications in immutable images, or deploy applications directly on hardware without a traditional operating system.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="resources">Resources<a href="https://kb.buildingbetterteams.de/blog/2015/07/14/static-website-unikernel#resources" class="hash-link" aria-label="Direct link to Resources" title="Direct link to Resources" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://rumpkernel.github.io/" target="_blank" rel="noopener noreferrer" class="">Rump Kernels Project</a></li>
<li class=""><a href="http://backreference.org/2010/03/26/tuntap-interface-tutorial/" target="_blank" rel="noopener noreferrer" class="">TUN/TAP Interface Tutorial</a></li>
<li class=""><a href="https://github.com/rumpkernel/rumprun" target="_blank" rel="noopener noreferrer" class="">Rumprun GitHub Repository</a></li>
</ul>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>Lost Blog Post</div><div class="admonitionContent_BuS1"><p>I previously wrote a blog post explaining how to host Symfony 2 PHP applications on a Rump Kernel, but I've lost the original content. If anyone has a copy or link to this post, please send it my way! It covered more advanced topics around running dynamic web applications as unikernels.</p></div></div>]]></content>
        <author>
            <name>Brian Graham</name>
            <uri>/blog/about-brian</uri>
        </author>
        <category label="unikernel" term="unikernel"/>
        <category label="rumpkernel" term="rumpkernel"/>
        <category label="nginx" term="nginx"/>
        <category label="virtualization" term="virtualization"/>
        <category label="containers" term="containers"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Your Monitor Is Awful]]></title>
        <id>https://kb.buildingbetterteams.de/blog/2012/01/21/your-monitor-is-awful</id>
        <link href="https://kb.buildingbetterteams.de/blog/2012/01/21/your-monitor-is-awful"/>
        <updated>2012-01-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Your monitor is awful. Not because you bought the wrong one, and not because it lacks enough pixels. Computer displays have evolved dramatically since the days of punch cards and blinking lights on supercomputers, eventually progressing through oscilloscopes to today's flat, lightweight panels with high resolution and millions of colors.]]></summary>
        <content type="html"><![CDATA[<p>Your monitor is awful. Not because you bought the wrong one, and not because it lacks enough pixels. Computer displays have evolved dramatically since the days of punch cards and blinking lights on supercomputers, eventually progressing through oscilloscopes to today's flat, lightweight panels with high resolution and millions of colors.</p>
<p>Yet despite these advances, we've hit a wall.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-diminishing-returns-of-more">The Diminishing Returns of "More"<a href="https://kb.buildingbetterteams.de/blog/2012/01/21/your-monitor-is-awful#the-diminishing-returns-of-more" class="hash-link" aria-label="Direct link to The Diminishing Returns of &quot;More&quot;" title="Direct link to The Diminishing Returns of &quot;More&quot;" translate="no">​</a></h2>
<p>As a programmer, I prefer dual monitors, but there's a limit to how much screen real estate actually helps. My two Acer monitors cost under $150 each, have lasted over three years without dead pixels, and provide roughly four feet of working display. Adding more screens beyond this point creates more problems than solutions: suddenly I'm moving my head constantly, losing track of windows, and spending more time managing my workspace than working in it.</p>
<p>The market has responded by pushing the same tired metrics: bigger screens, higher contrast ratios, more pixels. You can find 70-inch monitors on Amazon, waterproof displays, wall projections, but this approach misses the fundamental purpose of a display.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="innovation-has-stalled-where-it-matters-most">Innovation Has Stalled Where It Matters Most<a href="https://kb.buildingbetterteams.de/blog/2012/01/21/your-monitor-is-awful#innovation-has-stalled-where-it-matters-most" class="hash-link" aria-label="Direct link to Innovation Has Stalled Where It Matters Most" title="Direct link to Innovation Has Stalled Where It Matters Most" translate="no">​</a></h2>
<p>Display technology has lost interest in solving the real problem: how humans actually interact with information. Instead of innovating toward better human-computer interaction, manufacturers keep fighting for incremental improvements in image quality. Innovation continues, but those pushing meaningful boundaries face enormous momentum from an industry focused on specs rather than usability.</p>
<p>Many people speculate the next "big thing" will be headache-inducing "3D" displays. Put on glasses, stare at interlaced images, or endure other visual tricks. You can buy these TVs, but most people simply don't care whether their advertisements jump out of the screen. There's a long way to go before we reach Star Wars-like holograms with R2D2 projecting videos in mid-air.</p>
<p>Even genuinely impressive technologies like laser-based holographic projections that create points of light in midair address the wrong problem. These systems focus on visual spectacle rather than the fundamental reason we need displays: to facilitate meaningful interaction between humans and computers.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-happens-when-we-focus-on-human-interaction">What Happens When We Focus on Human Interaction?<a href="https://kb.buildingbetterteams.de/blog/2012/01/21/your-monitor-is-awful#what-happens-when-we-focus-on-human-interaction" class="hash-link" aria-label="Direct link to What Happens When We Focus on Human Interaction?" title="Direct link to What Happens When We Focus on Human Interaction?" translate="no">​</a></h2>
<p>When we shift perspective to human interaction, picture quality becomes less important than usability and value. The most promising developments focus on displays that adapt to human needs rather than forcing humans to adapt to the technology.</p>
<p>Take f.lux, a simple application that automatically adjusts screen brightness and color temperature based on time of day. It eliminates the jarring experience of staring into blazing white light late at night, helping maintain natural sleep cycles. This represents exactly what displays should do: fit the human like a glove.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-real-problem-displays-dont-fit-humans">The Real Problem: Displays Don't Fit Humans<a href="https://kb.buildingbetterteams.de/blog/2012/01/21/your-monitor-is-awful#the-real-problem-displays-dont-fit-humans" class="hash-link" aria-label="Direct link to The Real Problem: Displays Don't Fit Humans" title="Direct link to The Real Problem: Displays Don't Fit Humans" translate="no">​</a></h2>
<p>Current displays fail because they don't consider that users are human. We're stuck staring into boxes of light in an interaction model that works well for photos and videos but falls short for most other computer tasks.</p>
<p>Right now, you have to hunt for windows you just minimized. Your eyes painfully readjust when switching from a dark website to a bright one. You scroll through tabs searching for a single piece of text. You navigate past banner ads and company branding just to reach your content. These problems stem from displays that force humans to adapt rather than adapting to human needs.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-solution-responsive-adaptive-displays">The Solution: Responsive, Adaptive Displays<a href="https://kb.buildingbetterteams.de/blog/2012/01/21/your-monitor-is-awful#the-solution-responsive-adaptive-displays" class="hash-link" aria-label="Direct link to The Solution: Responsive, Adaptive Displays" title="Direct link to The Solution: Responsive, Adaptive Displays" translate="no">​</a></h2>
<p>Future displays should do more than show content: they should intelligently present it. If I'm about to search for something online, my computer should anticipate this need and organize my workspace accordingly. It should consider my experience level and adapt the interface to match.</p>
<p>This requires separating content from presentation design. Instead of websites dictating exactly how information appears on your screen, displays should analyze multiple content sources and determine the most intuitive way for each individual user to absorb that information.</p>
<p>Consider displays that eliminate jarring transitions between light and dark content, that organize information based on your current task, that learn your patterns and adapt accordingly. This approach focuses on creating interfaces that wrap around human behavior rather than impressive visual effects.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-path-forward">The Path Forward<a href="https://kb.buildingbetterteams.de/blog/2012/01/21/your-monitor-is-awful#the-path-forward" class="hash-link" aria-label="Direct link to The Path Forward" title="Direct link to The Path Forward" translate="no">​</a></h2>
<p>We're already struggling to make websites work across different devices because we've locked presentation and content together. Displays focused on photo-realistic contrast struggle to deliver user experiences that demonstrate real value.</p>
<p>The future belongs to displays that understand their users. The first step is exposing content in ways that allow displays to intelligently mix and present information tailored to individual needs. Only then can we create display systems that truly fit humans like a glove: natural, intuitive, and focused on delivering value rather than visual spectacle.</p>
<p>The technology exists. What we need now is a paradigm shift from hardware specifications to human-centered design.</p>]]></content>
        <author>
            <name>Brian Graham</name>
            <uri>/blog/about-brian</uri>
        </author>
        <category label="HCI" term="HCI"/>
        <category label="displays" term="displays"/>
        <category label="human-computer-interaction" term="human-computer-interaction"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[The Lost Art of Internet Protocols]]></title>
        <id>https://kb.buildingbetterteams.de/blog/2012/01/11/internet-protocols</id>
        <link href="https://kb.buildingbetterteams.de/blog/2012/01/11/internet-protocols"/>
        <updated>2012-01-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This post was written in early 2012, when the internet landscape was quite different. At the time, websites were becoming increasingly bloated with Flash content and heavy JavaScript, mobile responsiveness was still a major challenge, and SOPA/PIPA legislation threatened internet freedom. Social media was dominated by Facebook and Twitter, and "Web 2.0" was still a meaningful term.]]></summary>
        <content type="html"><![CDATA[<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>Historical Context (2025)</div><div class="admonitionContent_BuS1"><p>This post was written in early 2012, when the internet landscape was quite different. At the time, websites were becoming increasingly bloated with Flash content and heavy JavaScript, mobile responsiveness was still a major challenge, and SOPA/PIPA legislation threatened internet freedom. Social media was dominated by Facebook and Twitter, and "Web 2.0" was still a meaningful term.</p><p>Since then, many of the author's concerns proved prescient. We've seen the rise of platform monopolization, continued protocol stagnation despite technologies like WebRTC and HTTP/2, and growing awareness of how much the modern web's complexity costs users. The recent interest in decentralized protocols (ActivityPub, IPFS, Nostr) and the push for simpler, faster web experiences echoes many arguments made here over a decade ago.</p></div></div>
<div style="background-color:black;padding:20px 50px;margin-bottom:20px"><span style="color:#6fa8dc;font-family:Georgia, serif;font-size:large;font-weight:bold"><p>A long time ago, on an operating system far, far away...</p></span><div style="text-align:center;color:#f1c232;font-weight:bold;margin-top:20px"><p>It was a period of protocol war.<br>
Raw text connections sent<br>
over the internet had<br>
gained a strong following.<br><br></p><p>During this time, greater<br>
needs and complexity arose<br>
eventually leading to the<br>
wide adoption of the hyper<br>
text transport protocol<br><br></p><p>Knowledge of how the web worked<br>
on these lower levels soon<br>
vanished. It is up to you to<br>
learn the old ways and restore<br>
freedom to the internet...</p></div></div>
<p>There's something we lost when HTTP became the only game in town. Before the web browser dominated everything, the internet was a diverse ecosystem of protocols, each designed for specific purposes. We had telnet for raw connections, Gopher for clean content delivery, and text-based worlds that fostered creativity in ways the modern web struggles to match.</p>
<p>Understanding these "old ways" isn't just nostalgia. It reveals how much richer the internet could be, and why our current web-centric approach may be holding us back.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-telnet-taught-us">What Telnet Taught Us<a href="https://kb.buildingbetterteams.de/blog/2012/01/11/internet-protocols#what-telnet-taught-us" class="hash-link" aria-label="Direct link to What Telnet Taught Us" title="Direct link to What Telnet Taught Us" translate="no">​</a></h2>
<p>Telnet gets a bad reputation today, dismissed as an insecure relic. But calling it just "telnet" misses the point—we're really talking about the foundation of all internet communication: sending raw text over TCP/IP. Every protocol, from HTTP to SMTP to IRC, builds on this simple concept.</p>
<p>This simplicity was educational. When you connected to a server via telnet, you weren't hidden behind layers of abstraction. You typed commands, got responses, and understood exactly what was happening. The internet wasn't a magic box that rendered HTML into pretty pictures. It was a conversation between computers using plain text.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-rich-world-we-abandoned">The Rich World We Abandoned<a href="https://kb.buildingbetterteams.de/blog/2012/01/11/internet-protocols#the-rich-world-we-abandoned" class="hash-link" aria-label="Direct link to The Rich World We Abandoned" title="Direct link to The Rich World We Abandoned" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="multi-user-worlds">Multi-User Worlds<a href="https://kb.buildingbetterteams.de/blog/2012/01/11/internet-protocols#multi-user-worlds" class="hash-link" aria-label="Direct link to Multi-User Worlds" title="Direct link to Multi-User Worlds" translate="no">​</a></h3>
<p>One of the most engaging examples of pre-web internet culture was Multi-User Dungeons (MUDs, MOOs, MUSHes, and MUCKs). Born in the mid-1970s, these text-based virtual worlds had no graphics or special encodings. Just a stream of text that created immersive experiences for hours.</p>
<p>What made them special wasn't the technology, but the culture. Many MUD servers exposed programming languages to players. You could log in, write code that manipulated the game world, and watch other users discover and interact with your creations. We had user-generated content as the focus of the internet in the 1970s, decades before "Web 2.0" claimed to invent the concept.</p>
<p>I ran one of the most popular sites focused on Message Parsing Interpreter (MPI) when I was twelve. Players would write complex interactive objects and export that code to other servers. The Discworld MUD, based on Terry Pratchett's novels, has been online for almost 20 years with 50-150 players logged in at any time. These communities built lasting social connections around shared creativity and imagination.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="pure-content-delivery">Pure Content Delivery<a href="https://kb.buildingbetterteams.de/blog/2012/01/11/internet-protocols#pure-content-delivery" class="hash-link" aria-label="Direct link to Pure Content Delivery" title="Direct link to Pure Content Delivery" translate="no">​</a></h3>
<p>Before HTTP conquered everything, we had Gopher: a protocol designed to deliver pure content without design chrome or spam. The Gopher manifesto reads like a post-mortem now, but its vision was compelling: just the knowledge, without the sparkling prettiness of bad web design and ad-filled "news" sites.</p>
<p>Gopher would have made our current "mobile site" problems irrelevant. When you're only delivering content rather than layouts, backgrounds, animations, and advertisements, everything works everywhere. It's tragic the protocol died, because had it evolved with the same effort as HTTP, we might have a cleaner internet today.</p>
<p>The few remaining Gopher servers exist in near-stasis since 1991, but they demonstrate what we lost: instant access to information without visual noise or commercial interruption.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-http-won-and-what-we-lost">Why HTTP Won (And What We Lost)<a href="https://kb.buildingbetterteams.de/blog/2012/01/11/internet-protocols#why-http-won-and-what-we-lost" class="hash-link" aria-label="Direct link to Why HTTP Won (And What We Lost)" title="Direct link to Why HTTP Won (And What We Lost)" translate="no">​</a></h2>
<p>HTTP's dominance wasn't accidental. The web browser provided a unified interface for multiple protocols, solving real interoperability problems. Instead of needing different software for every service, users could access everything through one application.</p>
<p>But this convenience came with costs. We stopped innovating at the protocol level and started forcing everything through HTTP, regardless of whether it was the right tool. Today we have SOAP monsters and RESTful APIs trying to recreate functionality that specialized protocols handled more elegantly.</p>
<p>The deeper loss was educational. When protocols were visible and diverse, technically curious people learned how the internet actually worked. Now those mechanisms are hidden inside browsers, creating a generation that sees the internet as magic rather than engineering.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-knowledge-gap">The Knowledge Gap<a href="https://kb.buildingbetterteams.de/blog/2012/01/11/internet-protocols#the-knowledge-gap" class="hash-link" aria-label="Direct link to The Knowledge Gap" title="Direct link to The Knowledge Gap" translate="no">​</a></h2>
<p>Most people don't understand internet protocols because they've been abstracted away. This isn't because protocols are complicated—SMTP is simple enough that you can manually send emails by typing commands. The complexity is hidden, tucked inside software that "just works."</p>
<p>This knowledge gap has serious implications. When politicians propose blocking DNS or making encryption illegal, those who understand the internet's architecture immediately recognize how misguided these policies are. But that understanding is becoming rare, concentrated among a shrinking group of specialists rather than being widely distributed.</p>
<p>Understanding protocols also reveals possibilities. If you know that HTTP is just text commands like "GET /Resource," you realize you could create something similar. The internet isn't a closed system. It's an open platform for experimentation.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-we-could-build">What We Could Build<a href="https://kb.buildingbetterteams.de/blog/2012/01/11/internet-protocols#what-we-could-build" class="hash-link" aria-label="Direct link to What We Could Build" title="Direct link to What We Could Build" translate="no">​</a></h2>
<p>Imagine internet protocols designed for today's needs rather than retrofitted into HTTP:</p>
<ul>
<li class=""><strong>Efficient content delivery</strong>: Pre-computed DOM trees instead of HTML documents that require additional resource requests</li>
<li class=""><strong>Batch communication</strong>: Multiple documents sent simultaneously rather than the current request-response cycle</li>
<li class=""><strong>Purpose-built interfaces</strong>: Discussion protocols that work naturally in text environments, unwrapped from web browser chrome</li>
<li class=""><strong>Structured data</strong>: Native JSON protocols instead of encoding everything in markup</li>
<li class=""><strong>Academic publishing</strong>: Direct TeX format delivery for mathematical and scientific content</li>
</ul>
<p>We don't pursue these possibilities because HTTP's inertia is massive. But that doesn't mean enthusiastic hackers can't reclaim some of that experimental spirit.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-path-forward">The Path Forward<a href="https://kb.buildingbetterteams.de/blog/2012/01/11/internet-protocols#the-path-forward" class="hash-link" aria-label="Direct link to The Path Forward" title="Direct link to The Path Forward" translate="no">​</a></h2>
<p>I'm not suggesting we abandon the web. HTTP solved real problems and enabled unprecedented global communication. But we shouldn't let its success prevent us from exploring alternatives for specific use cases.</p>
<p>The protocols that built the early internet were designed by people who didn't know what was impossible. They experimented freely, creating tools that served distinct purposes rather than trying to make one protocol do everything.</p>
<p>Today's internet giants understand this. They've moved beyond HTTP for internal systems, using specialized protocols for performance and functionality. The rest of us are stuck in browsers, accepting the limitations of a document delivery system pressed into service as a universal application platform.</p>
<p>Learning these older protocols isn't just historical curiosity—it's preparation for building the next generation of internet tools. When you understand that the internet is bigger than the web, you start seeing possibilities that browser-based thinking misses.</p>
<p>The internet belongs to those who understand it. The more people who learn these fundamentals, the more likely we are to see real innovation rather than endless variations on HTTP-wrapped services.</p>
<p>Start with telnet. Pick a simple protocol like SMTP or IRC. Write a basic client. See how much you can accomplish with just text and creativity. The internet is still out there, waiting for the next generation of protocol pioneers.</p>]]></content>
        <author>
            <name>Brian Graham</name>
            <uri>/blog/about-brian</uri>
        </author>
        <category label="internet" term="internet"/>
        <category label="protocols" term="protocols"/>
        <category label="telnet" term="telnet"/>
        <category label="nostalgia" term="nostalgia"/>
        <category label="web-history" term="web-history"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Project Euler 001 The Hard Way]]></title>
        <id>https://kb.buildingbetterteams.de/blog/project-euler-001-hard-way</id>
        <link href="https://kb.buildingbetterteams.de/blog/project-euler-001-hard-way"/>
        <updated>2012-01-04T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Discover the hidden complexity of a simple programming problem and explore multiple solutions from brute force to mathematical optimization.]]></summary>
        <content type="html"><![CDATA[<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>Historical Context</div><div class="admonitionContent_BuS1"><p>This is a rewrite of an article I wrote in January 2012 where I discover the hidden complexity of a simple programming problem.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="problem-001">Problem 001<a href="https://kb.buildingbetterteams.de/blog/project-euler-001-hard-way#problem-001" class="hash-link" aria-label="Direct link to Problem 001" title="Direct link to Problem 001" translate="no">​</a></h2>
<p>On the popular programming challenge website <a href="https://projecteuler.net/problem=1" target="_blank" rel="noopener noreferrer" class="">Project Euler</a>, the first problem seems quite trivial. However, with deeper examination we can discover layers of complexity as we try to generalize the problem.</p>
<blockquote>
<p><strong>If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000.</strong></p>
</blockquote>
<p>It looks almost like a generic screening interview problem. The problem should be solvable anywhere between 1 and 5 minutes by any developer. It's a simple loop, some logic, and addition.</p>
<div style="margin:2rem 0;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-code-border-radius);overflow:hidden"><h4 style="margin:0;padding:1rem 1.5rem 0.5rem;color:var(--ifm-color-emphasis-800);font-size:1.1rem;font-weight:600;background:var(--ifm-color-emphasis-100)">Initial Brute Force Solution</h4><p style="margin:0;padding:0 1.5rem 1rem;color:var(--ifm-color-emphasis-700);background:var(--ifm-color-emphasis-100);font-style:italic">The most straightforward approach using a simple loop</p><div><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv codeBlockLinesWithNumbering_o6Pm" style="counter-reset:line-count 0"><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sumMultiplesOfThreeAndFive</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> sum </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">n</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i </span><span class="token operator" style="color:#393A34">%</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i </span><span class="token operator" style="color:#393A34">%</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">    sum </span><span class="token operator" style="color:#393A34">+=</span><span class="token plain"> i</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> sum</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">sumMultiplesOfThreeAndFive</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span></span><br></span></code></pre></div></div><div style="padding:1rem 1.5rem;background:var(--ifm-color-emphasis-100);border-top:1px solid var(--ifm-color-emphasis-300)"><button style="background:var(--ifm-color-primary);color:white;border:none;padding:0.5rem 1rem;border-radius:var(--ifm-button-border-radius);cursor:pointer;font-weight:500;opacity:1">Run Code</button></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="solving-every-set-of-multiples">Solving every set of multiples<a href="https://kb.buildingbetterteams.de/blog/project-euler-001-hard-way#solving-every-set-of-multiples" class="hash-link" aria-label="Direct link to Solving every set of multiples" title="Direct link to Solving every set of multiples" translate="no">​</a></h2>
<p>Looking at the code it's quite obvious 3 and 5 are replaceable with any set of other numbers. All we need to do is tweak the code to support accepting an array of multiples that will be tested.</p>
<div style="margin:2rem 0;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-code-border-radius);overflow:hidden"><h4 style="margin:0;padding:1rem 1.5rem 0.5rem;color:var(--ifm-color-emphasis-800);font-size:1.1rem;font-weight:600;background:var(--ifm-color-emphasis-100)">Generalized Solution</h4><p style="margin:0;padding:0 1.5rem 1rem;color:var(--ifm-color-emphasis-700);background:var(--ifm-color-emphasis-100);font-style:italic">Extended to work with any array of multiples</p><div><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv codeBlockLinesWithNumbering_o6Pm" style="counter-reset:line-count 0"><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sumMultiples</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">n</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> multiples</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> sum</span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">isMultiple</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">n</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> multiple</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">n </span><span class="token operator" style="color:#393A34">%</span><span class="token plain"> multiple</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">commonMultiples</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">n</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter">multiples</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> isCommon </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">multiples</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">    isCommon </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">isCommon </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">isMultiple</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">n</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> multiples</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> isCommon</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">n</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">commonMultiples</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">multiples</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">    sum </span><span class="token operator" style="color:#393A34">+=</span><span class="token plain"> i</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> sum</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">sumMultiples</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span></span><br></span></code></pre></div></div><div style="padding:1rem 1.5rem;background:var(--ifm-color-emphasis-100);border-top:1px solid var(--ifm-color-emphasis-300)"><button style="background:var(--ifm-color-primary);color:white;border:none;padding:0.5rem 1rem;border-radius:var(--ifm-button-border-radius);cursor:pointer;font-weight:500;opacity:1">Run Code</button></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="fixing-the-performance-issue">Fixing the performance issue<a href="https://kb.buildingbetterteams.de/blog/project-euler-001-hard-way#fixing-the-performance-issue" class="hash-link" aria-label="Direct link to Fixing the performance issue" title="Direct link to Fixing the performance issue" translate="no">​</a></h2>
<p>Every time it searches for a higher number it ends up taking longer to run. So how else might I try to solve this? I recalled a story a high school math teacher told me about the Mathematician Gauss. His teacher punished him with the daunting task of adding together all the numbers between 1 and 100. Gauss solved it in minutes, because saw a simple pattern which he invented called the Arithmetic Sum.</p>
<p>The formula for an arithmetic series is:</p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>S</mi><mi>n</mi></msub><mo>=</mo><mfrac><mi>n</mi><mn>2</mn></mfrac><mo stretchy="false">(</mo><msub><mi>a</mi><mn>1</mn></msub><mo>+</mo><msub><mi>a</mi><mi>n</mi></msub><mo stretchy="false">)</mo><mo>=</mo><mfrac><mi>n</mi><mn>2</mn></mfrac><mo stretchy="false">(</mo><mi>a</mi><mo>+</mo><mi>a</mi><mo>⋅</mo><mi>n</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">S_n = \frac{n}{2}(a_1 + a_n) = \frac{n}{2}(a + a \cdot n)</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" style="margin-right:0.05764em">S</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-left:-0.0576em;margin-right:0.05em"><span class="pstrut" style="height:2.7em"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</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:1.095em;vertical-align:-0.345em"></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="mopen">(</span><span class="mord"><span class="mord mathnormal">a</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.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"><span class="mord mathnormal">a</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-left:0em;margin-right:0.05em"><span class="pstrut" style="height:2.7em"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</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="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span></span><span class="base"><span class="strut" style="height:1.095em;vertical-align:-0.345em"></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="mopen">(</span><span class="mord mathnormal">a</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.4445em"></span><span class="mord mathnormal">a</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 mathnormal">n</span><span class="mclose">)</span></span></span></span></p>
<p>Where:</p>
<ul>
<li class=""><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 number of terms</li>
<li class=""><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.4306em"></span><span class="mord mathnormal">a</span></span></span></span> is the first term</li>
<li class=""><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>a</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">a_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5806em;vertical-align:-0.15em"></span><span class="mord"><span class="mord mathnormal">a</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-left:0em;margin-right:0.05em"><span class="pstrut" style="height:2.7em"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</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> is the last term</li>
</ul>
<blockquote>
<p><strong>The sum is equal to the first and last number in the series, multiplied by half the count of numbers in the series.</strong></p>
</blockquote>
<p>What's amazing about this is it scales at O(1), there's no Ifs or Loops here. It works the same way for 100 as it does 10e100.</p>
<p>If we find the sum of 3s, we just find the number of times 999 can be divided by 3, then apply the arithmetic series formula. The same for 5s. This does however introduce a slight problem: just adding the two values together is higher than the final result. We need to subtract all multiples that are common to both 3 and 5 (to avoid double-counting).</p>
<p>So, in summary, find the sum of 3s, 5s, and subtract once the sum of 15s (since 15 is the LCM - Least Common Multiple - of 3 and 5).</p>
<div style="margin:2rem 0;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-code-border-radius);overflow:hidden"><h4 style="margin:0;padding:1rem 1.5rem 0.5rem;color:var(--ifm-color-emphasis-800);font-size:1.1rem;font-weight:600;background:var(--ifm-color-emphasis-100)">Mathematical Optimization</h4><p style="margin:0;padding:0 1.5rem 1rem;color:var(--ifm-color-emphasis-700);background:var(--ifm-color-emphasis-100);font-style:italic">Using arithmetic series formula for O(1) performance</p><div><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv codeBlockLinesWithNumbering_o6Pm" style="counter-reset:line-count 0"><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sumMultiplesOfTwoOrThree</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> sum</span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">arithmeticSum</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">a</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token operator" style="color:#393A34">/</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">*</span><span class="token plain">n</span><span class="token operator" style="color:#393A34">*</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token operator" style="color:#393A34">+</span><span class="token plain">a</span><span class="token operator" style="color:#393A34">*</span><span class="token plain">n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">arithmeticSumFromSeriesMultiple</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">series</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> multiple</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  series </span><span class="token operator" style="color:#393A34">-=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">//Euler problem #1 wants numbers less than 1000.</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> multiple</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> n </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">floor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">series</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">multiple</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">arithmeticSum</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">sum </span><span class="token operator" style="color:#393A34">+=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">arithmeticSumFromSeriesMultiple</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">sum </span><span class="token operator" style="color:#393A34">+=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">arithmeticSumFromSeriesMultiple</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">sum </span><span class="token operator" style="color:#393A34">-=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">arithmeticSumFromSeriesMultiple</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">15</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> sum</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">sumMultiplesOfTwoOrThree</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span></span><br></span></code></pre></div></div><div style="padding:1rem 1.5rem;background:var(--ifm-color-emphasis-100);border-top:1px solid var(--ifm-color-emphasis-300)"><button style="background:var(--ifm-color-primary);color:white;border:none;padding:0.5rem 1rem;border-radius:var(--ifm-button-border-radius);cursor:pointer;font-weight:500;opacity:1">Run Code</button></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="solving-all-combinations-with-performance">Solving all combinations with performance<a href="https://kb.buildingbetterteams.de/blog/project-euler-001-hard-way#solving-all-combinations-with-performance" class="hash-link" aria-label="Direct link to Solving all combinations with performance" title="Direct link to Solving all combinations with performance" translate="no">​</a></h2>
<p>Thinking back to set theory and Venn diagrams, there's a visual intersection between 3s and 5s that is clearly just the set of 15s that need to be negated once. In more generic terms, if provided A and B, the script must run sum(A)+sum(B)-sum(AB).</p>
<p>Using two for-loops this is an easy task, but again leads to a slow running solution. The real problem here is finding a way to generate all permutations for a set. There's a great way to do that: simply counting in boolean and assigning a place-value to each element in the list of multiples.</p>
<p>That sounds a bit confusing so visualizing here will help. Let's look at this set of multiples with 3s, 5s, and 7s.</p>
<div style="display:flex;justify-content:center;margin:2rem 0;padding:1rem;background:var(--ifm-color-emphasis-100);border-radius:var(--ifm-code-border-radius);border:1px solid var(--ifm-color-emphasis-300)"><svg width="500" height="400" style="max-width:100%;height:auto"></svg></div>
<p>So there's some overlap between all these sets:</p>
<ul>
<li class="">3s and 5s</li>
<li class="">5s and 7s</li>
<li class="">7s and 3s</li>
<li class="">3s, 5s, and 7s combined</li>
</ul>
<p>So in this case I'd have to:
<strong>sum(3)+sum(5)+sum(7)-sum(3×5)-sum(3×7)-sum(7×3)+sum(3×5×7)</strong>.</p>
<p>As mentioned above, another way to look at this is binary mapping:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">001 = C      (cardinality 1: ADD)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">010 = B      (cardinality 1: ADD)  </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">011 = BC     (cardinality 2: SUBTRACT)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">100 = A      (cardinality 1: ADD)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">101 = AC     (cardinality 2: SUBTRACT)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">110 = AB     (cardinality 2: SUBTRACT)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">111 = ABC    (cardinality 3: ADD)</span><br></span></code></pre></div></div>
<p>Simply knowing this mapping we can generate all the combinations of sums needed. If it's added or subtracted is simply a matter of how many 1s are in a number: odd numbers get added, even gets removed.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Bitwise Magic</div><div class="admonitionContent_BuS1"><p>What's exciting here is using bitwise operators to generate all possible combinations. Each number from 1 to 2^n-1 represents a unique subset when interpreted as a binary mask!</p></div></div>
<p>This follows the <strong>inclusion-exclusion principle</strong>, which can be expressed mathematically as:</p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mo fence="true">∣</mo><msubsup><mo>⋃</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>n</mi></msubsup><msub><mi>A</mi><mi>i</mi></msub><mo fence="true">∣</mo></mrow><mo>=</mo><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>n</mi></msubsup><mi mathvariant="normal">∣</mi><msub><mi>A</mi><mi>i</mi></msub><mi mathvariant="normal">∣</mi><mo>−</mo><munder><mo>∑</mo><mrow><mn>1</mn><mo>≤</mo><mi>i</mi><mo>&lt;</mo><mi>j</mi><mo>≤</mo><mi>n</mi></mrow></munder><mi mathvariant="normal">∣</mi><msub><mi>A</mi><mi>i</mi></msub><mo>∩</mo><msub><mi>A</mi><mi>j</mi></msub><mi mathvariant="normal">∣</mi><mo>+</mo><munder><mo>∑</mo><mrow><mn>1</mn><mo>≤</mo><mi>i</mi><mo>&lt;</mo><mi>j</mi><mo>&lt;</mo><mi>k</mi><mo>≤</mo><mi>n</mi></mrow></munder><mi mathvariant="normal">∣</mi><msub><mi>A</mi><mi>i</mi></msub><mo>∩</mo><msub><mi>A</mi><mi>j</mi></msub><mo>∩</mo><msub><mi>A</mi><mi>k</mi></msub><mi mathvariant="normal">∣</mi><mo>−</mo><mo>…</mo><mo>+</mo><mo stretchy="false">(</mo><mo>−</mo><mn>1</mn><msup><mo stretchy="false">)</mo><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msup><mi mathvariant="normal">∣</mi><msub><mi>A</mi><mn>1</mn></msub><mo>∩</mo><msub><mi>A</mi><mn>2</mn></msub><mo>∩</mo><mo>…</mo><mo>∩</mo><msub><mi>A</mi><mi>n</mi></msub><mi mathvariant="normal">∣</mi></mrow><annotation encoding="application/x-tex">\left| \bigcup\limits_{i=1}^n A_i \right| = \sum\limits_{i=1}^n | A_i | - \sum\limits_{1 \le i&lt;j \le n} | A_i \cap A_j | + \sum\limits_{1 \le i &lt; j &lt; k \le n} | A_i \cap A_j \cap A_k | - \ldots + (-1)^{n-1} | A_1 \cap A_2  \cap \ldots  \cap A_n |</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.4276em;vertical-align:-0.9777em"></span><span class="minner"><span class="mopen"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em"><span style="top:-3.45em"><span class="pstrut" style="height:4.4em"></span><span style="width:0.333em;height:2.400em"><svg xmlns="http://www.w3.org/2000/svg" width="0.333em" height="2.400em" viewBox="0 0 333 2400"><path d="M145 15 v585 v1200 v585 c2.667,10,9.667,15,21,15
c10,0,16.667,-5,20,-15 v-585 v-1200 v-585 c-2.667,-10,-9.667,-15,-21,-15
c-10,0,-16.667,5,-20,15z M188 15 H145 v585 v1200 v585 h43z"></path></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.95em"><span></span></span></span></span></span></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3514em"><span style="top:-2.1223em;margin-left:0em"><span class="pstrut" style="height:3em"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3em"><span class="pstrut" style="height:3em"></span><span><span class="mop op-symbol small-op">⋃</span></span></span><span style="top:-3.95em;margin-left:0em"><span class="pstrut" style="height:3em"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9777em"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em"><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 mathnormal mtight">i</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 class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em"><span style="top:-3.45em"><span class="pstrut" style="height:4.4em"></span><span style="width:0.333em;height:2.400em"><svg xmlns="http://www.w3.org/2000/svg" width="0.333em" height="2.400em" viewBox="0 0 333 2400"><path d="M145 15 v585 v1200 v585 c2.667,10,9.667,15,21,15
c10,0,16.667,-5,20,-15 v-585 v-1200 v-585 c-2.667,-10,-9.667,-15,-21,-15
c-10,0,-16.667,5,-20,15z M188 15 H145 v585 v1200 v585 h43z"></path></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.95em"><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:2.3291em;vertical-align:-0.9777em"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3514em"><span style="top:-2.1223em;margin-left:0em"><span class="pstrut" style="height:3em"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3em"><span class="pstrut" style="height:3em"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.95em;margin-left:0em"><span class="pstrut" style="height:3em"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9777em"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em"></span><span class="mord">∣</span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em"><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 mathnormal mtight">i</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="mord">∣</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:1.8638em;vertical-align:-1.1138em"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.75em"><span style="top:-2.1223em;margin-left:0em"><span class="pstrut" style="height:3em"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mrel mtight">≤</span><span class="mord mathnormal mtight">i</span><span class="mrel mtight">&lt;</span><span class="mord mathnormal mtight" style="margin-right:0.05724em">j</span><span class="mrel mtight">≤</span><span class="mord mathnormal mtight">n</span></span></span></span><span style="top:-3em"><span class="pstrut" style="height:3em"></span><span><span class="mop op-symbol small-op">∑</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.1138em"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em"></span><span class="mord">∣</span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em"><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 mathnormal mtight">i</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.2222em"></span><span class="mbin">∩</span><span class="mspace" style="margin-right:0.2222em"></span></span><span class="base"><span class="strut" style="height:1.0361em;vertical-align:-0.2861em"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em"><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 mathnormal mtight" style="margin-right:0.05724em">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em"><span></span></span></span></span></span></span><span class="mord">∣</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:1.8882em;vertical-align:-1.1382em"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.75em"><span style="top:-2.0979em;margin-left:0em"><span class="pstrut" style="height:3em"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mrel mtight">≤</span><span class="mord mathnormal mtight">i</span><span class="mrel mtight">&lt;</span><span class="mord mathnormal mtight" style="margin-right:0.05724em">j</span><span class="mrel mtight">&lt;</span><span class="mord mathnormal mtight" style="margin-right:0.03148em">k</span><span class="mrel mtight">≤</span><span class="mord mathnormal mtight">n</span></span></span></span><span style="top:-3em"><span class="pstrut" style="height:3em"></span><span><span class="mop op-symbol small-op">∑</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.1382em"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em"></span><span class="mord">∣</span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em"><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 mathnormal mtight">i</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.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.9694em;vertical-align:-0.2861em"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em"><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 mathnormal mtight" style="margin-right:0.05724em">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em"><span></span></span></span></span></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"><span class="mord mathnormal">A</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-left:0em;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.03148em">k</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="mord">∣</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.6667em;vertical-align:-0.0833em"></span><span class="minner">…</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:1.0641em;vertical-align:-0.25em"></span><span class="mopen">(</span><span class="mord">−</span><span class="mord">1</span><span class="mclose"><span class="mclose">)</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"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mord">∣</span><span class="mord"><span class="mord mathnormal">A</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.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.8333em;vertical-align:-0.15em"></span><span class="mord"><span class="mord mathnormal">A</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.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.5556em"></span><span class="minner">…</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"><span class="mord mathnormal">A</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-left:0em;margin-right:0.05em"><span class="pstrut" style="height:2.7em"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</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="mord">∣</span></span></span></span></p>
<p>For our specific case with three sets (multiples of 3, 5, and 7), this becomes:</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>A</mi><mo>∪</mo><mi>B</mi><mo>∪</mo><mi>C</mi><mi mathvariant="normal">∣</mi><mo>=</mo><mi mathvariant="normal">∣</mi><mi>A</mi><mi mathvariant="normal">∣</mi><mo>+</mo><mi mathvariant="normal">∣</mi><mi>B</mi><mi mathvariant="normal">∣</mi><mo>+</mo><mi mathvariant="normal">∣</mi><mi>C</mi><mi mathvariant="normal">∣</mi><mo>−</mo><mi mathvariant="normal">∣</mi><mi>A</mi><mo>∩</mo><mi>B</mi><mi mathvariant="normal">∣</mi><mo>−</mo><mi mathvariant="normal">∣</mi><mi>A</mi><mo>∩</mo><mi>C</mi><mi mathvariant="normal">∣</mi><mo>−</mo><mi mathvariant="normal">∣</mi><mi>B</mi><mo>∩</mo><mi>C</mi><mi mathvariant="normal">∣</mi><mo>+</mo><mi mathvariant="normal">∣</mi><mi>A</mi><mo>∩</mo><mi>B</mi><mo>∩</mo><mi>C</mi><mi mathvariant="normal">∣</mi></mrow><annotation encoding="application/x-tex">|A \cup B \cup C| = |A| + |B| + |C| - |A \cap B| - |A \cap C| - |B \cap C| + |A \cap B \cap C|</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="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 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 mathnormal" style="margin-right:0.07153em">C</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:1em;vertical-align:-0.25em"></span><span class="mord">∣</span><span class="mord mathnormal">A</span><span class="mord">∣</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">∣</span><span class="mord mathnormal" style="margin-right:0.05017em">B</span><span class="mord">∣</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">∣</span><span class="mord mathnormal" style="margin-right:0.07153em">C</span><span class="mord">∣</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">∣</span><span class="mord mathnormal">A</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 mathnormal" style="margin-right:0.05017em">B</span><span class="mord">∣</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">∣</span><span class="mord mathnormal">A</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 mathnormal" style="margin-right:0.07153em">C</span><span class="mord">∣</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">∣</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 mathnormal" style="margin-right:0.07153em">C</span><span class="mord">∣</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">∣</span><span class="mord mathnormal">A</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 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 mathnormal" style="margin-right:0.07153em">C</span><span class="mord">∣</span></span></span></span></p>
<p>So with this known, we simply need a combination generator. This will take <code>["a", "b", "c" , "d"]</code> and return <code>["a", "b", "ab", "c", "ac", "bc", "abc", "d", "ad", "bd", "abd", "cd", "acd", "bcd", "abcd"]</code> (all combinations of ABCD).</p>
<div style="margin:2rem 0;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-code-border-radius);overflow:hidden"><h4 style="margin:0;padding:1rem 1.5rem 0.5rem;color:var(--ifm-color-emphasis-800);font-size:1.1rem;font-weight:600;background:var(--ifm-color-emphasis-100)">Helper Functions</h4><p style="margin:0;padding:0 1.5rem 1rem;color:var(--ifm-color-emphasis-700);background:var(--ifm-color-emphasis-100);font-style:italic">Utility functions for combinations and arithmetic operations</p><div><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv codeBlockLinesWithNumbering_o6Pm" style="counter-reset:line-count 0"><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token comment" style="color:#999988;font-style:italic">/*Generate a list of all Combinations*/</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">getCombinations</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">list</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> combinations </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">//All combinations</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> combination </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">//Single combination</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> quantity </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;&lt;</span><span class="token plain"> list</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> quantity </span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  combination </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> j</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">j</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">list</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">j</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;&lt;</span><span class="token plain"> j</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">      combination</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">list</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">j</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">combination</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">    combinations</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">combination</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> combinations</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain" style="display:inline-block"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/*Generate a product from a list of numbers*/</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">listProduct</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">list</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> product</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">list</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  product </span><span class="token operator" style="color:#393A34">*=</span><span class="token plain">list</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> product</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain" style="display:inline-block"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/*Return the arithmetic sum*/</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">arithmeticSum</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">a</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token operator" style="color:#393A34">/</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">*</span><span class="token plain">n</span><span class="token operator" style="color:#393A34">*</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token operator" style="color:#393A34">+</span><span class="token plain">a</span><span class="token operator" style="color:#393A34">*</span><span class="token plain">n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain" style="display:inline-block"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/*Generate the arithmetic sum of a series based on a multiple*/</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">arithmeticSumFromSeriesMultiple</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">series</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> multiple</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">series </span><span class="token operator" style="color:#393A34">-=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">//Euler problem #1 wants numbers less than the range.</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> multiple</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> n </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">floor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">series</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">multiple</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">arithmeticSum</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span></span><br></span></code></pre></div></div></div></div>
<p>Now combining everything together the result is something like this:</p>
<div style="margin:2rem 0;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-code-border-radius);overflow:hidden"><h4 style="margin:0;padding:1rem 1.5rem 0.5rem;color:var(--ifm-color-emphasis-800);font-size:1.1rem;font-weight:600;background:var(--ifm-color-emphasis-100)">Complete Optimized Solution</h4><p style="margin:0;padding:0 1.5rem 1rem;color:var(--ifm-color-emphasis-700);background:var(--ifm-color-emphasis-100);font-style:italic">Final solution using inclusion-exclusion principle with O(1) arithmetic series</p><div><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv codeBlockLinesWithNumbering_o6Pm" style="counter-reset:line-count 0"><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token comment" style="color:#999988;font-style:italic">/*Generate a list of all Combinations*/</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">getCombinations</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">list</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> combinations </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">//All combinations</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> combination </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">//Single combination</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> quantity </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;&lt;</span><span class="token plain"> list</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> quantity </span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  combination </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> j</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">j</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">list</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">j</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;&lt;</span><span class="token plain"> j</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">      combination</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">list</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">j</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">combination</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">    combinations</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">combination</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> combinations</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain" style="display:inline-block"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/*Generate a product from a list of numbers*/</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">listProduct</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">list</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> product</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">list</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  product </span><span class="token operator" style="color:#393A34">*=</span><span class="token plain">list</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> product</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain" style="display:inline-block"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/*Return the arithmetic sum*/</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">arithmeticSum</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">a</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token operator" style="color:#393A34">/</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">*</span><span class="token plain">n</span><span class="token operator" style="color:#393A34">*</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token operator" style="color:#393A34">+</span><span class="token plain">a</span><span class="token operator" style="color:#393A34">*</span><span class="token plain">n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain" style="display:inline-block"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/*Generate the arithmetic sum of a series based on a multiple*/</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">arithmeticSumFromSeriesMultiple</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">series</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> multiple</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> multiple</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> n </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">floor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">series</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">multiple</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">arithmeticSum</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain" style="display:inline-block"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sumMultiples</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">range</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> multiples</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> sum</span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> subsetSums </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> multiplesCombination</span><span class="token operator" style="color:#393A34">=</span><span class="token function" style="color:#d73a49">getCombinations</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">multiples</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">multiplesCombination</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">//Generate product from combinations of multiples</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">//and</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">//Find individual sums of all combinations.</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  subsetSums</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">    </span><span class="token function" style="color:#d73a49">arithmeticSumFromSeriesMultiple</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">      range</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">      </span><span class="token function" style="color:#d73a49">listProduct</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">multiplesCombination</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain" style="display:inline-block"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> subsetSums</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">//Check if i is an even base 2.</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">    sum </span><span class="token operator" style="color:#393A34">+=</span><span class="token plain"> subsetSums</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">    sum </span><span class="token operator" style="color:#393A34">-=</span><span class="token plain"> subsetSums</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> sum</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain" style="display:inline-block"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#393A34"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">sumMultiples</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">999</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span></span><br></span></code></pre></div></div><div style="padding:1rem 1.5rem;background:var(--ifm-color-emphasis-100);border-top:1px solid var(--ifm-color-emphasis-300)"><button style="background:var(--ifm-color-primary);color:white;border:none;padding:0.5rem 1rem;border-radius:var(--ifm-button-border-radius);cursor:pointer;font-weight:500;opacity:1">Run Code</button></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="results">Results<a href="https://kb.buildingbetterteams.de/blog/project-euler-001-hard-way#results" class="hash-link" aria-label="Direct link to Results" title="Direct link to Results" translate="no">​</a></h2>
<p>A quick check of performance yields these results:</p>
<ul>
<li class="">Using really large numbers, the math approach is much faster.</li>
<li class="">Using really small sets, the simple for-loop is faster in 2020, but I remember it was slower in 2012 when I originally tested this.</li>
</ul>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Performance Insight</div><div class="admonitionContent_BuS1"><p>The mathematical approach scales at <strong>O(1)</strong> regardless of range size - it works the same for 1,000 as it does for 10^100. The brute force approach scales linearly with the range size.</p></div></div>]]></content>
        <author>
            <name>Brian Graham</name>
            <uri>/blog/about-brian</uri>
        </author>
        <category label="algorithms" term="algorithms"/>
        <category label="javascript" term="javascript"/>
        <category label="mathematics" term="mathematics"/>
        <category label="performance" term="performance"/>
        <category label="project-euler" term="project-euler"/>
    </entry>
</feed>