<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://trebledj.me">
  <title>TrebledJ&#39;s Pages</title>
  <subtitle>TrebledJ&#39;s personal blog on programming, cybersecurity, music, and memes.</subtitle>
  <link href="https://trebledj.me/feeds/mathematics.xml" rel="self"/>
  <link href="https://trebledj.me"/>
  <updated>2023-04-24T00:00:00Z</updated>
  <id>https://trebledj.me</id>
  <author>
    <name>TrebledJ</name>
    <email>trebledjjj@gmail.com</email>
  </author>
  
    
      
      <entry>
        <title>The Mathematics of Types</title>
        <description>Programming isn&#39;t about mindlessly typing away on a keyboard. There is an aesthetic quality that comes with approaching a problem.</description>
        <link href="https://trebledj.me/posts/the-mathematics-of-types/"/>
        <updated>2023-04-24T00:00:00Z</updated>
        <id>https://trebledj.me/posts/the-mathematics-of-types/</id>
        <content xml:lang="en" type="html">&lt;p&gt;Algebraic data types (ADTs) encompass a wide range of types commonly used in our day-to-day tasks. Over the past years, they’ve grown in popularity with the rise of modern languages such as Rust and Scala. They allow us to effectively model data, write readable code, and catch bugs at compile time. But rarely do we consider the aesthetics behind such constructs.&lt;/p&gt;
&lt;p&gt;This post is for the curious programmer. Today, we’ll be looking at the mathematics behind ADTs. In doing so, we also gain an appreciation for their utility and aesthetics. I’ll be mainly using Haskell code blocks in this post, because types are very straightforward to express in this language. If you’re unfamiliar with Haskell, fear not!—the concepts addressed below are transferable to most programming languages.&lt;/p&gt;
&lt;h2 id=&quot;motivation-for-adts&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#motivation-for-adts&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Motivation for ADTs&lt;/h2&gt;
&lt;p&gt;We are interested in combining types, but that alone isn’t saying much. First, we want to combine types &lt;strong&gt;meaningfully&lt;/strong&gt; in order to communicate ideas through those types.
This notion lies with expressibility and the art of programming. Code is, after all, a medium between programmers.&lt;/p&gt;
&lt;p&gt;Second, we want to combine types &lt;strong&gt;concisely&lt;/strong&gt;; our types shouldn’t contain redundant, ambiguous information. Removing redundancy implies removing duplicate or invalid states, leading to better maintainability and fewer bugs.&lt;/p&gt;
&lt;p&gt;ADTs offers us two ways to combine types: &lt;strong&gt;product types&lt;/strong&gt; and &lt;strong&gt;sum types&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;product-types&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#product-types&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Product Types&lt;/h3&gt;
&lt;p&gt;If you’ve used structs, tuples, or record types, then you already have a sense of what product types are. Product types combine types together as one. A pizza is like a product type, combining crust, cheese, and toppings. When you bite into a pizza, you enjoy the sensation of all three together.&lt;/p&gt;
&lt;p&gt;Here are some product types in Haskell:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;-- Haskell Tuple&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- -------------&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- Haskell separates types from data.&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- Type&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- Data&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;-- Here&#39;s another tuple:&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;-- We can have a product type of product types.&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Char&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3.14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;a&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;-- Although semantically, it&#39;s the same as...&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Char&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3.14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;a&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;-- Haskell Data Constructor&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- ------------------------&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- We define a new type: RectangleType.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- We also define Rect to be a data constructor.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- The data constructor takes 4 integer arguments.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;RectangleType&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Rect&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;-- We can create a RectangleType by passing concrete &lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- values to the Rect data constructor.&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;rect&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;RectangleType&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;rect&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Rect&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;-- Haskell Record&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- --------------&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- Let&#39;s define a record!&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- With Haskell record syntax, we can give names to fields.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- Here, `Person` is both the type and data constructor.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;age&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;-- Let&#39;s construct a Person type! A person has a name AND an age.&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Person&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Peter Parker&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In the final example above, we wrote a product type representing a &lt;code&gt;Person&lt;/code&gt;. All people have &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;age&lt;/code&gt; properties, so it makes sense to combine them in coexistence.&lt;/p&gt;
&lt;h3 id=&quot;sum-types&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#sum-types&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Sum Types&lt;/h3&gt;
&lt;p&gt;Sum types are another way to combine types. In contrast to product types, sum types combine types &lt;em&gt;exclusively&lt;/em&gt;. The choice of crust is like a sum type. Should the crust be thin, thick, or stuffed with cheese? We can only choose one option.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Sum types stand out from the historic dominance of product types.&quot; href=&quot;https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/sheesh-sum-types-500w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-55&quot; src=&quot;https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/sheesh-sum-types-500w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 500 / 559&quot; alt=&quot;Teletubbies handstacking meme, sum types are different from product types.&quot; title=&quot;Sum types stand out from the historic dominance of product types.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/sheesh-sum-types-256w.webp 256w, https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/sheesh-sum-types-500w.webp 500w&quot; sizes=&quot;(max-width: 256px) 256px, 500px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sum types in their &lt;em&gt;simplest&lt;/em&gt; form are just enums. In C/C++, we might define them like so:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	False&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	True&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In Haskell, a &lt;code&gt;Bool&lt;/code&gt; can be defined like so:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;True&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Notice the vertical bar &lt;code&gt;|&lt;/code&gt;. This means a value with type &lt;code&gt;Bool&lt;/code&gt; can either be &lt;code&gt;False&lt;/code&gt; or &lt;code&gt;True&lt;/code&gt;. It can’t be both at the same time.&lt;/p&gt;
&lt;p&gt;Sum types also allow us to represent more complex data structures. Suppose we want to model students and teachers in a school. The traditional object-oriented method would be to declare a base &lt;code&gt;Member&lt;/code&gt; class, then derive &lt;code&gt;Student&lt;/code&gt; and &lt;code&gt;Teacher&lt;/code&gt; classes.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// C++ Object-Oriented Approach&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; Course &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// For simplicity, a course is simply a string.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Student&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token base-clause&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// A student...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; year&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;                    &lt;span class=&quot;token comment&quot;&gt;// ...belongs to a year.&lt;/span&gt;
    std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;vector&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Course&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; courses&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// ...takes some courses.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Teacher&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token base-clause&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
	std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;vector&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Course&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; teaches&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// A teacher teaches some courses.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In functional programming, we could express a &lt;code&gt;Member&lt;/code&gt; as a sum type of &lt;code&gt;Student&lt;/code&gt; or &lt;code&gt;Teacher&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Course&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Member&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Student&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;year&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;courses&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Course&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
			&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Teacher&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;teaches&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Course&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Here, &lt;code&gt;Student&lt;/code&gt; and &lt;code&gt;Teacher&lt;/code&gt; are two branches of the &lt;code&gt;Member&lt;/code&gt; type, and a &lt;code&gt;Member&lt;/code&gt; can only be either a &lt;code&gt;Student&lt;/code&gt; or a &lt;code&gt;Teacher&lt;/code&gt;. We can also add more branches to the sum type, such as &lt;code&gt;Administrator&lt;/code&gt;, &lt;code&gt;Visitor&lt;/code&gt;, and so on.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;There are pros and cons for choosing between the object-oriented approach and functional approach, but that’s a topic for another day.&lt;/p&gt;
