787 lines
82 KiB
HTML
787 lines
82 KiB
HTML
|
||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
<head>
|
||
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
|
||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
<title>Advent of Code 2017 — Thun 0.2.0 documentation</title>
|
||
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||
<script type="text/javascript" src="../_static/documentation_options.js"></script>
|
||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||
<link rel="index" title="Index" href="../genindex.html" />
|
||
<link rel="search" title="Search" href="../search.html" />
|
||
|
||
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
|
||
|
||
|
||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||
|
||
</head><body>
|
||
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<div class="section" id="advent-of-code-2017">
|
||
<h1>Advent of Code 2017<a class="headerlink" href="#advent-of-code-2017" title="Permalink to this headline">¶</a></h1>
|
||
<div class="section" id="december-3rd">
|
||
<h2>December 3rd<a class="headerlink" href="#december-3rd" title="Permalink to this headline">¶</a></h2>
|
||
<p>You come across an experimental new kind of memory stored on an infinite
|
||
two-dimensional grid.</p>
|
||
<p>Each square on the grid is allocated in a spiral pattern starting at a
|
||
location marked 1 and then counting up while spiraling outward. For
|
||
example, the first few squares are allocated like this:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">17</span> <span class="mi">16</span> <span class="mi">15</span> <span class="mi">14</span> <span class="mi">13</span>
|
||
<span class="mi">18</span> <span class="mi">5</span> <span class="mi">4</span> <span class="mi">3</span> <span class="mi">12</span>
|
||
<span class="mi">19</span> <span class="mi">6</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">11</span>
|
||
<span class="mi">20</span> <span class="mi">7</span> <span class="mi">8</span> <span class="mi">9</span> <span class="mi">10</span>
|
||
<span class="mi">21</span> <span class="mi">22</span> <span class="mi">23</span><span class="o">---></span> <span class="o">...</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>While this is very space-efficient (no squares are skipped), requested
|
||
data must be carried back to square 1 (the location of the only access
|
||
port for this memory system) by programs that can only move up, down,
|
||
left, or right. They always take the shortest path: the Manhattan
|
||
Distance between the location of the data and square 1.</p>
|
||
<p>For example:</p>
|
||
<ul class="simple">
|
||
<li>Data from square 1 is carried 0 steps, since it’s at the access port.</li>
|
||
<li>Data from square 12 is carried 3 steps, such as: down, left, left.</li>
|
||
<li>Data from square 23 is carried only 2 steps: up twice.</li>
|
||
<li>Data from square 1024 must be carried 31 steps.</li>
|
||
</ul>
|
||
<p>How many steps are required to carry the data from the square identified
|
||
in your puzzle input all the way to the access port?</p>
|
||
<div class="section" id="analysis">
|
||
<h3>Analysis<a class="headerlink" href="#analysis" title="Permalink to this headline">¶</a></h3>
|
||
<p>I freely admit that I worked out the program I wanted to write using
|
||
graph paper and some Python doodles. There’s no point in trying to write
|
||
a Joy program until I’m sure I understand the problem well enough.</p>
|
||
<p>The first thing I did was to write a column of numbers from 1 to n (32
|
||
as it happens) and next to them the desired output number, to look for
|
||
patterns directly:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">0</span>
|
||
<span class="mi">2</span> <span class="mi">1</span>
|
||
<span class="mi">3</span> <span class="mi">2</span>
|
||
<span class="mi">4</span> <span class="mi">1</span>
|
||
<span class="mi">5</span> <span class="mi">2</span>
|
||
<span class="mi">6</span> <span class="mi">1</span>
|
||
<span class="mi">7</span> <span class="mi">2</span>
|
||
<span class="mi">8</span> <span class="mi">1</span>
|
||
<span class="mi">9</span> <span class="mi">2</span>
|
||
<span class="mi">10</span> <span class="mi">3</span>
|
||
<span class="mi">11</span> <span class="mi">2</span>
|
||
<span class="mi">12</span> <span class="mi">3</span>
|
||
<span class="mi">13</span> <span class="mi">4</span>
|
||
<span class="mi">14</span> <span class="mi">3</span>
|
||
<span class="mi">15</span> <span class="mi">2</span>
|
||
<span class="mi">16</span> <span class="mi">3</span>
|
||
<span class="mi">17</span> <span class="mi">4</span>
|
||
<span class="mi">18</span> <span class="mi">3</span>
|
||
<span class="mi">19</span> <span class="mi">2</span>
|
||
<span class="mi">20</span> <span class="mi">3</span>
|
||
<span class="mi">21</span> <span class="mi">4</span>
|
||
<span class="mi">22</span> <span class="mi">3</span>
|
||
<span class="mi">23</span> <span class="mi">2</span>
|
||
<span class="mi">24</span> <span class="mi">3</span>
|
||
<span class="mi">25</span> <span class="mi">4</span>
|
||
<span class="mi">26</span> <span class="mi">5</span>
|
||
<span class="mi">27</span> <span class="mi">4</span>
|
||
<span class="mi">28</span> <span class="mi">3</span>
|
||
<span class="mi">29</span> <span class="mi">4</span>
|
||
<span class="mi">30</span> <span class="mi">5</span>
|
||
<span class="mi">31</span> <span class="mi">6</span>
|
||
<span class="mi">32</span> <span class="mi">5</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>There are four groups repeating for a given “rank”, then the pattern
|
||
enlarges and four groups repeat again, etc.</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="mi">1</span> <span class="mi">2</span>
|
||
<span class="mi">3</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span>
|
||
<span class="mi">5</span> <span class="mi">4</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span>
|
||
<span class="mi">7</span> <span class="mi">6</span> <span class="mi">5</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span> <span class="mi">7</span> <span class="mi">8</span>
|
||
<span class="mi">9</span> <span class="mi">8</span> <span class="mi">7</span> <span class="mi">6</span> <span class="mi">5</span> <span class="mi">6</span> <span class="mi">7</span> <span class="mi">8</span> <span class="mi">9</span> <span class="mi">10</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Four of this pyramid interlock to tile the plane extending from the
|
||
initial “1” square.</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="mi">2</span> <span class="mi">3</span> <span class="o">|</span> <span class="mi">4</span> <span class="mi">5</span> <span class="o">|</span> <span class="mi">6</span> <span class="mi">7</span> <span class="o">|</span> <span class="mi">8</span> <span class="mi">9</span>
|
||
<span class="mi">10</span> <span class="mi">11</span> <span class="mi">12</span> <span class="mi">13</span><span class="o">|</span><span class="mi">14</span> <span class="mi">15</span> <span class="mi">16</span> <span class="mi">17</span><span class="o">|</span><span class="mi">18</span> <span class="mi">19</span> <span class="mi">20</span> <span class="mi">21</span><span class="o">|</span><span class="mi">22</span> <span class="mi">23</span> <span class="mi">24</span> <span class="mi">25</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>And so on.</p>
|
||
<p>We can figure out the pattern for a row of the pyramid at a given “rank”
|
||
<span class="math notranslate nohighlight">\(k\)</span>:</p>
|
||
<p><span class="math notranslate nohighlight">\(2k - 1, 2k - 2, ..., k, k + 1, k + 2, ..., 2k\)</span></p>
|
||
<p>or</p>
|
||
<p><span class="math notranslate nohighlight">\(k + (k - 1), k + (k - 2), ..., k, k + 1, k + 2, ..., k + k\)</span></p>
|
||
<p>This shows that the series consists at each place of <span class="math notranslate nohighlight">\(k\)</span> plus some
|
||
number that begins at <span class="math notranslate nohighlight">\(k - 1\)</span>, decreases to zero, then increases
|
||
to <span class="math notranslate nohighlight">\(k\)</span>. Each row has <span class="math notranslate nohighlight">\(2k\)</span> members.</p>
|
||
<p>Let’s figure out how, given an index into a row, we can calculate the
|
||
value there. The index will be from 0 to <span class="math notranslate nohighlight">\(k - 1\)</span>.</p>
|
||
<p>Let’s look at an example, with <span class="math notranslate nohighlight">\(k = 4\)</span>:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span> <span class="mi">7</span>
|
||
<span class="mi">7</span> <span class="mi">6</span> <span class="mi">5</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span> <span class="mi">7</span> <span class="mi">8</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">k</span> <span class="o">=</span> <span class="mi">4</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Subtract <span class="math notranslate nohighlight">\(k\)</span> from the index and take the absolute value:</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">k</span><span class="p">):</span>
|
||
<span class="nb">print</span> <span class="nb">abs</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="n">k</span><span class="p">),</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">4</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Not quite. Subtract <span class="math notranslate nohighlight">\(k - 1\)</span> from the index and take the absolute
|
||
value:</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">k</span><span class="p">):</span>
|
||
<span class="nb">print</span> <span class="nb">abs</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="p">(</span><span class="n">k</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)),</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Great, now add <span class="math notranslate nohighlight">\(k\)</span>…</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">k</span><span class="p">):</span>
|
||
<span class="nb">print</span> <span class="nb">abs</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="p">(</span><span class="n">k</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span> <span class="o">+</span> <span class="n">k</span><span class="p">,</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">7</span> <span class="mi">6</span> <span class="mi">5</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span> <span class="mi">7</span> <span class="mi">8</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>So to write a function that can give us the value of a row at a given
|
||
index:</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">row_value</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
|
||
<span class="n">i</span> <span class="o">%=</span> <span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">k</span><span class="p">)</span> <span class="c1"># wrap the index at the row boundary.</span>
|
||
<span class="k">return</span> <span class="nb">abs</span><span class="p">(</span><span class="n">i</span> <span class="o">-</span> <span class="p">(</span><span class="n">k</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span> <span class="o">+</span> <span class="n">k</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">k</span> <span class="o">=</span> <span class="mi">5</span>
|
||
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">k</span><span class="p">):</span>
|
||
<span class="nb">print</span> <span class="n">row_value</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">i</span><span class="p">),</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">9</span> <span class="mi">8</span> <span class="mi">7</span> <span class="mi">6</span> <span class="mi">5</span> <span class="mi">6</span> <span class="mi">7</span> <span class="mi">8</span> <span class="mi">9</span> <span class="mi">10</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>(I’m leaving out details of how I figured this all out and just giving
|
||
the relevent bits. It took a little while to zero in of the aspects of
|
||
the pattern that were important for the task.)</p>
|
||
</div>
|
||
<div class="section" id="finding-the-rank-and-offset-of-a-number">
|
||
<h3>Finding the rank and offset of a number.<a class="headerlink" href="#finding-the-rank-and-offset-of-a-number" title="Permalink to this headline">¶</a></h3>
|
||
<p>Now that we can compute the desired output value for a given rank and
|
||
the offset (index) into that rank, we need to determine how to find the
|
||
rank and offset of a number.</p>
|
||
<p>The rank is easy to find by iteratively stripping off the amount already
|
||
covered by previous ranks until you find the one that brackets the
|
||
target number. Because each row is <span class="math notranslate nohighlight">\(2k\)</span> places and there are
|
||
<span class="math notranslate nohighlight">\(4\)</span> per rank each rank contains <span class="math notranslate nohighlight">\(8k\)</span> places. Counting the
|
||
initial square we have:</p>
|
||
<p><span class="math notranslate nohighlight">\(corner_k = 1 + \sum_{n=1}^k 8n\)</span></p>
|
||
<p>I’m not mathematically sophisticated enough to turn this directly into a
|
||
formula (but Sympy is, see below.) I’m going to write a simple Python
|
||
function to iterate and search:</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">rank_and_offset</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
|
||
<span class="k">assert</span> <span class="n">n</span> <span class="o">>=</span> <span class="mi">2</span> <span class="c1"># Guard the domain.</span>
|
||
<span class="n">n</span> <span class="o">-=</span> <span class="mi">2</span> <span class="c1"># Subtract two,</span>
|
||
<span class="c1"># one for the initial square,</span>
|
||
<span class="c1"># and one because we are counting from 1 instead of 0.</span>
|
||
<span class="n">k</span> <span class="o">=</span> <span class="mi">1</span>
|
||
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
|
||
<span class="n">m</span> <span class="o">=</span> <span class="mi">8</span> <span class="o">*</span> <span class="n">k</span> <span class="c1"># The number of places total in this rank, 4(2k).</span>
|
||
<span class="k">if</span> <span class="n">n</span> <span class="o"><</span> <span class="n">m</span><span class="p">:</span>
|
||
<span class="k">return</span> <span class="n">k</span><span class="p">,</span> <span class="n">n</span> <span class="o">%</span> <span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">k</span><span class="p">)</span>
|
||
<span class="n">n</span> <span class="o">-=</span> <span class="n">m</span> <span class="c1"># Remove this rank's worth.</span>
|
||
<span class="n">k</span> <span class="o">+=</span> <span class="mi">1</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">51</span><span class="p">):</span>
|
||
<span class="nb">print</span> <span class="n">n</span><span class="p">,</span> <span class="n">rank_and_offset</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="mi">3</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="mi">4</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="mi">5</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="mi">6</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="mi">7</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="mi">8</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="mi">9</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="mi">10</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="mi">11</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="mi">12</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
||
<span class="mi">13</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
|
||
<span class="mi">14</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="mi">15</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="mi">16</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
||
<span class="mi">17</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
|
||
<span class="mi">18</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="mi">19</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="mi">20</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
||
<span class="mi">21</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
|
||
<span class="mi">22</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="mi">23</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="mi">24</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
||
<span class="mi">25</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
|
||
<span class="mi">26</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="mi">27</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="mi">28</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
||
<span class="mi">29</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
|
||
<span class="mi">30</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span>
|
||
<span class="mi">31</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
|
||
<span class="mi">32</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="mi">33</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="mi">34</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
||
<span class="mi">35</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
|
||
<span class="mi">36</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span>
|
||
<span class="mi">37</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
|
||
<span class="mi">38</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="mi">39</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="mi">40</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
||
<span class="mi">41</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
|
||
<span class="mi">42</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span>
|
||
<span class="mi">43</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
|
||
<span class="mi">44</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="mi">45</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="mi">46</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
||
<span class="mi">47</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
|
||
<span class="mi">48</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span>
|
||
<span class="mi">49</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
|
||
<span class="mi">50</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">51</span><span class="p">):</span>
|
||
<span class="n">k</span><span class="p">,</span> <span class="n">i</span> <span class="o">=</span> <span class="n">rank_and_offset</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
|
||
<span class="nb">print</span> <span class="n">n</span><span class="p">,</span> <span class="n">row_value</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span> <span class="mi">1</span>
|
||
<span class="mi">3</span> <span class="mi">2</span>
|
||
<span class="mi">4</span> <span class="mi">1</span>
|
||
<span class="mi">5</span> <span class="mi">2</span>
|
||
<span class="mi">6</span> <span class="mi">1</span>
|
||
<span class="mi">7</span> <span class="mi">2</span>
|
||
<span class="mi">8</span> <span class="mi">1</span>
|
||
<span class="mi">9</span> <span class="mi">2</span>
|
||
<span class="mi">10</span> <span class="mi">3</span>
|
||
<span class="mi">11</span> <span class="mi">2</span>
|
||
<span class="mi">12</span> <span class="mi">3</span>
|
||
<span class="mi">13</span> <span class="mi">4</span>
|
||
<span class="mi">14</span> <span class="mi">3</span>
|
||
<span class="mi">15</span> <span class="mi">2</span>
|
||
<span class="mi">16</span> <span class="mi">3</span>
|
||
<span class="mi">17</span> <span class="mi">4</span>
|
||
<span class="mi">18</span> <span class="mi">3</span>
|
||
<span class="mi">19</span> <span class="mi">2</span>
|
||
<span class="mi">20</span> <span class="mi">3</span>
|
||
<span class="mi">21</span> <span class="mi">4</span>
|
||
<span class="mi">22</span> <span class="mi">3</span>
|
||
<span class="mi">23</span> <span class="mi">2</span>
|
||
<span class="mi">24</span> <span class="mi">3</span>
|
||
<span class="mi">25</span> <span class="mi">4</span>
|
||
<span class="mi">26</span> <span class="mi">5</span>
|
||
<span class="mi">27</span> <span class="mi">4</span>
|
||
<span class="mi">28</span> <span class="mi">3</span>
|
||
<span class="mi">29</span> <span class="mi">4</span>
|
||
<span class="mi">30</span> <span class="mi">5</span>
|
||
<span class="mi">31</span> <span class="mi">6</span>
|
||
<span class="mi">32</span> <span class="mi">5</span>
|
||
<span class="mi">33</span> <span class="mi">4</span>
|
||
<span class="mi">34</span> <span class="mi">3</span>
|
||
<span class="mi">35</span> <span class="mi">4</span>
|
||
<span class="mi">36</span> <span class="mi">5</span>
|
||
<span class="mi">37</span> <span class="mi">6</span>
|
||
<span class="mi">38</span> <span class="mi">5</span>
|
||
<span class="mi">39</span> <span class="mi">4</span>
|
||
<span class="mi">40</span> <span class="mi">3</span>
|
||
<span class="mi">41</span> <span class="mi">4</span>
|
||
<span class="mi">42</span> <span class="mi">5</span>
|
||
<span class="mi">43</span> <span class="mi">6</span>
|
||
<span class="mi">44</span> <span class="mi">5</span>
|
||
<span class="mi">45</span> <span class="mi">4</span>
|
||
<span class="mi">46</span> <span class="mi">3</span>
|
||
<span class="mi">47</span> <span class="mi">4</span>
|
||
<span class="mi">48</span> <span class="mi">5</span>
|
||
<span class="mi">49</span> <span class="mi">6</span>
|
||
<span class="mi">50</span> <span class="mi">7</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="putting-it-all-together">
|
||
<h3>Putting it all together<a class="headerlink" href="#putting-it-all-together" title="Permalink to this headline">¶</a></h3>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">row_value</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="nb">abs</span><span class="p">(</span><span class="n">i</span> <span class="o">-</span> <span class="p">(</span><span class="n">k</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span> <span class="o">+</span> <span class="n">k</span>
|
||
|
||
|
||
<span class="k">def</span> <span class="nf">rank_and_offset</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
|
||
<span class="n">n</span> <span class="o">-=</span> <span class="mi">2</span> <span class="c1"># Subtract two,</span>
|
||
<span class="c1"># one for the initial square,</span>
|
||
<span class="c1"># and one because we are counting from 1 instead of 0.</span>
|
||
<span class="n">k</span> <span class="o">=</span> <span class="mi">1</span>
|
||
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
|
||
<span class="n">m</span> <span class="o">=</span> <span class="mi">8</span> <span class="o">*</span> <span class="n">k</span> <span class="c1"># The number of places total in this rank, 4(2k).</span>
|
||
<span class="k">if</span> <span class="n">n</span> <span class="o"><</span> <span class="n">m</span><span class="p">:</span>
|
||
<span class="k">return</span> <span class="n">k</span><span class="p">,</span> <span class="n">n</span> <span class="o">%</span> <span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">k</span><span class="p">)</span>
|
||
<span class="n">n</span> <span class="o">-=</span> <span class="n">m</span> <span class="c1"># Remove this rank's worth.</span>
|
||
<span class="n">k</span> <span class="o">+=</span> <span class="mi">1</span>
|
||
|
||
|
||
<span class="k">def</span> <span class="nf">aoc20173</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
|
||
<span class="k">if</span> <span class="n">n</span> <span class="o"><=</span> <span class="mi">1</span><span class="p">:</span>
|
||
<span class="k">return</span> <span class="mi">0</span>
|
||
<span class="n">k</span><span class="p">,</span> <span class="n">i</span> <span class="o">=</span> <span class="n">rank_and_offset</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">row_value</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">aoc20173</span><span class="p">(</span><span class="mi">23</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">aoc20173</span><span class="p">(</span><span class="mi">23000</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">105</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">aoc20173</span><span class="p">(</span><span class="mi">23000000000000</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">4572225</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="sympy-to-the-rescue">
|
||
<h1>Sympy to the Rescue<a class="headerlink" href="#sympy-to-the-rescue" title="Permalink to this headline">¶</a></h1>
|
||
<p>Using e.g. Sympy we can find the rank directly by solving for the roots
|
||
of an equation. For large numbers this will (eventually) be faster than
|
||
iterating as <code class="docutils literal notranslate"><span class="pre">rank_and_offset()</span></code> does.</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">sympy</span> <span class="k">import</span> <span class="n">floor</span><span class="p">,</span> <span class="n">lambdify</span><span class="p">,</span> <span class="n">solve</span><span class="p">,</span> <span class="n">symbols</span>
|
||
<span class="kn">from</span> <span class="nn">sympy</span> <span class="k">import</span> <span class="n">init_printing</span>
|
||
<span class="n">init_printing</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">k</span> <span class="o">=</span> <span class="n">symbols</span><span class="p">(</span><span class="s1">'k'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Since</p>
|
||
<p><span class="math notranslate nohighlight">\(1 + 2 + 3 + ... + N = \frac{N(N + 1)}{2}\)</span></p>
|
||
<p>and</p>
|
||
<p><span class="math notranslate nohighlight">\(\sum_{n=1}^k 8n = 8(\sum_{n=1}^k n) = 8\frac{k(k + 1)}{2}\)</span></p>
|
||
<p>We want:</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">E</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">8</span> <span class="o">*</span> <span class="n">k</span> <span class="o">*</span> <span class="p">(</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1"># For the reason for adding 2 see above.</span>
|
||
|
||
<span class="n">E</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="math notranslate nohighlight">
|
||
\[4 k \left(k + 1\right) + 2\]</div>
|
||
<p>We can write a function to solve for <span class="math notranslate nohighlight">\(k\)</span> given some <span class="math notranslate nohighlight">\(n\)</span>…</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">rank_of</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="n">floor</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="n">solve</span><span class="p">(</span><span class="n">E</span> <span class="o">-</span> <span class="n">n</span><span class="p">,</span> <span class="n">k</span><span class="p">)))</span> <span class="o">+</span> <span class="mi">1</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>First <code class="docutils literal notranslate"><span class="pre">solve()</span></code> for <span class="math notranslate nohighlight">\(E - n = 0\)</span> which has two solutions (because
|
||
the equation is quadratic so it has two roots) and since we only care
|
||
about the larger one we use <code class="docutils literal notranslate"><span class="pre">max()</span></code> to select it. It will generally
|
||
not be a nice integer (unless <span class="math notranslate nohighlight">\(n\)</span> is the number of an end-corner
|
||
of a rank) so we take the <code class="docutils literal notranslate"><span class="pre">floor()</span></code> and add 1 to get the integer rank
|
||
of <span class="math notranslate nohighlight">\(n\)</span>. (Taking the <code class="docutils literal notranslate"><span class="pre">ceiling()</span></code> gives off-by-one errors on the
|
||
rank boundaries. I don’t know why. I’m basically like a monkey doing
|
||
math here.) =-D</p>
|
||
<p>It gives correct answers:</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">25</span><span class="p">,</span> <span class="mi">26</span><span class="p">,</span> <span class="mi">49</span><span class="p">,</span> <span class="mi">50</span><span class="p">):</span>
|
||
<span class="nb">print</span> <span class="n">n</span><span class="p">,</span> <span class="n">rank_of</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">9</span> <span class="mi">1</span>
|
||
<span class="mi">10</span> <span class="mi">2</span>
|
||
<span class="mi">25</span> <span class="mi">2</span>
|
||
<span class="mi">26</span> <span class="mi">3</span>
|
||
<span class="mi">49</span> <span class="mi">3</span>
|
||
<span class="mi">50</span> <span class="mi">4</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>And it runs much faster (at least for large numbers):</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">%</span><span class="n">time</span> <span class="n">rank_of</span><span class="p">(</span><span class="mi">23000000000000</span><span class="p">)</span> <span class="c1"># Compare runtime with rank_and_offset()!</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">68</span> <span class="n">ms</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mi">8</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mi">76</span> <span class="n">ms</span>
|
||
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mf">73.8</span> <span class="n">ms</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="math notranslate nohighlight">
|
||
\[2397916\]</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">%</span><span class="n">time</span> <span class="n">rank_and_offset</span><span class="p">(</span><span class="mi">23000000000000</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">308</span> <span class="n">ms</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mi">0</span> <span class="n">ns</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mi">308</span> <span class="n">ms</span>
|
||
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mi">306</span> <span class="n">ms</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="math notranslate nohighlight">
|
||
\[\left ( 2397916, \quad 223606\right )\]</div>
|
||
<p>After finding the rank you would still have to find the actual value of
|
||
the rank’s first corner and subtract it (plus 2) from the number and
|
||
compute the offset as above and then the final output, but this overhead
|
||
is partially shared by the other method, and overshadowed by the time it
|
||
(the other iterative method) would take for really big inputs.</p>
|
||
<p>The fun thing to do here would be to graph the actual runtime of both
|
||
methods against each other to find the trade-off point.</p>
|
||
<p>Sympy is a <em>symbolic</em> math library, and it supports symbolic
|
||
manipulation of equations. I can put in <span class="math notranslate nohighlight">\(y\)</span> (instead of a value)
|
||
and ask it to solve for <span class="math notranslate nohighlight">\(k\)</span>.</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">y</span> <span class="o">=</span> <span class="n">symbols</span><span class="p">(</span><span class="s1">'y'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">g</span><span class="p">,</span> <span class="n">f</span> <span class="o">=</span> <span class="n">solve</span><span class="p">(</span><span class="n">E</span> <span class="o">-</span> <span class="n">y</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The equation is quadratic so there are two roots, we are interested in
|
||
the greater one…</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">g</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="math notranslate nohighlight">
|
||
\[- \frac{1}{2} \sqrt{y - 1} - \frac{1}{2}\]</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">f</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="math notranslate nohighlight">
|
||
\[\frac{1}{2} \sqrt{y - 1} - \frac{1}{2}\]</div>
|
||
<p>Now we can take the <code class="docutils literal notranslate"><span class="pre">floor()</span></code>, add 1, and <code class="docutils literal notranslate"><span class="pre">lambdify()</span></code> the equation
|
||
to get a Python function that calculates the rank directly.</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">floor</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="math notranslate nohighlight">
|
||
\[\lfloor{\frac{1}{2} \sqrt{y - 1} - \frac{1}{2}}\rfloor + 1\]</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">lambdify</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">floor</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">25</span><span class="p">,</span> <span class="mi">26</span><span class="p">,</span> <span class="mi">49</span><span class="p">,</span> <span class="mi">50</span><span class="p">):</span>
|
||
<span class="nb">print</span> <span class="n">n</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">F</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">9</span> <span class="mi">1</span>
|
||
<span class="mi">10</span> <span class="mi">2</span>
|
||
<span class="mi">25</span> <span class="mi">2</span>
|
||
<span class="mi">26</span> <span class="mi">3</span>
|
||
<span class="mi">49</span> <span class="mi">3</span>
|
||
<span class="mi">50</span> <span class="mi">4</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>It’s pretty fast.</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">%</span><span class="n">time</span> <span class="nb">int</span><span class="p">(</span><span class="n">F</span><span class="p">(</span><span class="mi">23000000000000</span><span class="p">))</span> <span class="c1"># The clear winner.</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">0</span> <span class="n">ns</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mi">0</span> <span class="n">ns</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mi">0</span> <span class="n">ns</span>
|
||
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mf">11.9</span> <span class="n">µs</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="math notranslate nohighlight">
|
||
\[2397916\]</div>
|
||
<p>Knowing the equation we could write our own function manually, but the
|
||
speed is no better.</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">math</span> <span class="k">import</span> <span class="n">floor</span> <span class="k">as</span> <span class="n">mfloor</span><span class="p">,</span> <span class="n">sqrt</span>
|
||
|
||
<span class="k">def</span> <span class="nf">mrank_of</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">mfloor</span><span class="p">(</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">23000000000000</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">-</span> <span class="mf">0.5</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">%</span><span class="n">time</span> <span class="n">mrank_of</span><span class="p">(</span><span class="mi">23000000000000</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">0</span> <span class="n">ns</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mi">0</span> <span class="n">ns</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mi">0</span> <span class="n">ns</span>
|
||
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mf">12.9</span> <span class="n">µs</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="math notranslate nohighlight">
|
||
\[2397916\]</div>
|
||
<p>Now that we have a fast way to get the rank, we still need to use it to
|
||
compute the offset into a pyramid row.</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">offset_of</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">k</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">4</span> <span class="o">*</span> <span class="n">k</span> <span class="o">*</span> <span class="p">(</span><span class="n">k</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span> <span class="o">%</span> <span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">k</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>(Note the sneaky way the sign changes from <span class="math notranslate nohighlight">\(k(k + 1)\)</span> to
|
||
<span class="math notranslate nohighlight">\(k(k - 1)\)</span>. This is because we want to subract the
|
||
<span class="math notranslate nohighlight">\((k - 1)\)</span>th rank’s total places (its own and those of lesser
|
||
rank) from our <span class="math notranslate nohighlight">\(n\)</span> of rank <span class="math notranslate nohighlight">\(k\)</span>. Substituting <span class="math notranslate nohighlight">\(k - 1\)</span>
|
||
for <span class="math notranslate nohighlight">\(k\)</span> in <span class="math notranslate nohighlight">\(k(k + 1)\)</span> gives <span class="math notranslate nohighlight">\((k - 1)(k - 1 + 1)\)</span>,
|
||
which of course simplifies to <span class="math notranslate nohighlight">\(k(k - 1)\)</span>.)</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">offset_of</span><span class="p">(</span><span class="mi">23000000000000</span><span class="p">,</span> <span class="mi">2397916</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="math notranslate nohighlight">
|
||
\[223606\]</div>
|
||
<p>So, we can compute the rank, then the offset, then the row value.</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">rank_of</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">mfloor</span><span class="p">(</span><span class="n">sqrt</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">-</span> <span class="mf">0.5</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
|
||
|
||
|
||
<span class="k">def</span> <span class="nf">offset_of</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">k</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">4</span> <span class="o">*</span> <span class="n">k</span> <span class="o">*</span> <span class="p">(</span><span class="n">k</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span> <span class="o">%</span> <span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">k</span><span class="p">)</span>
|
||
|
||
|
||
<span class="k">def</span> <span class="nf">row_value</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="nb">abs</span><span class="p">(</span><span class="n">i</span> <span class="o">-</span> <span class="p">(</span><span class="n">k</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span> <span class="o">+</span> <span class="n">k</span>
|
||
|
||
|
||
<span class="k">def</span> <span class="nf">aoc20173</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
|
||
<span class="n">k</span> <span class="o">=</span> <span class="n">rank_of</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
|
||
<span class="n">i</span> <span class="o">=</span> <span class="n">offset_of</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">row_value</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">aoc20173</span><span class="p">(</span><span class="mi">23</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="math notranslate nohighlight">
|
||
\[2\]</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">aoc20173</span><span class="p">(</span><span class="mi">23000</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="math notranslate nohighlight">
|
||
\[105\]</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">aoc20173</span><span class="p">(</span><span class="mi">23000000000000</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="math notranslate nohighlight">
|
||
\[4572225\]</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">%</span><span class="n">time</span> <span class="n">aoc20173</span><span class="p">(</span><span class="mi">23000000000000000000000000</span><span class="p">)</span> <span class="c1"># Fast for large values.</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">0</span> <span class="n">ns</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mi">0</span> <span class="n">ns</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mi">0</span> <span class="n">ns</span>
|
||
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mi">20</span> <span class="n">µs</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="math notranslate nohighlight">
|
||
\[2690062495969\]</div>
|
||
</div>
|
||
<div class="section" id="a-joy-version">
|
||
<h1>A Joy Version<a class="headerlink" href="#a-joy-version" title="Permalink to this headline">¶</a></h1>
|
||
<p>At this point I feel confident that I can implement a concise version of
|
||
this code in Joy. ;-)</p>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">n</span> <span class="n">rank_of</span>
|
||
<span class="o">---------------</span>
|
||
<span class="n">k</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The translation is straightforward.</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">int</span><span class="p">(</span><span class="n">floor</span><span class="p">(</span><span class="n">sqrt</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">-</span> <span class="mf">0.5</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
|
||
|
||
<span class="n">rank_of</span> <span class="o">==</span> <span class="o">--</span> <span class="n">sqrt</span> <span class="mi">2</span> <span class="o">/</span> <span class="mf">0.5</span> <span class="o">-</span> <span class="n">floor</span> <span class="o">++</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'rank_of == -- sqrt 2 / 0.5 - floor ++'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">n</span> <span class="n">k</span> <span class="n">offset_of</span>
|
||
<span class="o">-------------------</span>
|
||
<span class="n">i</span>
|
||
|
||
<span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">4</span> <span class="o">*</span> <span class="n">k</span> <span class="o">*</span> <span class="p">(</span><span class="n">k</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span> <span class="o">%</span> <span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">k</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>A little tricky…</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">n</span> <span class="n">k</span> <span class="n">dup</span> <span class="mi">2</span> <span class="o">*</span>
|
||
<span class="n">n</span> <span class="n">k</span> <span class="n">k</span> <span class="mi">2</span> <span class="o">*</span>
|
||
<span class="n">n</span> <span class="n">k</span> <span class="n">k</span><span class="o">*</span><span class="mi">2</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">dip</span> <span class="o">%</span>
|
||
<span class="n">n</span> <span class="n">k</span> <span class="n">Q</span> <span class="n">k</span><span class="o">*</span><span class="mi">2</span> <span class="o">%</span>
|
||
|
||
<span class="n">n</span> <span class="n">k</span> <span class="n">dup</span> <span class="o">--</span>
|
||
<span class="n">n</span> <span class="n">k</span> <span class="n">k</span> <span class="o">--</span>
|
||
<span class="n">n</span> <span class="n">k</span> <span class="n">k</span><span class="o">-</span><span class="mi">1</span> <span class="mi">4</span> <span class="o">*</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="o">-</span>
|
||
<span class="n">n</span> <span class="n">k</span><span class="o">*</span><span class="n">k</span><span class="o">-</span><span class="mi">1</span><span class="o">*</span><span class="mi">4</span> <span class="mi">2</span> <span class="o">+</span> <span class="o">-</span>
|
||
<span class="n">n</span> <span class="n">k</span><span class="o">*</span><span class="n">k</span><span class="o">-</span><span class="mi">1</span><span class="o">*</span><span class="mi">4</span><span class="o">+</span><span class="mi">2</span> <span class="o">-</span>
|
||
<span class="n">n</span><span class="o">-</span><span class="n">k</span><span class="o">*</span><span class="n">k</span><span class="o">-</span><span class="mi">1</span><span class="o">*</span><span class="mi">4</span><span class="o">+</span><span class="mi">2</span>
|
||
|
||
<span class="n">n</span><span class="o">-</span><span class="n">k</span><span class="o">*</span><span class="n">k</span><span class="o">-</span><span class="mi">1</span><span class="o">*</span><span class="mi">4</span><span class="o">+</span><span class="mi">2</span> <span class="n">k</span><span class="o">*</span><span class="mi">2</span> <span class="o">%</span>
|
||
<span class="n">n</span><span class="o">-</span><span class="n">k</span><span class="o">*</span><span class="n">k</span><span class="o">-</span><span class="mi">1</span><span class="o">*</span><span class="mi">4</span><span class="o">+</span><span class="mi">2</span><span class="o">%</span><span class="n">k</span><span class="o">*</span><span class="mi">2</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Ergo:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">offset_of</span> <span class="o">==</span> <span class="n">dup</span> <span class="mi">2</span> <span class="o">*</span> <span class="p">[</span><span class="n">dup</span> <span class="o">--</span> <span class="mi">4</span> <span class="o">*</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="p">]</span> <span class="n">dip</span> <span class="o">%</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'offset_of == dup 2 * [dup -- 4 * * 2 + -] dip %'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">k</span> <span class="n">i</span> <span class="n">row_value</span>
|
||
<span class="o">-------------------</span>
|
||
<span class="n">n</span>
|
||
|
||
<span class="nb">abs</span><span class="p">(</span><span class="n">i</span> <span class="o">-</span> <span class="p">(</span><span class="n">k</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span> <span class="o">+</span> <span class="n">k</span>
|
||
|
||
<span class="n">k</span> <span class="n">i</span> <span class="n">over</span> <span class="o">--</span> <span class="o">-</span> <span class="nb">abs</span> <span class="o">+</span>
|
||
<span class="n">k</span> <span class="n">i</span> <span class="n">k</span> <span class="o">--</span> <span class="o">-</span> <span class="nb">abs</span> <span class="o">+</span>
|
||
<span class="n">k</span> <span class="n">i</span> <span class="n">k</span><span class="o">-</span><span class="mi">1</span> <span class="o">-</span> <span class="nb">abs</span> <span class="o">+</span>
|
||
<span class="n">k</span> <span class="n">i</span><span class="o">-</span><span class="n">k</span><span class="o">-</span><span class="mi">1</span> <span class="nb">abs</span> <span class="o">+</span>
|
||
<span class="n">k</span> <span class="o">|</span><span class="n">i</span><span class="o">-</span><span class="n">k</span><span class="o">-</span><span class="mi">1</span><span class="o">|</span> <span class="o">+</span>
|
||
<span class="n">k</span><span class="o">+|</span><span class="n">i</span><span class="o">-</span><span class="n">k</span><span class="o">-</span><span class="mi">1</span><span class="o">|</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'row_value == over -- - abs +'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">n</span> <span class="n">aoc2017</span><span class="o">.</span><span class="mi">3</span>
|
||
<span class="o">-----------------</span>
|
||
<span class="n">m</span>
|
||
|
||
<span class="n">n</span> <span class="n">dup</span> <span class="n">rank_of</span>
|
||
<span class="n">n</span> <span class="n">k</span> <span class="p">[</span><span class="n">offset_of</span><span class="p">]</span> <span class="n">dupdip</span>
|
||
<span class="n">n</span> <span class="n">k</span> <span class="n">offset_of</span> <span class="n">k</span>
|
||
<span class="n">i</span> <span class="n">k</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="n">k</span> <span class="n">i</span> <span class="n">row_value</span>
|
||
<span class="n">m</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'aoc2017.3 == dup rank_of [offset_of] dupdip swap row_value'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 aoc2017.3'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23000 aoc2017.3'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">105</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'23000000000000 aoc2017.3'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">23000000000000</span> <span class="n">aoc2017</span><span class="o">.</span><span class="mi">3</span>
|
||
<span class="mi">23000000000000</span> <span class="o">.</span> <span class="n">aoc2017</span><span class="o">.</span><span class="mi">3</span>
|
||
<span class="mi">23000000000000</span> <span class="o">.</span> <span class="n">dup</span> <span class="n">rank_of</span> <span class="p">[</span><span class="n">offset_of</span><span class="p">]</span> <span class="n">dupdip</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">23000000000000</span> <span class="o">.</span> <span class="n">rank_of</span> <span class="p">[</span><span class="n">offset_of</span><span class="p">]</span> <span class="n">dupdip</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">23000000000000</span> <span class="o">.</span> <span class="o">--</span> <span class="n">sqrt</span> <span class="mi">2</span> <span class="o">/</span> <span class="mf">0.5</span> <span class="o">-</span> <span class="n">floor</span> <span class="o">++</span> <span class="p">[</span><span class="n">offset_of</span><span class="p">]</span> <span class="n">dupdip</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">22999999999999</span> <span class="o">.</span> <span class="n">sqrt</span> <span class="mi">2</span> <span class="o">/</span> <span class="mf">0.5</span> <span class="o">-</span> <span class="n">floor</span> <span class="o">++</span> <span class="p">[</span><span class="n">offset_of</span><span class="p">]</span> <span class="n">dupdip</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mf">4795831.523312615</span> <span class="o">.</span> <span class="mi">2</span> <span class="o">/</span> <span class="mf">0.5</span> <span class="o">-</span> <span class="n">floor</span> <span class="o">++</span> <span class="p">[</span><span class="n">offset_of</span><span class="p">]</span> <span class="n">dupdip</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mf">4795831.523312615</span> <span class="mi">2</span> <span class="o">.</span> <span class="o">/</span> <span class="mf">0.5</span> <span class="o">-</span> <span class="n">floor</span> <span class="o">++</span> <span class="p">[</span><span class="n">offset_of</span><span class="p">]</span> <span class="n">dupdip</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mf">2397915.7616563076</span> <span class="o">.</span> <span class="mf">0.5</span> <span class="o">-</span> <span class="n">floor</span> <span class="o">++</span> <span class="p">[</span><span class="n">offset_of</span><span class="p">]</span> <span class="n">dupdip</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mf">2397915.7616563076</span> <span class="mf">0.5</span> <span class="o">.</span> <span class="o">-</span> <span class="n">floor</span> <span class="o">++</span> <span class="p">[</span><span class="n">offset_of</span><span class="p">]</span> <span class="n">dupdip</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mf">2397915.2616563076</span> <span class="o">.</span> <span class="n">floor</span> <span class="o">++</span> <span class="p">[</span><span class="n">offset_of</span><span class="p">]</span> <span class="n">dupdip</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">2397915</span> <span class="o">.</span> <span class="o">++</span> <span class="p">[</span><span class="n">offset_of</span><span class="p">]</span> <span class="n">dupdip</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">2397916</span> <span class="o">.</span> <span class="p">[</span><span class="n">offset_of</span><span class="p">]</span> <span class="n">dupdip</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">2397916</span> <span class="p">[</span><span class="n">offset_of</span><span class="p">]</span> <span class="o">.</span> <span class="n">dupdip</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">2397916</span> <span class="o">.</span> <span class="n">offset_of</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">2397916</span> <span class="o">.</span> <span class="n">dup</span> <span class="mi">2</span> <span class="o">*</span> <span class="p">[</span><span class="n">dup</span> <span class="o">--</span> <span class="mi">4</span> <span class="o">*</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="p">]</span> <span class="n">dip</span> <span class="o">%</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">2397916</span> <span class="mi">2397916</span> <span class="o">.</span> <span class="mi">2</span> <span class="o">*</span> <span class="p">[</span><span class="n">dup</span> <span class="o">--</span> <span class="mi">4</span> <span class="o">*</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="p">]</span> <span class="n">dip</span> <span class="o">%</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">2397916</span> <span class="mi">2397916</span> <span class="mi">2</span> <span class="o">.</span> <span class="o">*</span> <span class="p">[</span><span class="n">dup</span> <span class="o">--</span> <span class="mi">4</span> <span class="o">*</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="p">]</span> <span class="n">dip</span> <span class="o">%</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">2397916</span> <span class="mi">4795832</span> <span class="o">.</span> <span class="p">[</span><span class="n">dup</span> <span class="o">--</span> <span class="mi">4</span> <span class="o">*</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="p">]</span> <span class="n">dip</span> <span class="o">%</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">2397916</span> <span class="mi">4795832</span> <span class="p">[</span><span class="n">dup</span> <span class="o">--</span> <span class="mi">4</span> <span class="o">*</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="p">]</span> <span class="o">.</span> <span class="n">dip</span> <span class="o">%</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">2397916</span> <span class="o">.</span> <span class="n">dup</span> <span class="o">--</span> <span class="mi">4</span> <span class="o">*</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="o">-</span> <span class="mi">4795832</span> <span class="o">%</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">2397916</span> <span class="mi">2397916</span> <span class="o">.</span> <span class="o">--</span> <span class="mi">4</span> <span class="o">*</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="o">-</span> <span class="mi">4795832</span> <span class="o">%</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">2397916</span> <span class="mi">2397915</span> <span class="o">.</span> <span class="mi">4</span> <span class="o">*</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="o">-</span> <span class="mi">4795832</span> <span class="o">%</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">2397916</span> <span class="mi">2397915</span> <span class="mi">4</span> <span class="o">.</span> <span class="o">*</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="o">-</span> <span class="mi">4795832</span> <span class="o">%</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">2397916</span> <span class="mi">9591660</span> <span class="o">.</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="o">-</span> <span class="mi">4795832</span> <span class="o">%</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">22999994980560</span> <span class="o">.</span> <span class="mi">2</span> <span class="o">+</span> <span class="o">-</span> <span class="mi">4795832</span> <span class="o">%</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">22999994980560</span> <span class="mi">2</span> <span class="o">.</span> <span class="o">+</span> <span class="o">-</span> <span class="mi">4795832</span> <span class="o">%</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">23000000000000</span> <span class="mi">22999994980562</span> <span class="o">.</span> <span class="o">-</span> <span class="mi">4795832</span> <span class="o">%</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">5019438</span> <span class="o">.</span> <span class="mi">4795832</span> <span class="o">%</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">5019438</span> <span class="mi">4795832</span> <span class="o">.</span> <span class="o">%</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">223606</span> <span class="o">.</span> <span class="mi">2397916</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">223606</span> <span class="mi">2397916</span> <span class="o">.</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
<span class="mi">2397916</span> <span class="mi">223606</span> <span class="o">.</span> <span class="n">row_value</span>
|
||
<span class="mi">2397916</span> <span class="mi">223606</span> <span class="o">.</span> <span class="n">over</span> <span class="o">--</span> <span class="o">-</span> <span class="nb">abs</span> <span class="o">+</span>
|
||
<span class="mi">2397916</span> <span class="mi">223606</span> <span class="mi">2397916</span> <span class="o">.</span> <span class="o">--</span> <span class="o">-</span> <span class="nb">abs</span> <span class="o">+</span>
|
||
<span class="mi">2397916</span> <span class="mi">223606</span> <span class="mi">2397915</span> <span class="o">.</span> <span class="o">-</span> <span class="nb">abs</span> <span class="o">+</span>
|
||
<span class="mi">2397916</span> <span class="o">-</span><span class="mi">2174309</span> <span class="o">.</span> <span class="nb">abs</span> <span class="o">+</span>
|
||
<span class="mi">2397916</span> <span class="mi">2174309</span> <span class="o">.</span> <span class="o">+</span>
|
||
<span class="mi">4572225</span> <span class="o">.</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">rank_of</span> <span class="o">==</span> <span class="o">--</span> <span class="n">sqrt</span> <span class="mi">2</span> <span class="o">/</span> <span class="mf">0.5</span> <span class="o">-</span> <span class="n">floor</span> <span class="o">++</span>
|
||
<span class="n">offset_of</span> <span class="o">==</span> <span class="n">dup</span> <span class="mi">2</span> <span class="o">*</span> <span class="p">[</span><span class="n">dup</span> <span class="o">--</span> <span class="mi">4</span> <span class="o">*</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="p">]</span> <span class="n">dip</span> <span class="o">%</span>
|
||
<span class="n">row_value</span> <span class="o">==</span> <span class="n">over</span> <span class="o">--</span> <span class="o">-</span> <span class="nb">abs</span> <span class="o">+</span>
|
||
|
||
<span class="n">aoc2017</span><span class="o">.</span><span class="mi">3</span> <span class="o">==</span> <span class="n">dup</span> <span class="n">rank_of</span> <span class="p">[</span><span class="n">offset_of</span><span class="p">]</span> <span class="n">dupdip</span> <span class="n">swap</span> <span class="n">row_value</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||
<div class="sphinxsidebarwrapper">
|
||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">Advent of Code 2017</a><ul>
|
||
<li><a class="reference internal" href="#december-3rd">December 3rd</a><ul>
|
||
<li><a class="reference internal" href="#analysis">Analysis</a></li>
|
||
<li><a class="reference internal" href="#finding-the-rank-and-offset-of-a-number">Finding the rank and offset of a number.</a></li>
|
||
<li><a class="reference internal" href="#putting-it-all-together">Putting it all together</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#sympy-to-the-rescue">Sympy to the Rescue</a></li>
|
||
<li><a class="reference internal" href="#a-joy-version">A Joy Version</a></li>
|
||
</ul>
|
||
<div class="relations">
|
||
<h3>Related Topics</h3>
|
||
<ul>
|
||
<li><a href="../index.html">Documentation overview</a><ul>
|
||
</ul></li>
|
||
</ul>
|
||
</div>
|
||
<div role="note" aria-label="source link">
|
||
<h3>This Page</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../_sources/notebooks/Advent of Code 2017 December 3rd.rst.txt"
|
||
rel="nofollow">Show Source</a></li>
|
||
</ul>
|
||
</div>
|
||
<div id="searchbox" style="display: none" role="search">
|
||
<h3>Quick search</h3>
|
||
<div class="searchformwrapper">
|
||
<form class="search" action="../search.html" method="get">
|
||
<input type="text" name="q" />
|
||
<input type="submit" value="Go" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
</div>
|
||
<script type="text/javascript">$('#searchbox').show(0);</script>
|
||
</div>
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
<div class="footer" role="contentinfo">
|
||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
|
||
<img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" />
|
||
</a>
|
||
<br />
|
||
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
|
||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
|
||
</div>
|
||
|
||
</body>
|
||
</html> |