&lt;p&gt;Sum types also enable us to express errors in a type-safe way. We can create a &lt;code&gt;Maybe&lt;/code&gt; type that can be either &lt;code&gt;Nothing&lt;/code&gt; or &lt;code&gt;Just&lt;/code&gt; with the former indicating no result, and the latter indicating some result. (More on this later!)&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Maybe&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Nothing&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This type allows us to handle errors in a more structured way and avoid a lot of &lt;code&gt;if-else&lt;/code&gt; statements (with the help of monads!).&lt;/p&gt;
&lt;p&gt;To sum up, sum types enable us to express complex data structures, while avoiding redundancy and making our code more maintainable and type-safe.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;We call &lt;code&gt;Just&lt;/code&gt; a &lt;em&gt;data constructor&lt;/em&gt;. This means we can construct concrete data by applying values to &lt;code&gt;Just&lt;/code&gt;, as if it were a function. For example, &lt;code&gt;Just 1&lt;/code&gt;, &lt;code&gt;Just &amp;quot;in&amp;quot;&lt;/code&gt;, and &lt;code&gt;Just (Just 42)&lt;/code&gt; are all concrete data. The same applies to &lt;code&gt;False&lt;/code&gt;, &lt;code&gt;True&lt;/code&gt;, and &lt;code&gt;Nothing&lt;/code&gt;, but those don’t take arguments.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;types-in-the-wild&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#types-in-the-wild&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Types in the Wild&lt;/h2&gt;
&lt;p&gt;Let’s familiarise ourselves with ADTs and look at a few use cases.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;std::any — I choose you!&quot; href=&quot;https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/wild-types-510w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-45&quot; src=&quot;https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/wild-types-510w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 510 / 499&quot; alt=&quot;Pokemon battle with the user pulling out their prized pokemon: std::any.&quot; title=&quot;std::any — I choose you!&quot; srcset=&quot;https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/wild-types-256w.webp 256w, https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/wild-types-510w.webp 510w&quot; sizes=&quot;(max-width: 256px) 256px, 510px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;product-types-in-the-wild&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#product-types-in-the-wild&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Product Types in the Wild&lt;/h3&gt;
&lt;p&gt;In most languages, product types are useful when passing/returning data containing multiple values. For instance, we can define a &lt;code&gt;divMod&lt;/code&gt; function which returns the quotient and the remainder of two numbers.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;divMod&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;`div`&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;`mod`&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;divMod&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;divMod&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;alert alert-secondary d-flex align-items-start&quot;&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;In the Haskell REPL, lines starting with &lt;code&gt;ghci&amp;gt;&lt;/code&gt; indicate REPL input. Other lines are REPL output.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;sum-types-in-the-wild&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#sum-types-in-the-wild&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Sum Types in the Wild&lt;/h3&gt;
&lt;p&gt;There are two common sum types in the wild: &lt;code&gt;Maybe&lt;/code&gt; (introduced previously) and &lt;code&gt;Either&lt;/code&gt;. These are typically used to express errors: either an error occurred or a valid result is returned.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Maybe&lt;/code&gt; and &lt;code&gt;Either&lt;/code&gt; have other names as well. In Rust, they’re called &lt;a href=&quot;https://doc.rust-lang.org/std/option/enum.Option.html&quot;&gt;&lt;code&gt;Option&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://doc.rust-lang.org/std/result/enum.Result.html&quot;&gt;&lt;code&gt;Result&lt;/code&gt;&lt;/a&gt;. In Scala, it’s &lt;a href=&quot;https://www.scala-lang.org/api/2.13.3/scala/Option.html&quot;&gt;&lt;code&gt;Option&lt;/code&gt;&lt;/a&gt; (not the same one as Rust!) and &lt;a href=&quot;https://www.scala-lang.org/api/2.13.6/scala/util/Either.html&quot;&gt;&lt;code&gt;Either&lt;/code&gt;&lt;/a&gt;. In C++, it’s &lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/optional&quot;&gt;&lt;code&gt;optional&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://github.com/TartanLlama/expected&quot;&gt;&lt;code&gt;expected&lt;/code&gt;&lt;/a&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fn2&quot; id=&quot;fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.
This list isn&#39;t exhaustive, but it goes to show how ubiquitous sum types are—though not as widespread as product types, for historic reasons.&lt;/p&gt;
&lt;p&gt;Again, &lt;code&gt;Maybe&lt;/code&gt; is defined as a sum type like so:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Maybe&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Nothing&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Here, &lt;code&gt;a&lt;/code&gt; is a type parameter, much like the type parameters in C++ templates and other generic programming languages. We can substitute types to get a &lt;strong&gt;concrete type&lt;/strong&gt;. For example, we can have &lt;code&gt;Maybe Int&lt;/code&gt;, &lt;code&gt;Maybe Bool&lt;/code&gt;, &lt;code&gt;Maybe String&lt;/code&gt;, or—for the absolute masochists—&lt;code&gt;Maybe (Maybe (Maybe Int))&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Maybe&lt;/code&gt; is commonly used to denote a computation that might fail. For instance, we can write a safe integer divide function which returns &lt;code&gt;Nothing&lt;/code&gt; when the divisor is &lt;code&gt;0&lt;/code&gt; (indicating an error, since we can&#39;t divide) and returning the wrapped quotient otherwise.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;safeDiv&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Nothing&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;`div`&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;safeDiv&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token constant&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;safeDiv&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token constant&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;safeDiv&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token constant&quot;&gt;Nothing&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Maybe&lt;/code&gt; is used in other places where the error is obvious, such as in map lookup (where &lt;code&gt;Nothing&lt;/code&gt; implies non-existence).&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Either&lt;/code&gt; is similar, but is defined over two type parameters.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The type parameters &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; can be anything; but commonly, &lt;code&gt;a&lt;/code&gt; is used to describe an error (such as a &lt;code&gt;String&lt;/code&gt; or an enum) while &lt;code&gt;b&lt;/code&gt; is some successful computation.&lt;/p&gt;
&lt;p&gt;In the wild, &lt;code&gt;Either&lt;/code&gt; is used in Haskell parsing libraries to return parse results. Sometimes, the parse is successful and returns the generated tree or data (&lt;code&gt;Right&lt;/code&gt;). Other times, the parse fails and the library returns information of where it failed (&lt;code&gt;Left&lt;/code&gt;). For example, maybe it failed to parse an unexpected &lt;code&gt;:&lt;/code&gt; at line 5, column 42 of something.json.&lt;/p&gt;
&lt;h2 id=&quot;the-algebra-of-types&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#the-algebra-of-types&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Algebra of Types&lt;/h2&gt;
&lt;p&gt;The astute may notice that product types combine types in an “&lt;em&gt;&lt;strong&gt;and&lt;/strong&gt;&lt;/em&gt;” fashion, whereas sum types do so in an “&lt;em&gt;&lt;strong&gt;or&lt;/strong&gt;&lt;/em&gt;” fashion. One of the alluring aspects of ADTs is that we can construct an algebra over them, allowing us to rigorously work with types.&lt;/p&gt;
&lt;p&gt;In the following parts, we&#39;ll explore how types relate to math and apply algebraic principles similar to those from elementary!&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-circle-info ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;A word on notation.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Monospaced letters ($&#92;texttt{a}$) denote types/code,&lt;/li&gt;
&lt;li&gt;$|&#92;texttt{a}|$ denotes the size of set &lt;code&gt;a&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;$&#92;equiv$ denotes an isomorphism between types (as in $&#92;texttt{Int} &#92;equiv &#92;texttt{Int}$), and&lt;/li&gt;
&lt;li&gt;$=$ is reserved for good ol&#39; algebraic equivalence.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;types-as-sets&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#types-as-sets&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Types as Sets&lt;/h3&gt;
&lt;p&gt;Let’s start by treating types as &lt;em&gt;sets of values&lt;/em&gt;.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fn3&quot; id=&quot;fnref3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; For instance, a &lt;code&gt;Bool&lt;/code&gt; can be thought of as a set of two values: ${&#92;texttt{True}, &#92;texttt{False}}$, so $|&#92;texttt{Bool}| = 2$.&lt;/p&gt;
&lt;p&gt;What about a $(&#92;texttt{Bool}, &#92;texttt{Bool})$?  Each &lt;code&gt;Bool&lt;/code&gt; can be either &lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;; thus their combination yields $|(&#92;texttt{Bool}, &#92;texttt{Bool})| = 2 &#92;times 2 = 4$ values. Generalising this,&lt;/p&gt;
&lt;p&gt;$$
|&#92;texttt{(a, b)}| = |&#92;texttt{a}| &#92;times |&#92;texttt{b}|
$$&lt;/p&gt;
&lt;p&gt;See how it got the name “product type”?&lt;/p&gt;
&lt;p&gt;What about sum types? How many values can &lt;code&gt;Maybe Bool&lt;/code&gt; take? In the &lt;code&gt;Nothing&lt;/code&gt; branch, we have one value: &lt;code&gt;Nothing&lt;/code&gt;. In the &lt;code&gt;Just&lt;/code&gt; branch, we have two: &lt;code&gt;Just True&lt;/code&gt; and &lt;code&gt;Just False&lt;/code&gt;. Altogether, $|&#92;texttt{Maybe Bool}| = 3$. In general,&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align*}
|&#92;texttt{Maybe a}| &amp;amp;= |&#92;texttt{a}| + 1 &#92;&#92;
|&#92;texttt{Either a b}| &amp;amp;= |&#92;texttt{a}| + |&#92;texttt{b}|
&#92;end{align*}
$$&lt;/p&gt;
&lt;p&gt;Indeed, product types resemble multiplication over spaces whereas sum types suggest addition over spaces.&lt;/p&gt;
&lt;h3 id=&quot;isomorphism-of-types&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#isomorphism-of-types&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Isomorphism of Types&lt;/h3&gt;
&lt;p&gt;The above-mentioned mathematical representation may come in handy when refactoring/optimising code.&lt;/p&gt;
&lt;p&gt;Suppose we want a type with two “bins”: bin A and bin B. Items can belong to either bin, but not both… How can we represent this as a type?&lt;/p&gt;
&lt;p&gt;One way is to use &lt;code&gt;Either a a&lt;/code&gt;. We let &lt;code&gt;Left x&lt;/code&gt; denote items in bin A, and &lt;code&gt;Right x&lt;/code&gt; denote those in bin B.&lt;/p&gt;
&lt;p&gt;Is there another way to represent the problem? Yes: &lt;code&gt;(Bool, a)&lt;/code&gt;. We can use the &lt;code&gt;Bool&lt;/code&gt; to flag whether the corresponding item is in bin A. Thus, &lt;code&gt;(True, x)&lt;/code&gt; and &lt;code&gt;(False, x)&lt;/code&gt; are used to denote items in bin A and B respectively.&lt;/p&gt;
&lt;p&gt;In fact, we’ve just constructed an &lt;strong&gt;isomorphism&lt;/strong&gt; between types!&lt;/p&gt;
&lt;p&gt;The beauty is in the algebra. The equivalence above can be succinctly (and abstractly!) written as $&#92;texttt{Either a a} {} &#92;equiv &#92;texttt{(Bool, a)}$—or more algebraically, $a + a = 2a$.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;More formally, an isomorphism exists between types &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; if we can &lt;em&gt;convert between the two types without loss of information&lt;/em&gt;. The most straightforward approach is to define two functions: &lt;code&gt;toRHS :: a -&amp;gt; b&lt;/code&gt; and &lt;code&gt;toLHS :: b -&amp;gt; a&lt;/code&gt;. Alternatively with the algebra presented above, we can easily prove isomorphisms by checking the algebraic equivalence of two types!&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With the toy example presented above, our converters would be&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;toRHS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toRHS&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toRHS&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;toLHS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toLHS&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toLHS&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Notice how information is preserved, i.e. $&#92;texttt{toLHS }(&#92;texttt{toRHS } x) = x,&#92; &#92;forall x &#92;in &#92;texttt{Either a a}$ and $&#92;texttt{toRHS } (&#92;texttt{toLHS }y) = y, &#92; &#92;forall y &#92;in &#92;texttt{(Bool, a)}$.&lt;/p&gt;
&lt;p&gt;In the same vein, the following types are also equivalent:&lt;/p&gt;
&lt;p&gt;$$&#92;texttt{Maybe (Maybe a)} &#92;equiv &#92;texttt{Either Bool a}$$&lt;/p&gt;
&lt;p&gt;$$&#92;texttt{Maybe} &#92;texttt{(Either (a, a) (Bool, a))} &#92;equiv &#92;texttt{(Maybe a, Maybe a)}$$&lt;/p&gt;
&lt;!-- 
$$&#92;begin{align*}
&#92;texttt{Maybe (Maybe a)} &amp;&#92;equiv &#92;texttt{Either Bool a} &#92;&#92;&#92;&#92;
&#92;texttt{Maybe} &#92;texttt{(Either (a, a) (Bool, a))} &amp;&#92;equiv &#92;texttt{(Maybe a, Maybe a)}
&#92;end{align*}
$$ --&gt;
&lt;h3 id=&quot;unit-values-in-the-algebra-of-types&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#unit-values-in-the-algebra-of-types&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Unit Values in the Algebra of Types&lt;/h3&gt;
&lt;p&gt;But wait, there’s more! There are also &lt;em&gt;null&lt;/em&gt; and &lt;em&gt;unit&lt;/em&gt; types which behave just like 0 and 1 in the integers, with the usual axioms.&lt;/p&gt;
&lt;p&gt;Meet &lt;code&gt;Void&lt;/code&gt; and &lt;code&gt;()&lt;/code&gt;, two very special types. &lt;code&gt;Void&lt;/code&gt; resembles the null set: it has &lt;em&gt;no concrete values&lt;/em&gt;. So how is this type used? Well, without any concrete values, its primary utility is in the type level. For example, in the &lt;a href=&quot;https://hackage.haskell.org/package/megaparsec&quot;&gt;Megaparsec&lt;/a&gt; parsing library, &lt;code&gt;Void&lt;/code&gt; is used in &lt;code&gt;Parsec Void u a&lt;/code&gt; to indicate a default option.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;()&lt;/code&gt; is the 0-tuple, the singleton set containing &lt;code&gt;()&lt;/code&gt; itself. (To clarify, “&lt;code&gt;()&lt;/code&gt;” is both a type and a value, depending on the context.)&lt;/p&gt;
&lt;div class=&quot;alert alert-warning d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-triangle-exclamation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;C’s &lt;code&gt;void&lt;/code&gt; should &lt;strong&gt;not&lt;/strong&gt; be confused with Haskell’s &lt;code&gt;Void&lt;/code&gt;. The former is more like &lt;code&gt;()&lt;/code&gt;, containing only one possible result.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With these funky creatures, we can write isomorphisms such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;$&#92;texttt{Either Void a} &#92;equiv &#92;texttt{a}$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Corresponds to $0 + a = a$.&lt;/li&gt;
&lt;li&gt;Bijection:&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;toRHS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Void&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toRHS&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- toRHS (Left x) = undefined -- Implicit.&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;toLHS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Void&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toLHS&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$&#92;texttt{((), a)} &#92;equiv &#92;texttt{a}$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Corresponds to $1 &#92;times a = a$.&lt;/li&gt;
&lt;li&gt;Bijection:&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;toRHS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toRHS&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;toLHS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toLHS&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You may verify that the bijections&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fn4&quot; id=&quot;fnref4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; hold, i.e. show that $&#92;texttt{toLHS }(&#92;texttt{toRHS } x) = x$ and $&#92;texttt{toRHS }(&#92;texttt{toLHS } y) = y$ for any $x$ and $y$.&lt;/p&gt;
&lt;p&gt;As for other algebraic constructions, I shall kindly leave them as an exercise for the reader. 🙃 Try coming up with examples of types and bijections for the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Associativity: $(a + b) + c = a + (b + c)$, $(ab)c = a(bc)$&lt;/li&gt;
&lt;li&gt;Commutativity: $a + b = b + a$, $ab = ba$&lt;/li&gt;
&lt;li&gt;Distribution: $a(b + c) = ab + ac$&lt;/li&gt;
&lt;li&gt;Null: $0a = 0$&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;enums-as-sum-types&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#enums-as-sum-types&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Enums as Sum Types&lt;/h3&gt;
&lt;p&gt;An aside regarding sum types and enums.&lt;/p&gt;
&lt;p&gt;Early on I mentioned sum types as &lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#motivation-for-adts&quot;&gt;a way to combine &lt;em&gt;types&lt;/em&gt;&lt;/a&gt;. Then I suggested &lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#sum-types&quot;&gt;&lt;em&gt;enums&lt;/em&gt; as an example of sum types&lt;/a&gt;… But we usually think of enums as combining &lt;em&gt;values&lt;/em&gt;, not &lt;em&gt;types&lt;/em&gt;. What’s going on here?&lt;/p&gt;
&lt;p&gt;Well, one way to view enums is to treat each value as if they take a unit type &lt;code&gt;()&lt;/code&gt; parameter. That is,&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;True&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;(N.B. $&#92;texttt{Bool} &#92;equiv &#92;texttt{Either () ()}$.)&lt;/p&gt;
&lt;p&gt;Here, &lt;code&gt;False&lt;/code&gt; is a &lt;em&gt;data constructor&lt;/em&gt; while &lt;code&gt;()&lt;/code&gt; is a &lt;em&gt;type&lt;/em&gt;. In this version of &lt;code&gt;Bool&lt;/code&gt;, we’re basically combining a bunch of unit types &lt;code&gt;()&lt;/code&gt; using different tags.&lt;/p&gt;
&lt;p&gt;In this regard, we can think of enums as sugar-coated sum types; and conversely, sum types can be thought of as glorified enums. We’ve seen how enums and sum types can be defined similarly in Haskell. The same goes for Rust and Scala 3, where the &lt;code&gt;enum&lt;/code&gt; keyword is not only used to define enums, but also sum types (and in general, ADTs).&lt;/p&gt;
&lt;h2 id=&quot;conclusion-and-recap&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#conclusion-and-recap&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Conclusion and Recap&lt;/h2&gt;
&lt;p&gt;Is that all?&lt;/p&gt;
&lt;p&gt;Au contraire.&lt;/p&gt;
&lt;p&gt;Algebraic data types may be sufficient for most use cases, but we’ve only scratched the surface. There are more quirky animals out there! Generalised ADTs. Union/disjunctive types. Conjunctive/intersection types. Pi types.&lt;/p&gt;
&lt;p&gt;But to recap:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Algebraic data types (ADTs)&lt;/strong&gt; consist of &lt;em&gt;product types&lt;/em&gt; and &lt;em&gt;sum types&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;By leveraging ADTs, we can write code that is meaningful and concise, modelling the real world more closely.&lt;/li&gt;
&lt;li&gt;There are two main forms of ADTs. Both enable us to combine smaller types into larger types.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Product types&lt;/strong&gt; can be thought of as a &lt;em&gt;multiplication on types&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Similarly, &lt;strong&gt;sum types&lt;/strong&gt; are like a &lt;em&gt;summation on types&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ADTs follow mathematical laws similar to other structures (e.g. the integers), but without the inverse property. These mathematical laws allow us to rigorously reason with types.
&lt;ul&gt;
&lt;li&gt;We can express ADTs through a mathematical algebra such as $|&#92;texttt{(a, b)}| = a &#92;times b$ and $|&#92;texttt{Either a b}| = a + b$.&lt;/li&gt;
&lt;li&gt;Types with an equivalent algebraic representation are &lt;strong&gt;isomorphic&lt;/strong&gt;. This may prove useful in refactoring and optimising.&lt;/li&gt;
&lt;li&gt;The algebra of types follows &lt;strong&gt;algebraic laws&lt;/strong&gt; similar to the laws for integers and other algebras. There are laws on identity (e.g. $0 + a = a$), associativity, distribution, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Thus, in addition to their utilitarian use, types also exhibit an aesthetic beauty.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;references-further-reading&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#references-further-reading&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; References/Further Reading&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/gregberns/5e9da0c95a9a8d2b6338afe69310b945&quot;&gt;The Algebra of Algebraic Data Types: Part 1&lt;/a&gt; by Chris Taylor&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kseo.github.io/posts/2016-12-25-type-isomorphism.html&quot;&gt;Type Isomorphism&lt;/a&gt; by Kwang Yul Seo&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20140122164049/http://chris-taylor.github.io/blog/2013/02/11/the-algebra-of-algebraic-data-types-part-ii/&quot;&gt;The Algebra of Algebraic Data Types: Part 2&lt;/a&gt; by Chris Taylor (dives into recursive ADTs!)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;We could do the same in C++ by using &lt;a href=&quot;https://theboostcpplibraries.com/boost.variant&quot;&gt;Boost variant&lt;/a&gt;, using &lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/variant&quot;&gt;C++17’s &lt;code&gt;std::variant&lt;/code&gt;&lt;/a&gt;, or using a tagged union (which is just a &lt;code&gt;union&lt;/code&gt; with a &lt;code&gt;uint8_t&lt;/code&gt;/&lt;code&gt;int&lt;/code&gt; tag). &lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;&lt;code&gt;std::optional&lt;/code&gt; was introduced in C++17, and &lt;code&gt;std::expected&lt;/code&gt; is expected (haha) to arrive with C++23. You can still pull these types from various libraries though. &lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;I should mention—there are significant differences between types and sets. But please bear with me, for the sake of this post. ._. &lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/Bijection&quot;&gt;bijection&lt;/a&gt; is also known as a &lt;em&gt;one-to-one correspondence&lt;/em&gt; or &lt;em&gt;invertible&lt;/em&gt; function. Each input must map to one (and only one) unique output.
&lt;br /&gt;
Functions such as $x &#92;mapsto &#92;sqrt{x}$ and $x &#92;mapsto &#92;lfloor x &#92;rfloor$ are not bijections since multiple inputs may map to the same output—we can&#39;t recover a unique input given an output. This is the whole idea of being &lt;em&gt;invertible&lt;/em&gt;. &lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fnref4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>programming</category>
        
          <category>mathematics</category>
        
          <category>haskell</category>
        
          <category>types</category>
        
          <category>functional</category>
        
          <category>software-engineering</category>
        
          <category>programming-languages</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>AOC 2021 Day&amp;nbsp;22 – Reactor Reboot</title>
        <description>Reboot reactors from a submarine using set theory.</description>
        <link href="https://trebledj.me/posts/aoc-2021-day-22/"/>
        <updated>2022-12-02T00:00:00Z</updated>
        <id>https://trebledj.me/posts/aoc-2021-day-22/</id>
        <content xml:lang="en" type="html">&lt;p&gt;This post is a (very very late) writeup on solving the &lt;a href=&quot;https://trebledj.me/tags/aoc/&quot;&gt;Advent of Code&lt;/a&gt; &lt;a href=&quot;https://adventofcode.com/2021/day/22&quot;&gt;2021 Day 22 challenge&lt;/a&gt;. This was one of the challenges I spent more time on, and ended up developing three algorithms (which is a bit overkill), all using set theory. I also ended up writing all three in both Haskell and Rust, and benchmarking to compare the runtimes. Needless to say, Rust ran about 25%-50% faster, but performance tuning is not the main point of this article.&lt;/p&gt;
&lt;p&gt;I&#39;ll &lt;em&gt;mainly&lt;/em&gt; show code snippets and implementations in Rust, well, because I think it&#39;s more readable. But the general ideas are similar in Haskell.&lt;/p&gt;
&lt;h2 id=&quot;the-problem&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#the-problem&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Problem&lt;/h2&gt;
&lt;p&gt;It’s a fun, little problem. We&#39;re given a list of input. Each line specifies an action (&lt;code&gt;on&lt;/code&gt; or &lt;code&gt;off&lt;/code&gt;) and a cuboid (rectangular prism) of points &lt;code&gt;x=10..12,y=10..12,z=10..12&lt;/code&gt;. Each line will switch all points within the cuboid on or off.&lt;/p&gt;
&lt;p&gt;Sample input:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;on x=10..12,y=10..12,z=10..12
on x=11..13,y=11..13,z=11..13
off x=9..11,y=9..11,z=9..11
on x=10..10,y=10..10,z=10..10&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The objective is to determine the number of points that are still &lt;code&gt;on&lt;/code&gt; after applying every line.&lt;/p&gt;
&lt;h2 id=&quot;solving&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#solving&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Solving&lt;/h2&gt;
&lt;p&gt;There are three main components to most of my AOC solves. For this challenge, we&#39;ll be implementing these functions.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;contents&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;part1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cmds&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;, and&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;part2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cmds&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For Day 22, the only difference between part 1 and part 2 is the bound size, so a solution for part 2 would also be able to solve part 1 (but of course I didn&#39;t know this until later).&lt;/p&gt;
&lt;h3 id=&quot;parsing&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#parsing&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Parsing&lt;/h3&gt;
&lt;p&gt;Parsing is actually pretty straightforward, so let&#39;s get it out of the way first. Essentially, we translate each line of text to a 2-tuple: &lt;code&gt;(bool, Cuboid)&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-rust&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Some useful type aliases.&lt;/span&gt;
&lt;span class=&quot;token attribute attr-name&quot;&gt;#[allow(non_camel_case_types)]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;cube_t&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Each pair corresponds to min/max values in a dimension.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;Cuboid&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cuboid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Parse takes a String and returns a Vec of Commands.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;contents&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; re &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Regex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;r&quot;(on|off) x=(-?&#92;d+)..(-?&#92;d+),y=(-?&#92;d+)..(-?&#92;d+),z=(-?&#92;d+)..(-?&#92;d+)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contents
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Split text at lines.&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token closure-params&quot;&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;s&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; cap &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; re&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;captures_iter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Match with regex, and get capture groups.&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
                    &lt;span class=&quot;token comment&quot;&gt;// Capture group 0 is the entire matched string. So we start with 1, to obtain the first capture group.&lt;/span&gt;
                    cap&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;on&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// str&#39;s parse is builtin and returns an Option&amp;lt;_&amp;gt;.&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cap&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;cube_t&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cap&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;cube_t&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cap&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;cube_t&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cap&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;cube_t&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cap&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;cube_t&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cap&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;cube_t&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token macro property&quot;&gt;unreachable!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;aaaaaah&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Safety measure. We assume all lines follow the above pattern.&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Rust&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3 id=&quot;a-naive-approach&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#a-naive-approach&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; A Naive Approach&lt;/h3&gt;
&lt;p&gt;Our first attempt may be to use a naive brute force approach. We keep track of every single point and whether it is toggled or not. Of course this will not scale well especially if the cubes become larger; but for part 1 of the challenge, it is sufficient. Part 1 simply confines the scope of our problem to &lt;code&gt;((-50, 50), (-50, 50), (-50, 50))&lt;/code&gt;. Any points activated or deactivated outside can be disregarded.&lt;/p&gt;
&lt;p&gt;We can use a HashSet to store the 3D points. &lt;code&gt;on&lt;/code&gt; would correspond with &lt;code&gt;set.insert&lt;/code&gt; and  &lt;code&gt;off&lt;/code&gt; would correspond to &lt;code&gt;set.remove&lt;/code&gt;. Thus after processing, we just need to &lt;em&gt;count&lt;/em&gt; the number of elements (&lt;code&gt;set.len()&lt;/code&gt;) to get the number of points that are left &lt;strong&gt;on&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Further, we’ll also restrict our scope by using &lt;code&gt;.max&lt;/code&gt; and &lt;code&gt;.min&lt;/code&gt; so that if, say &lt;code&gt;x1&lt;/code&gt; is way out there at &lt;code&gt;-1000&lt;/code&gt;, &lt;code&gt;x1.max(-r)&lt;/code&gt; will pull it back to &lt;code&gt;-50&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-rust&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Solution 1: Brute-force Approach.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HashSet&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;brute_force&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cmds&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; set&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HashSet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;onoff&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;z1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; z2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; cmds &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; x1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..=&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; j &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..=&lt;/span&gt;y2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; k &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; z1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..=&lt;/span&gt;z2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; onoff &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        set&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; j&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; k&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        set&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; j&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; k&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    set&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u32&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Rust&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Simple, right? Unfortunately for large cuboids this approach becomes extremely slow. By “large”, I mean cuboids like &lt;code&gt;x=-100000..100000, y=-100000..100000, z=-100000..100000&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To deal with these big numbers, we need to bring in some big guns!&lt;/p&gt;
&lt;h3 id=&quot;a-set-union-approach&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#a-set-union-approach&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; A Set Union Approach&lt;/h3&gt;
&lt;p&gt;In part 1, our scope was limited to a 100x100x100 cube centred on the origin. Part 2 &lt;em&gt;removes&lt;/em&gt; this scope, meaning we have to take into account &lt;em&gt;every single point in existence&lt;/em&gt;! Time to use this organ called the brain!&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Pikachu, use brain!&quot; href=&quot;https://trebledj.me/img/posts/programming/aoc-2021/assets/aoc-2021-day-22-bigbrain-600w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-45&quot; src=&quot;https://trebledj.me/img/posts/programming/aoc-2021/assets/aoc-2021-day-22-bigbrain-600w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 600 / 452&quot; alt=&quot;Pikachu, use brain!&quot; title=&quot;Pikachu, use brain!&quot; srcset=&quot;https://trebledj.me/img/posts/programming/aoc-2021/assets/aoc-2021-day-22-bigbrain-256w.webp 256w, https://trebledj.me/img/posts/programming/aoc-2021/assets/aoc-2021-day-22-bigbrain-512w.webp 512w, https://trebledj.me/img/posts/programming/aoc-2021/assets/aoc-2021-day-22-bigbrain-600w.webp 600w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 600px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let’s start with some investigative work and put on our thinking caps. For the moment, let’s imagine we’re working in 2D instead of 3D. Also, imagine our input is in some generic form.&lt;/p&gt;
&lt;div class=&quot;mb-2 rw center jw-75 video&quot;&gt;&lt;video autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; class=&quot;jw-100&quot;&gt;&lt;source src=&quot;https://trebledj.me/img/aoc-2021-day-22-anim1.mp4&quot; type=&quot;video/mp4&quot; /&gt;&lt;/video&gt;&lt;/div&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;$A$ &lt;code&gt;on&lt;/code&gt;, $B$ &lt;code&gt;on&lt;/code&gt;, $C$ &lt;code&gt;on&lt;/code&gt;.&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;mb-2 rw center jw-75 video&quot;&gt;&lt;video autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; class=&quot;jw-100&quot;&gt;&lt;source src=&quot;https://trebledj.me/img/aoc-2021-day-22-anim2.mp4&quot; type=&quot;video/mp4&quot; /&gt;&lt;/video&gt;&lt;/div&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;$A$ &lt;code&gt;on&lt;/code&gt;, $B$ &lt;code&gt;off&lt;/code&gt;, $C$ &lt;code&gt;on&lt;/code&gt;.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;When $A$ turns &lt;code&gt;on&lt;/code&gt;, all the points in $A$ light up. Currently, we have $|A|$ points. Now let’s explore our next options.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$B$ turns &lt;code&gt;on&lt;/code&gt;. We now have $|A &#92;cup B|$ points.&lt;/li&gt;
&lt;li&gt;$B$ turns &lt;code&gt;off&lt;/code&gt;. How many points were switched off? Well, we simply subtract the intersection $|A &#92;cap B|$, so that we end up with $|A| - |A &#92;cap B| = |A &#92;cup B| - |B|$ points.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Continuing further, we have&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;$B$ &lt;code&gt;on&lt;/code&gt;: $|A &#92;cup B|$.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;$C$ &lt;code&gt;on&lt;/code&gt; → $|A &#92;cup B &#92;cup C|$ points.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$C$ &lt;code&gt;off&lt;/code&gt; → Again, we subtract the intersection. $|A &#92;cup B| - |(A &#92;cup B) &#92;cap C| = |A &#92;cup B &#92;cup C| - |C|$ points.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$B$ &lt;code&gt;off&lt;/code&gt;: $|A &#92;cup B| - |B|$.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;$C$ &lt;code&gt;on&lt;/code&gt; → We want to add $|C|$, but suppose the points were already counted? We would need to subtract the &lt;em&gt;double-counted&lt;/em&gt; points by considering the intersection of the new set $C$ and &lt;strong&gt;original&lt;/strong&gt; points. We thus have—brace yourself—three new terms: $- |(A &#92;cup B) &#92;cap C|$, $+ |B &#92;cap C|$, and $+ |C|$.&lt;/p&gt;
&lt;p&gt;$$
&#92;underbrace{|A &#92;cup B| - |B|}_{&#92;text{original sets}} - &#92;underbrace{|(A &#92;cup B) &#92;cap C| + |B &#92;cap C|}_{&#92;text{subtract double-counted}} + |C|.
$$&lt;/p&gt;
&lt;p&gt;Regrouping and simplifying, we get&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align*}
&amp;amp;|A &#92;cup B| + |C| - |(A &#92;cup B) &#92;cap C| - |B| + |B &#92;cap C| &#92;&#92;
&amp;amp;= &#92;underbrace{|A &#92;cup B &#92;cup C| - |B &#92;cup C|}_{&#92;text{original sets unioned with } C} + &#92;underbrace{|C|}_{&#92;text{new}}.
&#92;end{align*}
$$&lt;/p&gt;
&lt;p&gt;Notice how we started off from $|A &#92;cup B| - |B|$, and now we&#39;ve simply extended them with $&#92;cup&#92; C$ and added a $|C|$ term.&lt;/p&gt;
&lt;p&gt;This is actually similar to what we did when turning $B$ &lt;code&gt;off&lt;/code&gt; the first time! We originally had $|A|$, then introduced $&#92;cup&#92; B$, and subtracted $|B|$ so that we don’t count anything from $B$. We &lt;strong&gt;subtracted&lt;/strong&gt; $|B|$ then, since we were turning $B$ &lt;code&gt;off&lt;/code&gt;, but now we &lt;em&gt;add&lt;/em&gt; $|C|$ since we’re turning $C$ &lt;code&gt;on&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Finally, let’s see what happens for the $A$ &lt;code&gt;on&lt;/code&gt;, $B$ &lt;code&gt;off&lt;/code&gt;, $C$ &lt;code&gt;off&lt;/code&gt; case.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$C$ &lt;code&gt;off&lt;/code&gt; → We can think of this as similar to the $B$ &lt;code&gt;off&lt;/code&gt; $C$ &lt;code&gt;on&lt;/code&gt; path above, except we don’t add the $|C|$ term. So we just have two terms:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align*}
&amp;amp;&#92;underbrace{|A &#92;cup B &#92;cup C| - |B &#92;cup C| + |C|}_{&#92;text{same as } B &#92;text{ off, } C &#92;text{ on}} - &#92;underbrace{|C|}_{&#92;text{new}} &#92;&#92;
&amp;amp;= |A &#92;cup B &#92;cup C| - |B &#92;cup C|.
&#92;end{align*}
$$&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notice that as we consider a new set, we union it with the previous sets. For example, $A$ &lt;code&gt;on&lt;/code&gt; $B$ &lt;code&gt;off&lt;/code&gt; has $|A &#92;cup B| - |B|$ points. After adding $C$ &lt;code&gt;off&lt;/code&gt;, we have $|A &#92;cup B &#92;cup C| - |B &#92;cup C|$ points. Notice the similarity?&lt;/p&gt;
&lt;p&gt;Moreover, we add a new term each time we change between &lt;code&gt;on&lt;/code&gt; and &lt;code&gt;off&lt;/code&gt;. We see this above in when going from $A$ &lt;code&gt;on&lt;/code&gt; to $B$ &lt;code&gt;off&lt;/code&gt;, from $B$ &lt;code&gt;on&lt;/code&gt; to $C$ &lt;code&gt;off&lt;/code&gt;, and $B$ &lt;code&gt;off&lt;/code&gt; to $C$ &lt;code&gt;on&lt;/code&gt;. Each time it’s one new term, and it’s the opposite sign of the previous term. It goes without saying, that this can be generalised.&lt;/p&gt;
&lt;h3 id=&quot;can-we-build-it-yes-we-can&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#can-we-build-it-yes-we-can&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Can we build it? Yes, we can!&lt;/h3&gt;
&lt;p&gt;Moving on to practical matters… how do we code this? We’ll separate the logic into two stages: one for building a set expression, the other for evaluating the expression.&lt;/p&gt;
&lt;p&gt;Taking a lesson from functional programming, let’s discuss data and representation first. We can represent a union as a vector of cuboids: &lt;code&gt;Vec&amp;lt;Cuboid&amp;gt;&lt;/code&gt;. But a cuboid is six integers, and the sets in our union all come from the input. So we can actually use a vector of indices instead: &lt;code&gt;Vec&amp;lt;usize&amp;gt;&lt;/code&gt;. We’ll wrap these vectors in another container to represent our alternating union (this means every second term subtracts). I went for &lt;code&gt;LinkedList&lt;/code&gt; for performance, but &lt;code&gt;Vec&lt;/code&gt; should work as well.&lt;/p&gt;
&lt;p&gt;Let’s build our set expression then:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-rust&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; alternating_unions&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LinkedList&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LinkedList&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; lookup &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cmds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token closure-params&quot;&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;_&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;on&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; cmds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; v &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; alternating_unions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;iter_mut&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Push the current tag.&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;alternating_unions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; on &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// A new union term is added if &quot;on&quot; and even, or &quot;off&quot; and odd.&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; v &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token macro property&quot;&gt;vec!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reserve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cmds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Smol optimisation.&lt;/span&gt;
        alternating_unions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;v&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Rust&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Evaluating the union is simply a matter of taking the set of unions, applying the inclusion-exclusion and generating a DFS tree with pruning. Those are some pretty big words. Let’s unpack it a bit.&lt;/p&gt;
&lt;h3 id=&quot;what-the-heck-is-the-inclusion-exclusion-principle&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#what-the-heck-is-the-inclusion-exclusion-principle&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; What the heck is the Inclusion-Exclusion Principle?&lt;/h3&gt;
&lt;p&gt;Given two sets $A$ and $B$, we can compute the union through $|A &#92;cup B| = |A| + |B| - |A &#92;cap B|$. The idea is that we add $A$ and $B$; but since we double-counted the overlapping region ($A &#92;cap B$), we subtract it once to balance things out. It turns out this principle can be generalised for any number of sets.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Venn diagram of the inclusion-exclusion principle.&quot; href=&quot;https://trebledj.me/img/VennDiagram_900-1024w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-65 alpha-img&quot; src=&quot;https://trebledj.me/img/VennDiagram_900-351w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 351 / 152&quot; alt=&quot;Venn diagram of the inclusion-exclusion principle.&quot; title=&quot;Venn diagram of the inclusion-exclusion principle.&quot; srcset=&quot;https://trebledj.me/img/VennDiagram_900-256w.webp 256w, https://trebledj.me/img/VennDiagram_900-351w.webp 351w, https://trebledj.me/img/VennDiagram_900-512w.webp 512w, https://trebledj.me/img/VennDiagram_900-1024w.webp 1024w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 351px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Take a look at the diagram and convince yourself that for three sets, we have&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align*}
|A&#92;nobreak&#92;cup&#92;nobreak B&#92;nobreak&#92;cup&#92;nobreak C| = &amp;amp;|A| + |B| + |C| &#92;&#92;
&amp;amp;- |A &#92;cap B| - |A &#92;cap C| - |B &#92;cap C| &#92;&#92;
&amp;amp;+ |A &#92;cap B &#92;cap C|.
&#92;end{align*}
$$&lt;/p&gt;
&lt;p&gt;The inclusion-exclusion principle extends this idea to $n$ sets by including (adding) sets and excluding (subtracting) sets. The general formula for $n$ sets is&lt;/p&gt;
&lt;p&gt;$$
&#92;left| &#92;bigcup_{i=0}^n A_i &#92;right| = &#92;sum_{k=1}^n (-1)^{k+1} &#92;left( &#92;sum_{1 &#92;le i_1 &amp;lt; &#92;cdots &amp;lt; i_k &#92;le n} |A_{i_1} &#92;cap &#92;cdots &#92;cap A_{i_k}| &#92;right).
$$&lt;/p&gt;
&lt;h3 id=&quot;the-inclusion-exclusion-principle-as-dfs&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#the-inclusion-exclusion-principle-as-dfs&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Inclusion-Exclusion Principle as DFS&lt;/h3&gt;
&lt;p&gt;Earlier I mentioned DFS with pruning. Why DFS?&lt;/p&gt;
&lt;p&gt;Let’s say we want to evaluate $|A &#92;cup B &#92;cup C|$. In a breadth-first approach, we would first evaluate the $k=1$ sets ($|A|$, $|B|$, $|C|$), followed by the $k=2$ sets ($|A &#92;cap B|$, $|A &#92;cap C|$, $|B &#92;cap C|$), and so on. However, a depth-first approach would be more efficient in this case. Once we’ve computed $|A &#92;cap B|$, we can compute $|A &#92;cap B &#92;cap C|$ as well.&lt;/p&gt;
&lt;p&gt;Here’s a DFS tree for computing $|A &#92;cup B &#92;cup C|$:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;A u B u C
|-- A
|   |-- A n B
|   |   |-- A n B n C
|   |
|   |-- A n C
|
|-- B
|   |-- B n C
|
|-- C&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Can we parallelise this? Probably. But let’s leave that for another time.&lt;/p&gt;
&lt;p&gt;Now what if two sets are disjoint? Suppose $A = ((0, 10), (0, 10), (0, 10))$ and $B = ((100, 200), (0, 10), (0, 10))$. These two sets have nothing in common, i.e. $A &#92;cap B = &#92;varnothing$. It follows that $A &#92;cap B &#92;cap C = &#92;varnothing$. Thus, once we know a set has no intersection, we don’t need to further explore its branches. This is the &lt;strong&gt;pruning&lt;/strong&gt; part of the DFS.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-rust&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// @brief   Computes the number of points in a cuboid.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// @return  Number of points in a cuboid.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;eval_cuboid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;z1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; z2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Cuboid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u64&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// @brief   Computes the intersection of a cuboid.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// @return  Some(Cuboid) if the intersection exists, None otherwise.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;intersect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; z1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Cuboid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; z2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Cuboid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Cuboid&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// @brief    Finds the intersection between two ranges.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// @return   Some((cube_t, cube_t)) if an intersection exists, None if there is no intersection.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;range_intersect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; a2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;b1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// @brief    eval_union computes the number of points in the union of sets `u`.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// @param    lookup: A lookup table of cuboids. Our sets will be represented as an array of indices (storing one i32 instead of six i32&#39;s).&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// @param    add: Whether the current iteration adds or subtracts the union.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// @param    int: The current intersected cuboid.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// @param    u: The set of cuboids in the current union.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;eval_union&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lookup&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Cuboid&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; add&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; int&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cuboid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; u&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    u&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token closure-params&quot;&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;tag&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;intersect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;int&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;lookup&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;tag&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;next_int&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; v &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;eval_cuboid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;next_int&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; rest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;eval_union&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lookup&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;add&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next_int&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;u&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; add &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    rest &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; v
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    rest &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; v
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// No intersection. No need to evaluate deeper, since any intersection with the empty set will just be the empty set.&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; scope &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
alternating_unions
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token closure-params&quot;&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; u&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;eval_union&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;lookup&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; scope&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;u&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Rust&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h2 id=&quot;final-remarks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#final-remarks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Final Remarks&lt;/h2&gt;
&lt;p&gt;This was one of the more challenging (but also rewarding!) Advent of Code challenges this year. Some others propose a cuboid-slicing method as opposed to set theory. However, I find this approach difficult to grasp and plan. Moreover, cuboid-slicing appears more difficult to generalise into higher dimensions, whereas with the set theoretic approach you pretty much just need to change the data types and &lt;code&gt;intersect&lt;/code&gt; functions.&lt;/p&gt;
&lt;p&gt;Anyway, let’s end on a pedagogical note. Here are some exercises for the reader:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The set expression we built above contains some redundant information. What is redundant, and how can we optimise it?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the code above, we initialised our search with a scope.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-rust&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; scope &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Rust&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Points outside the scope won’t be considered. Rewrite the evaluation logic so that a scope doesn’t need to be specified.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In this post, we used a union-based approach, i.e. storing an alternating set of unions, then computing it by applying the inclusion-exclusion principle. Try rewriting the algorithm into an intersection-based approach. Instead of storing unions, store sets of intersections.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What are the computation differences?&lt;/li&gt;
&lt;li&gt;Compare the two algorithms. Under what circumstances are one better?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;full-script&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#full-script&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Full Script&lt;/h2&gt;
&lt;p&gt;For completeness, here&#39;s the full d22.rs script.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/TrebledJ/7190c102579bfde273a7b74e90116b49.js&quot;&gt;&lt;/script&gt;
</content>
        
          <category>programming</category>
        
          <category>aoc</category>
        
          <category>rust</category>
        
          <category>mathematics</category>
        
          <category>writeup</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>Fractons</title>
        <description>An interactive fractions game for elementary students made using Felgo/QML.</description>
        <link href="https://trebledj.me/posts/fractons/"/>
        <updated>2019-05-24T00:00:00Z</updated>
        <id>https://trebledj.me/posts/fractons/</id>
        <content xml:lang="en" type="html">&lt;p&gt;Fractons is an educational, interactive fractions game for elementary students made using Felgo/QML. The project is published &lt;a href=&quot;https://github.com/TrebledJ/fractons&quot;&gt;online&lt;/a&gt; along with a &lt;a href=&quot;https://github.com/TrebledJ/fractons/releases/tag/v1.0&quot;&gt;release build for macOS&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;features&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/fractons/#features&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Features&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Exp + Levelling Mechanics 📈&lt;/li&gt;
&lt;li&gt;Clean, slick, and bubbly UI&lt;/li&gt;
&lt;li&gt;5 different question modes!&lt;/li&gt;
&lt;li&gt;40+ achievements (including secret achievements! 🤫)&lt;/li&gt;
&lt;li&gt;Statistics, to see how well you&#39;re doing&lt;/li&gt;
&lt;li&gt;Fun little lottery system&lt;/li&gt;
&lt;li&gt;Number pad (for mobile/tablets), configurable in settings&lt;/li&gt;
&lt;li&gt;Daily quests! 🤠&lt;/li&gt;
&lt;li&gt;SFX and background music 🎵&lt;/li&gt;
&lt;li&gt;Floating fractions in the background (with the occasional secret! 🤫)&lt;/li&gt;
&lt;li&gt;Notifications to notify you when you level up, complete a quest, or earn an achievement&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;showcase&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/fractons/#showcase&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Showcase&lt;/h3&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Fractons: Main Menu&quot; href=&quot;https://trebledj.me/img/posts/projects/02-fractons/assets/img2-1916w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-85&quot; src=&quot;https://trebledj.me/img/posts/projects/02-fractons/assets/img2-1916w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1916 / 1276&quot; alt=&quot;Fractons: Main Menu&quot; title=&quot;Fractons: Main Menu&quot; srcset=&quot;https://trebledj.me/img/posts/projects/02-fractons/assets/img2-256w.webp 256w, https://trebledj.me/img/posts/projects/02-fractons/assets/img2-512w.webp 512w, https://trebledj.me/img/posts/projects/02-fractons/assets/img2-1024w.webp 1024w, https://trebledj.me/img/posts/projects/02-fractons/assets/img2-1916w.webp 1916w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1916px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Main menu. Daily quests are on the left. Achievements, statistics on the top left. Notifications and settings on the top right.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Fractons: Solver UI&quot; href=&quot;https://trebledj.me/img/posts/projects/02-fractons/assets/img4-1909w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-85&quot; src=&quot;https://trebledj.me/img/posts/projects/02-fractons/assets/img4-1909w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1909 / 1273&quot; alt=&quot;Fractons: Solver UI&quot; title=&quot;Fractons: Solver UI&quot; srcset=&quot;https://trebledj.me/img/posts/projects/02-fractons/assets/img4-256w.webp 256w, https://trebledj.me/img/posts/projects/02-fractons/assets/img4-512w.webp 512w, https://trebledj.me/img/posts/projects/02-fractons/assets/img4-1024w.webp 1024w, https://trebledj.me/img/posts/projects/02-fractons/assets/img4-1909w.webp 1909w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1909px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Solving questions in Balance mode. How fast can you fill in the question mark?&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;center rw mb-2  lightbox-gallery&quot;&gt;
&lt;a class=&quot;&quot; title=&quot;Fractons: Achievements!&quot; href=&quot;https://trebledj.me/img/posts/projects/02-fractons/assets/img5-1913w.webp&quot;&gt;&lt;img class=&quot;jw-45 multi&quot; src=&quot;https://trebledj.me/img/posts/projects/02-fractons/assets/img5-1913w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1913 / 1280&quot; alt=&quot;Fractons: Achievements!&quot; title=&quot;Fractons: Achievements!&quot; srcset=&quot;https://trebledj.me/img/posts/projects/02-fractons/assets/img5-256w.webp 256w, https://trebledj.me/img/posts/projects/02-fractons/assets/img5-512w.webp 512w, https://trebledj.me/img/posts/projects/02-fractons/assets/img5-1024w.webp 1024w, https://trebledj.me/img/posts/projects/02-fractons/assets/img5-1913w.webp 1913w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1913px&quot; /&gt;&lt;/a&gt;
&lt;a class=&quot;&quot; title=&quot;Fractons: More Achievements!&quot; href=&quot;https://trebledj.me/img/posts/projects/02-fractons/assets/img6-1915w.webp&quot;&gt;&lt;img class=&quot;jw-45 multi&quot; src=&quot;https://trebledj.me/img/posts/projects/02-fractons/assets/img6-1915w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1915 / 1278&quot; alt=&quot;Fractons: More Achievements!&quot; title=&quot;Fractons: More Achievements!&quot; srcset=&quot;https://trebledj.me/img/posts/projects/02-fractons/assets/img6-256w.webp 256w, https://trebledj.me/img/posts/projects/02-fractons/assets/img6-512w.webp 512w, https://trebledj.me/img/posts/projects/02-fractons/assets/img6-1024w.webp 1024w, https://trebledj.me/img/posts/projects/02-fractons/assets/img6-1915w.webp 1915w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1915px&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Tons of achievements to try to earn!&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&quot;history&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/fractons/#history&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; History&lt;/h3&gt;
&lt;p&gt;Fractons was originally programmed in Flash/Actionscript 2.0 for a ninth grade design project targetting fifth/sixth graders. It was later reprogrammed in a more appealing UI with user engagement features such as daily quests and a lottery.&lt;/p&gt;
</content>
        
          <category>project</category>
        
          <category>project</category>
        
          <category>qml</category>
        
          <category>software-engineering</category>
        
          <category>felgo</category>
        
          <category>js</category>
        
          <category>qt</category>
        
          <category>learning</category>
        
          <category>apps</category>
        
          <category>mathematics</category>
        
      </entry>
    
  
</feed>