Add final annotations

This commit is contained in:
Dimitri Lozeve 2020-08-03 11:38:10 +02:00
parent d77bd328a9
commit 32966c661d
4 changed files with 347 additions and 371 deletions

View file

@ -103,50 +103,33 @@
<div class="sourceCode" id="cb9"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb9-1" title="1">sset←{((1E6|2∘×)⍣⍵)1}</a></code></pre></div> <div class="sourceCode" id="cb9"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb9-1" title="1">sset←{((1E6|2∘×)⍣⍵)1}</a></code></pre></div>
<p>Since we cannot just compute <span class="math inline">\(2^n\)</span> directly and take the remainder, we use modular arithmetic to stay mod 1,000,000 during the whole computation. The dfn <code>(1E6|2∘×)</code> doubles its argument mod 1,000,000. So we just apply this function <span class="math inline">\(n\)</span> times using the <a href="https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Operators/Power%20Operator.htm">Power</a> operator (<code></code>), with an initial value of 1.</p> <p>Since we cannot just compute <span class="math inline">\(2^n\)</span> directly and take the remainder, we use modular arithmetic to stay mod 1,000,000 during the whole computation. The dfn <code>(1E6|2∘×)</code> doubles its argument mod 1,000,000. So we just apply this function <span class="math inline">\(n\)</span> times using the <a href="https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Operators/Power%20Operator.htm">Power</a> operator (<code></code>), with an initial value of 1.</p>
<h2 id="problem-5-future-and-present-value">Problem 5 Future and Present Value</h2> <h2 id="problem-5-future-and-present-value">Problem 5 Future and Present Value</h2>
<div class="sourceCode" id="cb10"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb10-1" title="1">⍝ First solution: ((1+⊢)⊥⊣) computes the total return</a> <p>First solution: <code>((1+⊢)⊥⊣)</code> computes the total return for a vector of amounts <code></code> and a vector of rates <code></code>. It is applied to every prefix subarray of amounts and rates to get all intermediate values. However, this has quadratic complexity.</p>
<a class="sourceLine" id="cb10-2" title="2">⍝ for a vector of amounts and a vector of rates</a> <div class="sourceCode" id="cb10"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb10-1" title="1">rr←(,\⊣)((1+⊢)⊥⊣)¨(,\⊢)</a></code></pre></div>
<a class="sourceLine" id="cb10-3" title="3">⍝ ⍵. It is applied to every prefix subarray of amounts</a> <p>Second solution: We want to be able to use the recurrence relation (<code>recur</code>) and scan through the vectors of amounts and rates, accumulating the total value at every time step. However, APL evaluation is right-associative, so a simple <a href="https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Operators/Scan.htm">Scan</a> (<code>recur\amounts,¨values</code>) would not give the correct result, since <code>recur</code> is not associative and we need to evaluate it left-to-right. (In any case, in this case, Scan would have quadratic complexity, so would not bring any benefit over the previous solution.) What we need is something akin to Haskells <code>scanl</code> function, which would evaluate left to right in <span class="math inline">\(O(n)\)</span> time<span><label for="sn-1" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-1" class="margin-toggle" /><span class="sidenote">There is an interesting <a href="https://stackoverflow.com/a/25100675/8864368">StackOverflow answer</a> explaining the behaviour of Scan, and compares it to Haskells <code>scanl</code> function.<br />
<a class="sourceLine" id="cb10-4" title="4">⍝ and rates to get all intermediate values. However,</a> <br />
<a class="sourceLine" id="cb10-5" title="5">⍝ this has quadratic complexity.</a> </span></span>. This is what we do here, accumulating values from left to right. (This is inspired from <a href="https://dfns.dyalog.com/c_ascan.htm"><code>dfns.ascan</code></a>, although heavily simplified.)</p>
<a class="sourceLine" id="cb10-6" title="6">⍝ rr←(,\⊣)((1+⊢)⊥⊣)¨(,\⊢)</a> <div class="sourceCode" id="cb11"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb11-1" title="1">rr←{recur←{⍵[1]+×1+⍵[2]} ⋄ 1↓⌽⊃{(⊂(⊃⍵)recur),⍵}/⌽⍺,¨⍵}</a></code></pre></div>
<a class="sourceLine" id="cb10-7" title="7"></a> <p>For the second task, there is an explicit formula for cashflow calculations, so we can just apply it.</p>
<a class="sourceLine" id="cb10-8" title="8">⍝ Second solution: We want to be able to use the</a> <div class="sourceCode" id="cb12"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb12-1" title="1">pv←{+/⍺÷×\1+⍵}</a></code></pre></div>
<a class="sourceLine" id="cb10-9" title="9">⍝ recurrence relation (recur) and scan through the</a>
<a class="sourceLine" id="cb10-10" title="10">⍝ vectors of amounts and rates, accumulating the total</a>
<a class="sourceLine" id="cb10-11" title="11">⍝ value at every time step. However, APL evaluation is</a>
<a class="sourceLine" id="cb10-12" title="12">⍝ right-associative, so a simple Scan</a>
<a class="sourceLine" id="cb10-13" title="13">⍝ (recur\amounts,¨values) would not give the correct</a>
<a class="sourceLine" id="cb10-14" title="14">⍝ result, since recur is not associative and we need</a>
<a class="sourceLine" id="cb10-15" title="15">⍝ to evaluate it left-to-right. (In any case, in this</a>
<a class="sourceLine" id="cb10-16" title="16">⍝ case, Scan would have quadratic complexity, so would</a>
<a class="sourceLine" id="cb10-17" title="17">⍝ not bring any benefit over the previous solution.)</a>
<a class="sourceLine" id="cb10-18" title="18">⍝ What we need is something akin to Haskell's scanl</a>
<a class="sourceLine" id="cb10-19" title="19">⍝ function, which would evaluate left to right in O(n)</a>
<a class="sourceLine" id="cb10-20" title="20">⍝ time. This is what we do here, accumulating values</a>
<a class="sourceLine" id="cb10-21" title="21">⍝ from left to right. (This is inspired from</a>
<a class="sourceLine" id="cb10-22" title="22">⍝ dfns.ascan, although heavily simplified.)</a>
<a class="sourceLine" id="cb10-23" title="23">rr←{recur←{⍵[1]+×1+⍵[2]} ⋄ 1↓⌽⊃{(⊂(⊃⍵)recur),⍵}/⌽⍺,¨⍵}</a></code></pre></div>
<div class="sourceCode" id="cb11"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb11-1" title="1">⍝ Simply apply the formula for cashflow calculations.</a>
<a class="sourceLine" id="cb11-2" title="2">pv←{+/⍺÷×\1+⍵}</a></code></pre></div>
<h2 id="problem-6-merge">Problem 6 Merge</h2> <h2 id="problem-6-merge">Problem 6 Merge</h2>
<div class="sourceCode" id="cb12"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb12-1" title="1">∇ text←templateFile Merge jsonFile;template;ns</a> <div class="sourceCode" id="cb13"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb13-1" title="1">∇ text←templateFile Merge jsonFile;template;ns</a>
<a class="sourceLine" id="cb12-2" title="2"> template←⊃⎕NGET templateFile 1</a> <a class="sourceLine" id="cb13-2" title="2"> template←⊃⎕NGET templateFile 1</a>
<a class="sourceLine" id="cb12-3" title="3"> ns←⎕JSON⊃⎕NGET jsonFile</a> <a class="sourceLine" id="cb13-3" title="3"> ns←⎕JSON⊃⎕NGET jsonFile</a>
<a class="sourceLine" id="cb12-4" title="4"> ⍝ We use a simple regex search and replace on the</a> <a class="sourceLine" id="cb13-4" title="4"> ⍝ We use a simple regex search and replace on the</a>
<a class="sourceLine" id="cb12-5" title="5"> ⍝ template.</a> <a class="sourceLine" id="cb13-5" title="5"> ⍝ template.</a>
<a class="sourceLine" id="cb12-6" title="6"> text←↑('@[a-zA-Z]*@'⎕R{ns getval ¯1↓1↓⍵.Match})template</a> <a class="sourceLine" id="cb13-6" title="6"> text←↑('@[a-zA-Z]*@'⎕R{ns getval ¯1↓1↓⍵.Match})template</a>
<a class="sourceLine" id="cb12-7" title="7"></a></code></pre></div> <a class="sourceLine" id="cb13-7" title="7"></a></code></pre></div>
<p>We first read the template and the JSON values from their files. The <a href="https://help.dyalog.com/18.0/index.htm#Language/System%20Functions/nget.htm"><code>⎕NGET</code></a> function read simple text files, and <a href="https://help.dyalog.com/18.0/index.htm#Language/System%20Functions/json.htm"><code>⎕JSON</code></a> extracts the key-value pairs as a namespace.</p> <p>We first read the template and the JSON values from their files. The <a href="https://help.dyalog.com/18.0/index.htm#Language/System%20Functions/nget.htm"><code>⎕NGET</code></a> function read simple text files, and <a href="https://help.dyalog.com/18.0/index.htm#Language/System%20Functions/json.htm"><code>⎕JSON</code></a> extracts the key-value pairs as a namespace.</p>
<p>Assuming all variable names contain only letters, we match the regex <code>@[a-zA-Z]*@</code> to match variable names enclosed between <code>@</code> symbols. The function <code>getval</code> then returns the appropriate value, and we can replace the variable name in the template.</p> <p>Assuming all variable names contain only letters, we match the regex <code>@[a-zA-Z]*@</code> to match variable names enclosed between <code>@</code> symbols. The function <code>getval</code> then returns the appropriate value, and we can replace the variable name in the template.</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb13-1" title="1">∇ val←ns getval var</a> <div class="sourceCode" id="cb14"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb14-1" title="1">∇ val←ns getval var</a>
<a class="sourceLine" id="cb13-2" title="2"> :If ''≡var ⍝ literal '@'</a> <a class="sourceLine" id="cb14-2" title="2"> :If ''≡var ⍝ literal '@'</a>
<a class="sourceLine" id="cb13-3" title="3"> val←'@'</a> <a class="sourceLine" id="cb14-3" title="3"> val←'@'</a>
<a class="sourceLine" id="cb13-4" title="4"> :ElseIf (⊂var)∊ns.⎕NL ¯2</a> <a class="sourceLine" id="cb14-4" title="4"> :ElseIf (⊂var)∊ns.⎕NL ¯2</a>
<a class="sourceLine" id="cb13-5" title="5"> val←⍕ns⍎var</a> <a class="sourceLine" id="cb14-5" title="5"> val←⍕ns⍎var</a>
<a class="sourceLine" id="cb13-6" title="6"> :Else</a> <a class="sourceLine" id="cb14-6" title="6"> :Else</a>
<a class="sourceLine" id="cb13-7" title="7"> val←'???'</a> <a class="sourceLine" id="cb14-7" title="7"> val←'???'</a>
<a class="sourceLine" id="cb13-8" title="8"> :EndIf</a> <a class="sourceLine" id="cb14-8" title="8"> :EndIf</a>
<a class="sourceLine" id="cb13-9" title="9"></a></code></pre></div> <a class="sourceLine" id="cb14-9" title="9"></a></code></pre></div>
<p>This function takes the namespace matching the variable names to their respective values, and the name of the variable.</p> <p>This function takes the namespace matching the variable names to their respective values, and the name of the variable.</p>
<ul> <ul>
<li>If the variable name is empty, we matched the string <code>@@</code>, which corresponds to a literal <code>@</code>.</li> <li>If the variable name is empty, we matched the string <code>@@</code>, which corresponds to a literal <code>@</code>.</li>
@ -154,42 +137,42 @@
<li>Otherwise, we have an unknown variable, so we replace it with <code>???</code>.</li> <li>Otherwise, we have an unknown variable, so we replace it with <code>???</code>.</li>
</ul> </ul>
<h2 id="problem-7-upc">Problem 7 UPC</h2> <h2 id="problem-7-upc">Problem 7 UPC</h2>
<div class="sourceCode" id="cb14"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb14-1" title="1">CheckDigit←{10|-⍵+.×113 1}</a></code></pre></div> <div class="sourceCode" id="cb15"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb15-1" title="1">CheckDigit←{10|-⍵+.×113 1}</a></code></pre></div>
<p>The check digit satisfies the equation <span class="math display">\[ 3 x_{1}+x_{2}+3 x_{3}+x_{4}+3 x_{5}+x_{6}+3 x_{7}+x_{8}+3 x_{9}+x_{10}+3 x_{11}+x_{12} \equiv 0 \bmod 10, \]</span> therefore, <span class="math display">\[ x_{12} \equiv -(3 x_{1}+x_{2}+3 x_{3}+x_{4}+3 x_{5}+x_{6}+3 x_{7}+x_{8}+3 x_{9}+x_{10}+3 x_{11}) \bmod 10. \]</span></p> <p>The check digit satisfies the equation <span class="math display">\[ 3 x_{1}+x_{2}+3 x_{3}+x_{4}+3 x_{5}+x_{6}+3 x_{7}+x_{8}+3 x_{9}+x_{10}+3 x_{11}+x_{12} \equiv 0 \bmod 10, \]</span> therefore, <span class="math display">\[ x_{12} \equiv -(3 x_{1}+x_{2}+3 x_{3}+x_{4}+3 x_{5}+x_{6}+3 x_{7}+x_{8}+3 x_{9}+x_{10}+3 x_{11}) \bmod 10. \]</span></p>
<p>Translated to APL, we just take the dot product between the first 11 digits of the barcode with <code>113 1</code>, negate it, and take the remainder by 10.</p> <p>Translated to APL, we just take the dot product between the first 11 digits of the barcode with <code>113 1</code>, negate it, and take the remainder by 10.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb15-1" title="1">⍝ Left and right representations of digits. Decoding</a> <div class="sourceCode" id="cb16"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb16-1" title="1">⍝ Left and right representations of digits. Decoding</a>
<a class="sourceLine" id="cb15-2" title="2">⍝ the binary representation from decimal is more</a> <a class="sourceLine" id="cb16-2" title="2">⍝ the binary representation from decimal is more</a>
<a class="sourceLine" id="cb15-3" title="3">⍝ compact than writing everything explicitly.</a> <a class="sourceLine" id="cb16-3" title="3">⍝ compact than writing everything explicitly.</a>
<a class="sourceLine" id="cb15-4" title="4">lrepr←⍉(72)13 25 19 61 35 49 47 59 55 11</a> <a class="sourceLine" id="cb16-4" title="4">lrepr←⍉(72)13 25 19 61 35 49 47 59 55 11</a>
<a class="sourceLine" id="cb15-5" title="5">rrepr←~¨lrepr</a></code></pre></div> <a class="sourceLine" id="cb16-5" title="5">rrepr←~¨lrepr</a></code></pre></div>
<p>For the second task, the first thing we need to do is save the representation of digits. To save space, I did not encode the binary representation explicitly, instead using a decimal representation that I then decode in base 2. The right representation is just the bitwise negation.</p> <p>For the second task, the first thing we need to do is save the representation of digits. To save space, I did not encode the binary representation explicitly, instead using a decimal representation that I then decode in base 2. The right representation is just the bitwise negation.</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb16-1" title="1">∇ bits←WriteUPC digits;left;right</a> <div class="sourceCode" id="cb17"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb17-1" title="1">∇ bits←WriteUPC digits;left;right</a>
<a class="sourceLine" id="cb16-2" title="2"> :If (11=≢digits)∧∧/digits∊0,9</a> <a class="sourceLine" id="cb17-2" title="2"> :If (11=≢digits)∧∧/digits∊0,9</a>
<a class="sourceLine" id="cb16-3" title="3"> left←,lrepr[1+6↑digits;]</a> <a class="sourceLine" id="cb17-3" title="3"> left←,lrepr[1+6↑digits;]</a>
<a class="sourceLine" id="cb16-4" title="4"> right←,rrepr[1+6↓digits,CheckDigit digits;]</a> <a class="sourceLine" id="cb17-4" title="4"> right←,rrepr[1+6↓digits,CheckDigit digits;]</a>
<a class="sourceLine" id="cb16-5" title="5"> bits←1 0 1,left,0 1 0 1 0,right,1 0 1</a> <a class="sourceLine" id="cb17-5" title="5"> bits←1 0 1,left,0 1 0 1 0,right,1 0 1</a>
<a class="sourceLine" id="cb16-6" title="6"> :Else</a> <a class="sourceLine" id="cb17-6" title="6"> :Else</a>
<a class="sourceLine" id="cb16-7" title="7"> bits←¯1</a> <a class="sourceLine" id="cb17-7" title="7"> bits←¯1</a>
<a class="sourceLine" id="cb16-8" title="8"> :EndIf</a> <a class="sourceLine" id="cb17-8" title="8"> :EndIf</a>
<a class="sourceLine" id="cb16-9" title="9"></a></code></pre></div> <a class="sourceLine" id="cb17-9" title="9"></a></code></pre></div>
<p>First of all, if the vector <code>digits</code> does not have exactly 11 elements, all between 0 and 9, it is an error and we return <code>¯1</code>.</p> <p>First of all, if the vector <code>digits</code> does not have exactly 11 elements, all between 0 and 9, it is an error and we return <code>¯1</code>.</p>
<p>Then, we take the first 6 digits and encode them with <code>lrepr</code>, and the last 5 digits plus the check digit encoded with <code>rrepr</code>. In each case, adding 1 is necessary because <code>⎕IO←1</code>. We return the final bit array with the required beginning, middle, and end guard patterns.</p> <p>Then, we take the first 6 digits and encode them with <code>lrepr</code>, and the last 5 digits plus the check digit encoded with <code>rrepr</code>. In each case, adding 1 is necessary because <code>⎕IO←1</code>. We return the final bit array with the required beginning, middle, and end guard patterns.</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb17-1" title="1">∇ digits←ReadUPC bits</a> <div class="sourceCode" id="cb18"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb18-1" title="1">∇ digits←ReadUPC bits</a>
<a class="sourceLine" id="cb17-2" title="2"> :If 95≠bits ⍝ incorrect number of bits</a> <a class="sourceLine" id="cb18-2" title="2"> :If 95≠bits ⍝ incorrect number of bits</a>
<a class="sourceLine" id="cb17-3" title="3"> digits←¯1</a> <a class="sourceLine" id="cb18-3" title="3"> digits←¯1</a>
<a class="sourceLine" id="cb17-4" title="4"> :Else</a> <a class="sourceLine" id="cb18-4" title="4"> :Else</a>
<a class="sourceLine" id="cb17-5" title="5"> ⍝ Test if the barcode was scanned right-to-left.</a> <a class="sourceLine" id="cb18-5" title="5"> ⍝ Test if the barcode was scanned right-to-left.</a>
<a class="sourceLine" id="cb17-6" title="6"> :If 0=2|+/bits[3+7]</a> <a class="sourceLine" id="cb18-6" title="6"> :If 0=2|+/bits[3+7]</a>
<a class="sourceLine" id="cb17-7" title="7"> bits←⌽bits</a> <a class="sourceLine" id="cb18-7" title="7"> bits←⌽bits</a>
<a class="sourceLine" id="cb17-8" title="8"> :EndIf</a> <a class="sourceLine" id="cb18-8" title="8"> :EndIf</a>
<a class="sourceLine" id="cb17-9" title="9"> digits←({¯1+lrepr⍵}¨(7/6)⊆42↑3↓bits),{¯1+rrepr⍵}¨(7/6)⊆¯42↑¯3↓bits</a> <a class="sourceLine" id="cb18-9" title="9"> digits←({¯1+lrepr⍵}¨(7/6)⊆42↑3↓bits),{¯1+rrepr⍵}¨(7/6)⊆¯42↑¯3↓bits</a>
<a class="sourceLine" id="cb17-10" title="10"> :If ~∧/digits∊0,9 ⍝ incorrect parity</a> <a class="sourceLine" id="cb18-10" title="10"> :If ~∧/digits∊0,9 ⍝ incorrect parity</a>
<a class="sourceLine" id="cb17-11" title="11"> digits←¯1</a> <a class="sourceLine" id="cb18-11" title="11"> digits←¯1</a>
<a class="sourceLine" id="cb17-12" title="12"> :ElseIf (⊃⌽digits)≠CheckDigit ¯1↓digits ⍝ incorrect check digit</a> <a class="sourceLine" id="cb18-12" title="12"> :ElseIf (⊃⌽digits)≠CheckDigit ¯1↓digits ⍝ incorrect check digit</a>
<a class="sourceLine" id="cb17-13" title="13"> digits←¯1</a> <a class="sourceLine" id="cb18-13" title="13"> digits←¯1</a>
<a class="sourceLine" id="cb17-14" title="14"> :EndIf</a> <a class="sourceLine" id="cb18-14" title="14"> :EndIf</a>
<a class="sourceLine" id="cb17-15" title="15"> :EndIf</a> <a class="sourceLine" id="cb18-15" title="15"> :EndIf</a>
<a class="sourceLine" id="cb17-16" title="16"></a></code></pre></div> <a class="sourceLine" id="cb18-16" title="16"></a></code></pre></div>
<ul> <ul>
<li>If we dont have the correct number of bits, we return <code>¯1</code>.</li> <li>If we dont have the correct number of bits, we return <code>¯1</code>.</li>
<li>We test the first digit for its parity, to determine if its actually a left representation. If its not, we reverse the bit array.</li> <li>We test the first digit for its parity, to determine if its actually a left representation. If its not, we reverse the bit array.</li>
@ -197,51 +180,53 @@
<li>Final checks for the range of the digits (i.e., if the representations could not be found in the <code>lrepr</code> and <code>rrepr</code> vectors), and for the check digit.</li> <li>Final checks for the range of the digits (i.e., if the representations could not be found in the <code>lrepr</code> and <code>rrepr</code> vectors), and for the check digit.</li>
</ul> </ul>
<h2 id="problem-8-balancing-the-scales">Problem 8 Balancing the Scales</h2> <h2 id="problem-8-balancing-the-scales">Problem 8 Balancing the Scales</h2>
<div class="sourceCode" id="cb18"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb18-1" title="1">∇ parts←Balance nums;subsets;partitions</a> <div class="sourceCode" id="cb19"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb19-1" title="1">∇ parts←Balance nums;subsets;partitions</a>
<a class="sourceLine" id="cb18-2" title="2"> ⍝ This is a brute force solution, running in</a> <a class="sourceLine" id="cb19-2" title="2"> ⍝ This is a brute force solution, running in</a>
<a class="sourceLine" id="cb18-3" title="3"> ⍝ exponential time. We generate all the possible</a> <a class="sourceLine" id="cb19-3" title="3"> ⍝ exponential time. We generate all the possible</a>
<a class="sourceLine" id="cb18-4" title="4"> ⍝ partitions, filter out those which are not</a> <a class="sourceLine" id="cb19-4" title="4"> ⍝ partitions, filter out those which are not</a>
<a class="sourceLine" id="cb18-5" title="5"> ⍝ balanced, and return the first matching one. There</a> <a class="sourceLine" id="cb19-5" title="5"> ⍝ balanced, and return the first matching one. There</a>
<a class="sourceLine" id="cb18-6" title="6"> ⍝ are more advanced approach running in</a> <a class="sourceLine" id="cb19-6" title="6"> ⍝ are more advanced approach running in</a>
<a class="sourceLine" id="cb18-7" title="7"> ⍝ pseudo-polynomial time (based on dynamic</a> <a class="sourceLine" id="cb19-7" title="7"> ⍝ pseudo-polynomial time (based on dynamic</a>
<a class="sourceLine" id="cb18-8" title="8"> ⍝ programming, see the &quot;Partition problem&quot; Wikipedia</a> <a class="sourceLine" id="cb19-8" title="8"> ⍝ programming, see the &quot;Partition problem&quot; Wikipedia</a>
<a class="sourceLine" id="cb18-9" title="9"> ⍝ page), but they are not warranted here, as the</a> <a class="sourceLine" id="cb19-9" title="9"> ⍝ page), but they are not warranted here, as the</a>
<a class="sourceLine" id="cb18-10" title="10"> ⍝ input size remains fairly small.</a> <a class="sourceLine" id="cb19-10" title="10"> ⍝ input size remains fairly small.</a>
<a class="sourceLine" id="cb18-11" title="11"></a> <a class="sourceLine" id="cb19-11" title="11"></a>
<a class="sourceLine" id="cb18-12" title="12"> ⍝ Generate all partitions of a vector of a given</a> <a class="sourceLine" id="cb19-12" title="12"> ⍝ Generate all partitions of a vector of a given</a>
<a class="sourceLine" id="cb18-13" title="13"> ⍝ size, as binary mask vectors.</a> <a class="sourceLine" id="cb19-13" title="13"> ⍝ size, as binary mask vectors.</a>
<a class="sourceLine" id="cb18-14" title="14"> subsets←{1↓2⊥⍣¯12*⍵}</a> <a class="sourceLine" id="cb19-14" title="14"> subsets←{1↓2⊥⍣¯12*⍵}</a>
<a class="sourceLine" id="cb18-15" title="15"> ⍝ Keep only the subsets whose sum is exactly</a> <a class="sourceLine" id="cb19-15" title="15"> ⍝ Keep only the subsets whose sum is exactly</a>
<a class="sourceLine" id="cb18-16" title="16"> ⍝ (+/nums)÷2.</a> <a class="sourceLine" id="cb19-16" title="16"> ⍝ (+/nums)÷2.</a>
<a class="sourceLine" id="cb18-17" title="17"> partitions←nums{((2÷⍨+/)=+.×⍵)/⍵}subsetsnums</a> <a class="sourceLine" id="cb19-17" title="17"> partitions←nums{((2÷⍨+/)=+.×⍵)/⍵}subsetsnums</a>
<a class="sourceLine" id="cb18-18" title="18"> :If 0=≢,partitions</a> <a class="sourceLine" id="cb19-18" title="18"> :If 0=≢,partitions</a>
<a class="sourceLine" id="cb18-19" title="19"> ⍝ If no partition satisfy the above</a> <a class="sourceLine" id="cb19-19" title="19"> ⍝ If no partition satisfy the above</a>
<a class="sourceLine" id="cb18-20" title="20"> ⍝ criterion, we return ⍬.</a> <a class="sourceLine" id="cb19-20" title="20"> ⍝ criterion, we return ⍬.</a>
<a class="sourceLine" id="cb18-21" title="21"> parts←⍬</a> <a class="sourceLine" id="cb19-21" title="21"> parts←⍬</a>
<a class="sourceLine" id="cb18-22" title="22"> :Else</a> <a class="sourceLine" id="cb19-22" title="22"> :Else</a>
<a class="sourceLine" id="cb18-23" title="23"> ⍝ Otherwise, we return the first possible</a> <a class="sourceLine" id="cb19-23" title="23"> ⍝ Otherwise, we return the first possible</a>
<a class="sourceLine" id="cb18-24" title="24"> ⍝ partition.</a> <a class="sourceLine" id="cb19-24" title="24"> ⍝ partition.</a>
<a class="sourceLine" id="cb18-25" title="25"> parts←nums{((⊂,(⊂~))⊃↓⍉⍵)/¨2}partitions</a> <a class="sourceLine" id="cb19-25" title="25"> parts←nums{((⊂,(⊂~))⊃↓⍉⍵)/¨2}partitions</a>
<a class="sourceLine" id="cb18-26" title="26"> :EndIf</a> <a class="sourceLine" id="cb19-26" title="26"> :EndIf</a>
<a class="sourceLine" id="cb18-27" title="27"></a></code></pre></div> <a class="sourceLine" id="cb19-27" title="27"></a></code></pre></div>
<h2 id="problem-9-upwardly-mobile">Problem 9 Upwardly Mobile</h2> <h2 id="problem-9-upwardly-mobile">Problem 9 Upwardly Mobile</h2>
<div class="sourceCode" id="cb19"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb19-1" title="1">∇ weights←Weights filename;mobile;branches;mat</a> <p>This is the only problem that I didnt complete. It required parsing the files containing the graphical representations of the trees, which was needlessly complex and, quite frankly, hard and boring with a language like APL.</p>
<a class="sourceLine" id="cb19-2" title="2"> ⍝ Put your code and comments below here</a> <p>However, the next part is interesting: once we have a matrix of coefficients representing the relationships between the weights, we can solve the system of equations. <a href="https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Functions/Matrix%20Divide.htm">Matrix Divide</a> (<code></code>) will find one solution to the system. Since the system is overdetermined, we fix <code>A=1</code> to find one possible solution. Since we want integer weights, the solution we find is smaller than the one we want, and may contain fractional weights. So we multiply everything by the <a href="https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Functions/And%20Lowest%20Common%20Multiple.htm">Lowest Common Multiple</a> (<code></code>) to get the smallest integer weights.</p>
<a class="sourceLine" id="cb19-3" title="3"></a> <div class="sourceCode" id="cb20"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb20-1" title="1">∇ weights←Weights filename;mobile;branches;mat</a>
<a class="sourceLine" id="cb19-4" title="4"> ⍝ Parse the mobile input file.</a> <a class="sourceLine" id="cb20-2" title="2"> ⍝ Put your code and comments below here</a>
<a class="sourceLine" id="cb19-5" title="5"> mobile←↑⊃⎕NGET filename 1</a> <a class="sourceLine" id="cb20-3" title="3"></a>
<a class="sourceLine" id="cb19-6" title="6"> branches←⍸mobile∊'┌┴┐'</a> <a class="sourceLine" id="cb20-4" title="4"> ⍝ Parse the mobile input file.</a>
<a class="sourceLine" id="cb19-7" title="7"> ⍝ TODO: Build the matrix of coefficients mat.</a> <a class="sourceLine" id="cb20-5" title="5"> mobile←↑⊃⎕NGET filename 1</a>
<a class="sourceLine" id="cb19-8" title="8"></a> <a class="sourceLine" id="cb20-6" title="6"> branches←⍸mobile∊'┌┴┐'</a>
<a class="sourceLine" id="cb19-9" title="9"> ⍝ Solve the system of equations (arbitrarily setting</a> <a class="sourceLine" id="cb20-7" title="7"> ⍝ TODO: Build the matrix of coefficients mat.</a>
<a class="sourceLine" id="cb19-10" title="10"> ⍝ the first variable at 1 because the system is</a> <a class="sourceLine" id="cb20-8" title="8"></a>
<a class="sourceLine" id="cb19-11" title="11"> ⍝ overdetermined), then multiply the coefficients by</a> <a class="sourceLine" id="cb20-9" title="9"> ⍝ Solve the system of equations (arbitrarily setting</a>
<a class="sourceLine" id="cb19-12" title="12"> ⍝ their least common multiple to get the smallest</a> <a class="sourceLine" id="cb20-10" title="10"> ⍝ the first variable at 1 because the system is</a>
<a class="sourceLine" id="cb19-13" title="13"> ⍝ integer weights.</a> <a class="sourceLine" id="cb20-11" title="11"> ⍝ overdetermined), then multiply the coefficients by</a>
<a class="sourceLine" id="cb19-14" title="14"> weights←((1∘,)×(∧/÷))mat[;1]⌹1↓[2]mat</a> <a class="sourceLine" id="cb20-12" title="12"> ⍝ their least common multiple to get the smallest</a>
<a class="sourceLine" id="cb19-15" title="15"></a></code></pre></div> <a class="sourceLine" id="cb20-13" title="13"> ⍝ integer weights.</a>
<div class="sourceCode" id="cb20"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb20-1" title="1"> :EndNamespace</a> <a class="sourceLine" id="cb20-14" title="14"> weights←((1∘,)×(∧/÷))mat[;1]⌹1↓[2]mat</a>
<a class="sourceLine" id="cb20-2" title="2">:EndNamespace</a></code></pre></div> <a class="sourceLine" id="cb20-15" title="15"></a></code></pre></div>
<div class="sourceCode" id="cb21"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb21-1" title="1"> :EndNamespace</a>
<a class="sourceLine" id="cb21-2" title="2">:EndNamespace</a></code></pre></div>
</section> </section>
</article> </article>
]]></summary> ]]></summary>

View file

@ -137,50 +137,33 @@
<div class="sourceCode" id="cb9"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb9-1" title="1">sset←{((1E6|2∘×)⍣⍵)1}</a></code></pre></div> <div class="sourceCode" id="cb9"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb9-1" title="1">sset←{((1E6|2∘×)⍣⍵)1}</a></code></pre></div>
<p>Since we cannot just compute <span class="math inline">\(2^n\)</span> directly and take the remainder, we use modular arithmetic to stay mod 1,000,000 during the whole computation. The dfn <code>(1E6|2∘×)</code> doubles its argument mod 1,000,000. So we just apply this function <span class="math inline">\(n\)</span> times using the <a href="https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Operators/Power%20Operator.htm">Power</a> operator (<code></code>), with an initial value of 1.</p> <p>Since we cannot just compute <span class="math inline">\(2^n\)</span> directly and take the remainder, we use modular arithmetic to stay mod 1,000,000 during the whole computation. The dfn <code>(1E6|2∘×)</code> doubles its argument mod 1,000,000. So we just apply this function <span class="math inline">\(n\)</span> times using the <a href="https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Operators/Power%20Operator.htm">Power</a> operator (<code></code>), with an initial value of 1.</p>
<h2 id="problem-5-future-and-present-value">Problem 5 Future and Present Value</h2> <h2 id="problem-5-future-and-present-value">Problem 5 Future and Present Value</h2>
<div class="sourceCode" id="cb10"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb10-1" title="1">⍝ First solution: ((1+⊢)⊥⊣) computes the total return</a> <p>First solution: <code>((1+⊢)⊥⊣)</code> computes the total return for a vector of amounts <code></code> and a vector of rates <code></code>. It is applied to every prefix subarray of amounts and rates to get all intermediate values. However, this has quadratic complexity.</p>
<a class="sourceLine" id="cb10-2" title="2">⍝ for a vector of amounts and a vector of rates</a> <div class="sourceCode" id="cb10"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb10-1" title="1">rr←(,\⊣)((1+⊢)⊥⊣)¨(,\⊢)</a></code></pre></div>
<a class="sourceLine" id="cb10-3" title="3">⍝ ⍵. It is applied to every prefix subarray of amounts</a> <p>Second solution: We want to be able to use the recurrence relation (<code>recur</code>) and scan through the vectors of amounts and rates, accumulating the total value at every time step. However, APL evaluation is right-associative, so a simple <a href="https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Operators/Scan.htm">Scan</a> (<code>recur\amounts,¨values</code>) would not give the correct result, since <code>recur</code> is not associative and we need to evaluate it left-to-right. (In any case, in this case, Scan would have quadratic complexity, so would not bring any benefit over the previous solution.) What we need is something akin to Haskells <code>scanl</code> function, which would evaluate left to right in <span class="math inline">\(O(n)\)</span> time<span><label for="sn-1" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-1" class="margin-toggle" /><span class="sidenote">There is an interesting <a href="https://stackoverflow.com/a/25100675/8864368">StackOverflow answer</a> explaining the behaviour of Scan, and compares it to Haskells <code>scanl</code> function.<br />
<a class="sourceLine" id="cb10-4" title="4">⍝ and rates to get all intermediate values. However,</a> <br />
<a class="sourceLine" id="cb10-5" title="5">⍝ this has quadratic complexity.</a> </span></span>. This is what we do here, accumulating values from left to right. (This is inspired from <a href="https://dfns.dyalog.com/c_ascan.htm"><code>dfns.ascan</code></a>, although heavily simplified.)</p>
<a class="sourceLine" id="cb10-6" title="6">⍝ rr←(,\⊣)((1+⊢)⊥⊣)¨(,\⊢)</a> <div class="sourceCode" id="cb11"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb11-1" title="1">rr←{recur←{⍵[1]+×1+⍵[2]} ⋄ 1↓⌽⊃{(⊂(⊃⍵)recur),⍵}/⌽⍺,¨⍵}</a></code></pre></div>
<a class="sourceLine" id="cb10-7" title="7"></a> <p>For the second task, there is an explicit formula for cashflow calculations, so we can just apply it.</p>
<a class="sourceLine" id="cb10-8" title="8">⍝ Second solution: We want to be able to use the</a> <div class="sourceCode" id="cb12"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb12-1" title="1">pv←{+/⍺÷×\1+⍵}</a></code></pre></div>
<a class="sourceLine" id="cb10-9" title="9">⍝ recurrence relation (recur) and scan through the</a>
<a class="sourceLine" id="cb10-10" title="10">⍝ vectors of amounts and rates, accumulating the total</a>
<a class="sourceLine" id="cb10-11" title="11">⍝ value at every time step. However, APL evaluation is</a>
<a class="sourceLine" id="cb10-12" title="12">⍝ right-associative, so a simple Scan</a>
<a class="sourceLine" id="cb10-13" title="13">⍝ (recur\amounts,¨values) would not give the correct</a>
<a class="sourceLine" id="cb10-14" title="14">⍝ result, since recur is not associative and we need</a>
<a class="sourceLine" id="cb10-15" title="15">⍝ to evaluate it left-to-right. (In any case, in this</a>
<a class="sourceLine" id="cb10-16" title="16">⍝ case, Scan would have quadratic complexity, so would</a>
<a class="sourceLine" id="cb10-17" title="17">⍝ not bring any benefit over the previous solution.)</a>
<a class="sourceLine" id="cb10-18" title="18">⍝ What we need is something akin to Haskell's scanl</a>
<a class="sourceLine" id="cb10-19" title="19">⍝ function, which would evaluate left to right in O(n)</a>
<a class="sourceLine" id="cb10-20" title="20">⍝ time. This is what we do here, accumulating values</a>
<a class="sourceLine" id="cb10-21" title="21">⍝ from left to right. (This is inspired from</a>
<a class="sourceLine" id="cb10-22" title="22">⍝ dfns.ascan, although heavily simplified.)</a>
<a class="sourceLine" id="cb10-23" title="23">rr←{recur←{⍵[1]+×1+⍵[2]} ⋄ 1↓⌽⊃{(⊂(⊃⍵)recur),⍵}/⌽⍺,¨⍵}</a></code></pre></div>
<div class="sourceCode" id="cb11"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb11-1" title="1">⍝ Simply apply the formula for cashflow calculations.</a>
<a class="sourceLine" id="cb11-2" title="2">pv←{+/⍺÷×\1+⍵}</a></code></pre></div>
<h2 id="problem-6-merge">Problem 6 Merge</h2> <h2 id="problem-6-merge">Problem 6 Merge</h2>
<div class="sourceCode" id="cb12"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb12-1" title="1">∇ text←templateFile Merge jsonFile;template;ns</a> <div class="sourceCode" id="cb13"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb13-1" title="1">∇ text←templateFile Merge jsonFile;template;ns</a>
<a class="sourceLine" id="cb12-2" title="2"> template←⊃⎕NGET templateFile 1</a> <a class="sourceLine" id="cb13-2" title="2"> template←⊃⎕NGET templateFile 1</a>
<a class="sourceLine" id="cb12-3" title="3"> ns←⎕JSON⊃⎕NGET jsonFile</a> <a class="sourceLine" id="cb13-3" title="3"> ns←⎕JSON⊃⎕NGET jsonFile</a>
<a class="sourceLine" id="cb12-4" title="4"> ⍝ We use a simple regex search and replace on the</a> <a class="sourceLine" id="cb13-4" title="4"> ⍝ We use a simple regex search and replace on the</a>
<a class="sourceLine" id="cb12-5" title="5"> ⍝ template.</a> <a class="sourceLine" id="cb13-5" title="5"> ⍝ template.</a>
<a class="sourceLine" id="cb12-6" title="6"> text←↑('@[a-zA-Z]*@'⎕R{ns getval ¯1↓1↓⍵.Match})template</a> <a class="sourceLine" id="cb13-6" title="6"> text←↑('@[a-zA-Z]*@'⎕R{ns getval ¯1↓1↓⍵.Match})template</a>
<a class="sourceLine" id="cb12-7" title="7"></a></code></pre></div> <a class="sourceLine" id="cb13-7" title="7"></a></code></pre></div>
<p>We first read the template and the JSON values from their files. The <a href="https://help.dyalog.com/18.0/index.htm#Language/System%20Functions/nget.htm"><code>⎕NGET</code></a> function read simple text files, and <a href="https://help.dyalog.com/18.0/index.htm#Language/System%20Functions/json.htm"><code>⎕JSON</code></a> extracts the key-value pairs as a namespace.</p> <p>We first read the template and the JSON values from their files. The <a href="https://help.dyalog.com/18.0/index.htm#Language/System%20Functions/nget.htm"><code>⎕NGET</code></a> function read simple text files, and <a href="https://help.dyalog.com/18.0/index.htm#Language/System%20Functions/json.htm"><code>⎕JSON</code></a> extracts the key-value pairs as a namespace.</p>
<p>Assuming all variable names contain only letters, we match the regex <code>@[a-zA-Z]*@</code> to match variable names enclosed between <code>@</code> symbols. The function <code>getval</code> then returns the appropriate value, and we can replace the variable name in the template.</p> <p>Assuming all variable names contain only letters, we match the regex <code>@[a-zA-Z]*@</code> to match variable names enclosed between <code>@</code> symbols. The function <code>getval</code> then returns the appropriate value, and we can replace the variable name in the template.</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb13-1" title="1">∇ val←ns getval var</a> <div class="sourceCode" id="cb14"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb14-1" title="1">∇ val←ns getval var</a>
<a class="sourceLine" id="cb13-2" title="2"> :If ''≡var ⍝ literal '@'</a> <a class="sourceLine" id="cb14-2" title="2"> :If ''≡var ⍝ literal '@'</a>
<a class="sourceLine" id="cb13-3" title="3"> val←'@'</a> <a class="sourceLine" id="cb14-3" title="3"> val←'@'</a>
<a class="sourceLine" id="cb13-4" title="4"> :ElseIf (⊂var)∊ns.⎕NL ¯2</a> <a class="sourceLine" id="cb14-4" title="4"> :ElseIf (⊂var)∊ns.⎕NL ¯2</a>
<a class="sourceLine" id="cb13-5" title="5"> val←⍕ns⍎var</a> <a class="sourceLine" id="cb14-5" title="5"> val←⍕ns⍎var</a>
<a class="sourceLine" id="cb13-6" title="6"> :Else</a> <a class="sourceLine" id="cb14-6" title="6"> :Else</a>
<a class="sourceLine" id="cb13-7" title="7"> val←'???'</a> <a class="sourceLine" id="cb14-7" title="7"> val←'???'</a>
<a class="sourceLine" id="cb13-8" title="8"> :EndIf</a> <a class="sourceLine" id="cb14-8" title="8"> :EndIf</a>
<a class="sourceLine" id="cb13-9" title="9"></a></code></pre></div> <a class="sourceLine" id="cb14-9" title="9"></a></code></pre></div>
<p>This function takes the namespace matching the variable names to their respective values, and the name of the variable.</p> <p>This function takes the namespace matching the variable names to their respective values, and the name of the variable.</p>
<ul> <ul>
<li>If the variable name is empty, we matched the string <code>@@</code>, which corresponds to a literal <code>@</code>.</li> <li>If the variable name is empty, we matched the string <code>@@</code>, which corresponds to a literal <code>@</code>.</li>
@ -188,42 +171,42 @@
<li>Otherwise, we have an unknown variable, so we replace it with <code>???</code>.</li> <li>Otherwise, we have an unknown variable, so we replace it with <code>???</code>.</li>
</ul> </ul>
<h2 id="problem-7-upc">Problem 7 UPC</h2> <h2 id="problem-7-upc">Problem 7 UPC</h2>
<div class="sourceCode" id="cb14"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb14-1" title="1">CheckDigit←{10|-⍵+.×113 1}</a></code></pre></div> <div class="sourceCode" id="cb15"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb15-1" title="1">CheckDigit←{10|-⍵+.×113 1}</a></code></pre></div>
<p>The check digit satisfies the equation <span class="math display">\[ 3 x_{1}+x_{2}+3 x_{3}+x_{4}+3 x_{5}+x_{6}+3 x_{7}+x_{8}+3 x_{9}+x_{10}+3 x_{11}+x_{12} \equiv 0 \bmod 10, \]</span> therefore, <span class="math display">\[ x_{12} \equiv -(3 x_{1}+x_{2}+3 x_{3}+x_{4}+3 x_{5}+x_{6}+3 x_{7}+x_{8}+3 x_{9}+x_{10}+3 x_{11}) \bmod 10. \]</span></p> <p>The check digit satisfies the equation <span class="math display">\[ 3 x_{1}+x_{2}+3 x_{3}+x_{4}+3 x_{5}+x_{6}+3 x_{7}+x_{8}+3 x_{9}+x_{10}+3 x_{11}+x_{12} \equiv 0 \bmod 10, \]</span> therefore, <span class="math display">\[ x_{12} \equiv -(3 x_{1}+x_{2}+3 x_{3}+x_{4}+3 x_{5}+x_{6}+3 x_{7}+x_{8}+3 x_{9}+x_{10}+3 x_{11}) \bmod 10. \]</span></p>
<p>Translated to APL, we just take the dot product between the first 11 digits of the barcode with <code>113 1</code>, negate it, and take the remainder by 10.</p> <p>Translated to APL, we just take the dot product between the first 11 digits of the barcode with <code>113 1</code>, negate it, and take the remainder by 10.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb15-1" title="1">⍝ Left and right representations of digits. Decoding</a> <div class="sourceCode" id="cb16"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb16-1" title="1">⍝ Left and right representations of digits. Decoding</a>
<a class="sourceLine" id="cb15-2" title="2">⍝ the binary representation from decimal is more</a> <a class="sourceLine" id="cb16-2" title="2">⍝ the binary representation from decimal is more</a>
<a class="sourceLine" id="cb15-3" title="3">⍝ compact than writing everything explicitly.</a> <a class="sourceLine" id="cb16-3" title="3">⍝ compact than writing everything explicitly.</a>
<a class="sourceLine" id="cb15-4" title="4">lrepr←⍉(72)13 25 19 61 35 49 47 59 55 11</a> <a class="sourceLine" id="cb16-4" title="4">lrepr←⍉(72)13 25 19 61 35 49 47 59 55 11</a>
<a class="sourceLine" id="cb15-5" title="5">rrepr←~¨lrepr</a></code></pre></div> <a class="sourceLine" id="cb16-5" title="5">rrepr←~¨lrepr</a></code></pre></div>
<p>For the second task, the first thing we need to do is save the representation of digits. To save space, I did not encode the binary representation explicitly, instead using a decimal representation that I then decode in base 2. The right representation is just the bitwise negation.</p> <p>For the second task, the first thing we need to do is save the representation of digits. To save space, I did not encode the binary representation explicitly, instead using a decimal representation that I then decode in base 2. The right representation is just the bitwise negation.</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb16-1" title="1">∇ bits←WriteUPC digits;left;right</a> <div class="sourceCode" id="cb17"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb17-1" title="1">∇ bits←WriteUPC digits;left;right</a>
<a class="sourceLine" id="cb16-2" title="2"> :If (11=≢digits)∧∧/digits∊0,9</a> <a class="sourceLine" id="cb17-2" title="2"> :If (11=≢digits)∧∧/digits∊0,9</a>
<a class="sourceLine" id="cb16-3" title="3"> left←,lrepr[1+6↑digits;]</a> <a class="sourceLine" id="cb17-3" title="3"> left←,lrepr[1+6↑digits;]</a>
<a class="sourceLine" id="cb16-4" title="4"> right←,rrepr[1+6↓digits,CheckDigit digits;]</a> <a class="sourceLine" id="cb17-4" title="4"> right←,rrepr[1+6↓digits,CheckDigit digits;]</a>
<a class="sourceLine" id="cb16-5" title="5"> bits←1 0 1,left,0 1 0 1 0,right,1 0 1</a> <a class="sourceLine" id="cb17-5" title="5"> bits←1 0 1,left,0 1 0 1 0,right,1 0 1</a>
<a class="sourceLine" id="cb16-6" title="6"> :Else</a> <a class="sourceLine" id="cb17-6" title="6"> :Else</a>
<a class="sourceLine" id="cb16-7" title="7"> bits←¯1</a> <a class="sourceLine" id="cb17-7" title="7"> bits←¯1</a>
<a class="sourceLine" id="cb16-8" title="8"> :EndIf</a> <a class="sourceLine" id="cb17-8" title="8"> :EndIf</a>
<a class="sourceLine" id="cb16-9" title="9"></a></code></pre></div> <a class="sourceLine" id="cb17-9" title="9"></a></code></pre></div>
<p>First of all, if the vector <code>digits</code> does not have exactly 11 elements, all between 0 and 9, it is an error and we return <code>¯1</code>.</p> <p>First of all, if the vector <code>digits</code> does not have exactly 11 elements, all between 0 and 9, it is an error and we return <code>¯1</code>.</p>
<p>Then, we take the first 6 digits and encode them with <code>lrepr</code>, and the last 5 digits plus the check digit encoded with <code>rrepr</code>. In each case, adding 1 is necessary because <code>⎕IO←1</code>. We return the final bit array with the required beginning, middle, and end guard patterns.</p> <p>Then, we take the first 6 digits and encode them with <code>lrepr</code>, and the last 5 digits plus the check digit encoded with <code>rrepr</code>. In each case, adding 1 is necessary because <code>⎕IO←1</code>. We return the final bit array with the required beginning, middle, and end guard patterns.</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb17-1" title="1">∇ digits←ReadUPC bits</a> <div class="sourceCode" id="cb18"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb18-1" title="1">∇ digits←ReadUPC bits</a>
<a class="sourceLine" id="cb17-2" title="2"> :If 95≠bits ⍝ incorrect number of bits</a> <a class="sourceLine" id="cb18-2" title="2"> :If 95≠bits ⍝ incorrect number of bits</a>
<a class="sourceLine" id="cb17-3" title="3"> digits←¯1</a> <a class="sourceLine" id="cb18-3" title="3"> digits←¯1</a>
<a class="sourceLine" id="cb17-4" title="4"> :Else</a> <a class="sourceLine" id="cb18-4" title="4"> :Else</a>
<a class="sourceLine" id="cb17-5" title="5"> ⍝ Test if the barcode was scanned right-to-left.</a> <a class="sourceLine" id="cb18-5" title="5"> ⍝ Test if the barcode was scanned right-to-left.</a>
<a class="sourceLine" id="cb17-6" title="6"> :If 0=2|+/bits[3+7]</a> <a class="sourceLine" id="cb18-6" title="6"> :If 0=2|+/bits[3+7]</a>
<a class="sourceLine" id="cb17-7" title="7"> bits←⌽bits</a> <a class="sourceLine" id="cb18-7" title="7"> bits←⌽bits</a>
<a class="sourceLine" id="cb17-8" title="8"> :EndIf</a> <a class="sourceLine" id="cb18-8" title="8"> :EndIf</a>
<a class="sourceLine" id="cb17-9" title="9"> digits←({¯1+lrepr⍵}¨(7/6)⊆42↑3↓bits),{¯1+rrepr⍵}¨(7/6)⊆¯42↑¯3↓bits</a> <a class="sourceLine" id="cb18-9" title="9"> digits←({¯1+lrepr⍵}¨(7/6)⊆42↑3↓bits),{¯1+rrepr⍵}¨(7/6)⊆¯42↑¯3↓bits</a>
<a class="sourceLine" id="cb17-10" title="10"> :If ~∧/digits∊0,9 ⍝ incorrect parity</a> <a class="sourceLine" id="cb18-10" title="10"> :If ~∧/digits∊0,9 ⍝ incorrect parity</a>
<a class="sourceLine" id="cb17-11" title="11"> digits←¯1</a> <a class="sourceLine" id="cb18-11" title="11"> digits←¯1</a>
<a class="sourceLine" id="cb17-12" title="12"> :ElseIf (⊃⌽digits)≠CheckDigit ¯1↓digits ⍝ incorrect check digit</a> <a class="sourceLine" id="cb18-12" title="12"> :ElseIf (⊃⌽digits)≠CheckDigit ¯1↓digits ⍝ incorrect check digit</a>
<a class="sourceLine" id="cb17-13" title="13"> digits←¯1</a> <a class="sourceLine" id="cb18-13" title="13"> digits←¯1</a>
<a class="sourceLine" id="cb17-14" title="14"> :EndIf</a> <a class="sourceLine" id="cb18-14" title="14"> :EndIf</a>
<a class="sourceLine" id="cb17-15" title="15"> :EndIf</a> <a class="sourceLine" id="cb18-15" title="15"> :EndIf</a>
<a class="sourceLine" id="cb17-16" title="16"></a></code></pre></div> <a class="sourceLine" id="cb18-16" title="16"></a></code></pre></div>
<ul> <ul>
<li>If we dont have the correct number of bits, we return <code>¯1</code>.</li> <li>If we dont have the correct number of bits, we return <code>¯1</code>.</li>
<li>We test the first digit for its parity, to determine if its actually a left representation. If its not, we reverse the bit array.</li> <li>We test the first digit for its parity, to determine if its actually a left representation. If its not, we reverse the bit array.</li>
@ -231,51 +214,53 @@
<li>Final checks for the range of the digits (i.e., if the representations could not be found in the <code>lrepr</code> and <code>rrepr</code> vectors), and for the check digit.</li> <li>Final checks for the range of the digits (i.e., if the representations could not be found in the <code>lrepr</code> and <code>rrepr</code> vectors), and for the check digit.</li>
</ul> </ul>
<h2 id="problem-8-balancing-the-scales">Problem 8 Balancing the Scales</h2> <h2 id="problem-8-balancing-the-scales">Problem 8 Balancing the Scales</h2>
<div class="sourceCode" id="cb18"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb18-1" title="1">∇ parts←Balance nums;subsets;partitions</a> <div class="sourceCode" id="cb19"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb19-1" title="1">∇ parts←Balance nums;subsets;partitions</a>
<a class="sourceLine" id="cb18-2" title="2"> ⍝ This is a brute force solution, running in</a> <a class="sourceLine" id="cb19-2" title="2"> ⍝ This is a brute force solution, running in</a>
<a class="sourceLine" id="cb18-3" title="3"> ⍝ exponential time. We generate all the possible</a> <a class="sourceLine" id="cb19-3" title="3"> ⍝ exponential time. We generate all the possible</a>
<a class="sourceLine" id="cb18-4" title="4"> ⍝ partitions, filter out those which are not</a> <a class="sourceLine" id="cb19-4" title="4"> ⍝ partitions, filter out those which are not</a>
<a class="sourceLine" id="cb18-5" title="5"> ⍝ balanced, and return the first matching one. There</a> <a class="sourceLine" id="cb19-5" title="5"> ⍝ balanced, and return the first matching one. There</a>
<a class="sourceLine" id="cb18-6" title="6"> ⍝ are more advanced approach running in</a> <a class="sourceLine" id="cb19-6" title="6"> ⍝ are more advanced approach running in</a>
<a class="sourceLine" id="cb18-7" title="7"> ⍝ pseudo-polynomial time (based on dynamic</a> <a class="sourceLine" id="cb19-7" title="7"> ⍝ pseudo-polynomial time (based on dynamic</a>
<a class="sourceLine" id="cb18-8" title="8"> ⍝ programming, see the &quot;Partition problem&quot; Wikipedia</a> <a class="sourceLine" id="cb19-8" title="8"> ⍝ programming, see the &quot;Partition problem&quot; Wikipedia</a>
<a class="sourceLine" id="cb18-9" title="9"> ⍝ page), but they are not warranted here, as the</a> <a class="sourceLine" id="cb19-9" title="9"> ⍝ page), but they are not warranted here, as the</a>
<a class="sourceLine" id="cb18-10" title="10"> ⍝ input size remains fairly small.</a> <a class="sourceLine" id="cb19-10" title="10"> ⍝ input size remains fairly small.</a>
<a class="sourceLine" id="cb18-11" title="11"></a> <a class="sourceLine" id="cb19-11" title="11"></a>
<a class="sourceLine" id="cb18-12" title="12"> ⍝ Generate all partitions of a vector of a given</a> <a class="sourceLine" id="cb19-12" title="12"> ⍝ Generate all partitions of a vector of a given</a>
<a class="sourceLine" id="cb18-13" title="13"> ⍝ size, as binary mask vectors.</a> <a class="sourceLine" id="cb19-13" title="13"> ⍝ size, as binary mask vectors.</a>
<a class="sourceLine" id="cb18-14" title="14"> subsets←{1↓2⊥⍣¯12*⍵}</a> <a class="sourceLine" id="cb19-14" title="14"> subsets←{1↓2⊥⍣¯12*⍵}</a>
<a class="sourceLine" id="cb18-15" title="15"> ⍝ Keep only the subsets whose sum is exactly</a> <a class="sourceLine" id="cb19-15" title="15"> ⍝ Keep only the subsets whose sum is exactly</a>
<a class="sourceLine" id="cb18-16" title="16"> ⍝ (+/nums)÷2.</a> <a class="sourceLine" id="cb19-16" title="16"> ⍝ (+/nums)÷2.</a>
<a class="sourceLine" id="cb18-17" title="17"> partitions←nums{((2÷⍨+/)=+.×⍵)/⍵}subsetsnums</a> <a class="sourceLine" id="cb19-17" title="17"> partitions←nums{((2÷⍨+/)=+.×⍵)/⍵}subsetsnums</a>
<a class="sourceLine" id="cb18-18" title="18"> :If 0=≢,partitions</a> <a class="sourceLine" id="cb19-18" title="18"> :If 0=≢,partitions</a>
<a class="sourceLine" id="cb18-19" title="19"> ⍝ If no partition satisfy the above</a> <a class="sourceLine" id="cb19-19" title="19"> ⍝ If no partition satisfy the above</a>
<a class="sourceLine" id="cb18-20" title="20"> ⍝ criterion, we return ⍬.</a> <a class="sourceLine" id="cb19-20" title="20"> ⍝ criterion, we return ⍬.</a>
<a class="sourceLine" id="cb18-21" title="21"> parts←⍬</a> <a class="sourceLine" id="cb19-21" title="21"> parts←⍬</a>
<a class="sourceLine" id="cb18-22" title="22"> :Else</a> <a class="sourceLine" id="cb19-22" title="22"> :Else</a>
<a class="sourceLine" id="cb18-23" title="23"> ⍝ Otherwise, we return the first possible</a> <a class="sourceLine" id="cb19-23" title="23"> ⍝ Otherwise, we return the first possible</a>
<a class="sourceLine" id="cb18-24" title="24"> ⍝ partition.</a> <a class="sourceLine" id="cb19-24" title="24"> ⍝ partition.</a>
<a class="sourceLine" id="cb18-25" title="25"> parts←nums{((⊂,(⊂~))⊃↓⍉⍵)/¨2}partitions</a> <a class="sourceLine" id="cb19-25" title="25"> parts←nums{((⊂,(⊂~))⊃↓⍉⍵)/¨2}partitions</a>
<a class="sourceLine" id="cb18-26" title="26"> :EndIf</a> <a class="sourceLine" id="cb19-26" title="26"> :EndIf</a>
<a class="sourceLine" id="cb18-27" title="27"></a></code></pre></div> <a class="sourceLine" id="cb19-27" title="27"></a></code></pre></div>
<h2 id="problem-9-upwardly-mobile">Problem 9 Upwardly Mobile</h2> <h2 id="problem-9-upwardly-mobile">Problem 9 Upwardly Mobile</h2>
<div class="sourceCode" id="cb19"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb19-1" title="1">∇ weights←Weights filename;mobile;branches;mat</a> <p>This is the only problem that I didnt complete. It required parsing the files containing the graphical representations of the trees, which was needlessly complex and, quite frankly, hard and boring with a language like APL.</p>
<a class="sourceLine" id="cb19-2" title="2"> ⍝ Put your code and comments below here</a> <p>However, the next part is interesting: once we have a matrix of coefficients representing the relationships between the weights, we can solve the system of equations. <a href="https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Functions/Matrix%20Divide.htm">Matrix Divide</a> (<code></code>) will find one solution to the system. Since the system is overdetermined, we fix <code>A=1</code> to find one possible solution. Since we want integer weights, the solution we find is smaller than the one we want, and may contain fractional weights. So we multiply everything by the <a href="https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Functions/And%20Lowest%20Common%20Multiple.htm">Lowest Common Multiple</a> (<code></code>) to get the smallest integer weights.</p>
<a class="sourceLine" id="cb19-3" title="3"></a> <div class="sourceCode" id="cb20"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb20-1" title="1">∇ weights←Weights filename;mobile;branches;mat</a>
<a class="sourceLine" id="cb19-4" title="4"> ⍝ Parse the mobile input file.</a> <a class="sourceLine" id="cb20-2" title="2"> ⍝ Put your code and comments below here</a>
<a class="sourceLine" id="cb19-5" title="5"> mobile←↑⊃⎕NGET filename 1</a> <a class="sourceLine" id="cb20-3" title="3"></a>
<a class="sourceLine" id="cb19-6" title="6"> branches←⍸mobile∊'┌┴┐'</a> <a class="sourceLine" id="cb20-4" title="4"> ⍝ Parse the mobile input file.</a>
<a class="sourceLine" id="cb19-7" title="7"> ⍝ TODO: Build the matrix of coefficients mat.</a> <a class="sourceLine" id="cb20-5" title="5"> mobile←↑⊃⎕NGET filename 1</a>
<a class="sourceLine" id="cb19-8" title="8"></a> <a class="sourceLine" id="cb20-6" title="6"> branches←⍸mobile∊'┌┴┐'</a>
<a class="sourceLine" id="cb19-9" title="9"> ⍝ Solve the system of equations (arbitrarily setting</a> <a class="sourceLine" id="cb20-7" title="7"> ⍝ TODO: Build the matrix of coefficients mat.</a>
<a class="sourceLine" id="cb19-10" title="10"> ⍝ the first variable at 1 because the system is</a> <a class="sourceLine" id="cb20-8" title="8"></a>
<a class="sourceLine" id="cb19-11" title="11"> ⍝ overdetermined), then multiply the coefficients by</a> <a class="sourceLine" id="cb20-9" title="9"> ⍝ Solve the system of equations (arbitrarily setting</a>
<a class="sourceLine" id="cb19-12" title="12"> ⍝ their least common multiple to get the smallest</a> <a class="sourceLine" id="cb20-10" title="10"> ⍝ the first variable at 1 because the system is</a>
<a class="sourceLine" id="cb19-13" title="13"> ⍝ integer weights.</a> <a class="sourceLine" id="cb20-11" title="11"> ⍝ overdetermined), then multiply the coefficients by</a>
<a class="sourceLine" id="cb19-14" title="14"> weights←((1∘,)×(∧/÷))mat[;1]⌹1↓[2]mat</a> <a class="sourceLine" id="cb20-12" title="12"> ⍝ their least common multiple to get the smallest</a>
<a class="sourceLine" id="cb19-15" title="15"></a></code></pre></div> <a class="sourceLine" id="cb20-13" title="13"> ⍝ integer weights.</a>
<div class="sourceCode" id="cb20"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb20-1" title="1"> :EndNamespace</a> <a class="sourceLine" id="cb20-14" title="14"> weights←((1∘,)×(∧/÷))mat[;1]⌹1↓[2]mat</a>
<a class="sourceLine" id="cb20-2" title="2">:EndNamespace</a></code></pre></div> <a class="sourceLine" id="cb20-15" title="15"></a></code></pre></div>
<div class="sourceCode" id="cb21"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb21-1" title="1"> :EndNamespace</a>
<a class="sourceLine" id="cb21-2" title="2">:EndNamespace</a></code></pre></div>
</section> </section>
</article> </article>

View file

@ -99,50 +99,33 @@
<div class="sourceCode" id="cb9"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb9-1" title="1">sset←{((1E6|2∘×)⍣⍵)1}</a></code></pre></div> <div class="sourceCode" id="cb9"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb9-1" title="1">sset←{((1E6|2∘×)⍣⍵)1}</a></code></pre></div>
<p>Since we cannot just compute <span class="math inline">\(2^n\)</span> directly and take the remainder, we use modular arithmetic to stay mod 1,000,000 during the whole computation. The dfn <code>(1E6|2∘×)</code> doubles its argument mod 1,000,000. So we just apply this function <span class="math inline">\(n\)</span> times using the <a href="https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Operators/Power%20Operator.htm">Power</a> operator (<code></code>), with an initial value of 1.</p> <p>Since we cannot just compute <span class="math inline">\(2^n\)</span> directly and take the remainder, we use modular arithmetic to stay mod 1,000,000 during the whole computation. The dfn <code>(1E6|2∘×)</code> doubles its argument mod 1,000,000. So we just apply this function <span class="math inline">\(n\)</span> times using the <a href="https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Operators/Power%20Operator.htm">Power</a> operator (<code></code>), with an initial value of 1.</p>
<h2 id="problem-5-future-and-present-value">Problem 5 Future and Present Value</h2> <h2 id="problem-5-future-and-present-value">Problem 5 Future and Present Value</h2>
<div class="sourceCode" id="cb10"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb10-1" title="1">⍝ First solution: ((1+⊢)⊥⊣) computes the total return</a> <p>First solution: <code>((1+⊢)⊥⊣)</code> computes the total return for a vector of amounts <code></code> and a vector of rates <code></code>. It is applied to every prefix subarray of amounts and rates to get all intermediate values. However, this has quadratic complexity.</p>
<a class="sourceLine" id="cb10-2" title="2">⍝ for a vector of amounts and a vector of rates</a> <div class="sourceCode" id="cb10"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb10-1" title="1">rr←(,\⊣)((1+⊢)⊥⊣)¨(,\⊢)</a></code></pre></div>
<a class="sourceLine" id="cb10-3" title="3">⍝ ⍵. It is applied to every prefix subarray of amounts</a> <p>Second solution: We want to be able to use the recurrence relation (<code>recur</code>) and scan through the vectors of amounts and rates, accumulating the total value at every time step. However, APL evaluation is right-associative, so a simple <a href="https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Operators/Scan.htm">Scan</a> (<code>recur\amounts,¨values</code>) would not give the correct result, since <code>recur</code> is not associative and we need to evaluate it left-to-right. (In any case, in this case, Scan would have quadratic complexity, so would not bring any benefit over the previous solution.) What we need is something akin to Haskells <code>scanl</code> function, which would evaluate left to right in <span class="math inline">\(O(n)\)</span> time<span><label for="sn-1" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-1" class="margin-toggle" /><span class="sidenote">There is an interesting <a href="https://stackoverflow.com/a/25100675/8864368">StackOverflow answer</a> explaining the behaviour of Scan, and compares it to Haskells <code>scanl</code> function.<br />
<a class="sourceLine" id="cb10-4" title="4">⍝ and rates to get all intermediate values. However,</a> <br />
<a class="sourceLine" id="cb10-5" title="5">⍝ this has quadratic complexity.</a> </span></span>. This is what we do here, accumulating values from left to right. (This is inspired from <a href="https://dfns.dyalog.com/c_ascan.htm"><code>dfns.ascan</code></a>, although heavily simplified.)</p>
<a class="sourceLine" id="cb10-6" title="6">⍝ rr←(,\⊣)((1+⊢)⊥⊣)¨(,\⊢)</a> <div class="sourceCode" id="cb11"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb11-1" title="1">rr←{recur←{⍵[1]+×1+⍵[2]} ⋄ 1↓⌽⊃{(⊂(⊃⍵)recur),⍵}/⌽⍺,¨⍵}</a></code></pre></div>
<a class="sourceLine" id="cb10-7" title="7"></a> <p>For the second task, there is an explicit formula for cashflow calculations, so we can just apply it.</p>
<a class="sourceLine" id="cb10-8" title="8">⍝ Second solution: We want to be able to use the</a> <div class="sourceCode" id="cb12"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb12-1" title="1">pv←{+/⍺÷×\1+⍵}</a></code></pre></div>
<a class="sourceLine" id="cb10-9" title="9">⍝ recurrence relation (recur) and scan through the</a>
<a class="sourceLine" id="cb10-10" title="10">⍝ vectors of amounts and rates, accumulating the total</a>
<a class="sourceLine" id="cb10-11" title="11">⍝ value at every time step. However, APL evaluation is</a>
<a class="sourceLine" id="cb10-12" title="12">⍝ right-associative, so a simple Scan</a>
<a class="sourceLine" id="cb10-13" title="13">⍝ (recur\amounts,¨values) would not give the correct</a>
<a class="sourceLine" id="cb10-14" title="14">⍝ result, since recur is not associative and we need</a>
<a class="sourceLine" id="cb10-15" title="15">⍝ to evaluate it left-to-right. (In any case, in this</a>
<a class="sourceLine" id="cb10-16" title="16">⍝ case, Scan would have quadratic complexity, so would</a>
<a class="sourceLine" id="cb10-17" title="17">⍝ not bring any benefit over the previous solution.)</a>
<a class="sourceLine" id="cb10-18" title="18">⍝ What we need is something akin to Haskell's scanl</a>
<a class="sourceLine" id="cb10-19" title="19">⍝ function, which would evaluate left to right in O(n)</a>
<a class="sourceLine" id="cb10-20" title="20">⍝ time. This is what we do here, accumulating values</a>
<a class="sourceLine" id="cb10-21" title="21">⍝ from left to right. (This is inspired from</a>
<a class="sourceLine" id="cb10-22" title="22">⍝ dfns.ascan, although heavily simplified.)</a>
<a class="sourceLine" id="cb10-23" title="23">rr←{recur←{⍵[1]+×1+⍵[2]} ⋄ 1↓⌽⊃{(⊂(⊃⍵)recur),⍵}/⌽⍺,¨⍵}</a></code></pre></div>
<div class="sourceCode" id="cb11"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb11-1" title="1">⍝ Simply apply the formula for cashflow calculations.</a>
<a class="sourceLine" id="cb11-2" title="2">pv←{+/⍺÷×\1+⍵}</a></code></pre></div>
<h2 id="problem-6-merge">Problem 6 Merge</h2> <h2 id="problem-6-merge">Problem 6 Merge</h2>
<div class="sourceCode" id="cb12"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb12-1" title="1">∇ text←templateFile Merge jsonFile;template;ns</a> <div class="sourceCode" id="cb13"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb13-1" title="1">∇ text←templateFile Merge jsonFile;template;ns</a>
<a class="sourceLine" id="cb12-2" title="2"> template←⊃⎕NGET templateFile 1</a> <a class="sourceLine" id="cb13-2" title="2"> template←⊃⎕NGET templateFile 1</a>
<a class="sourceLine" id="cb12-3" title="3"> ns←⎕JSON⊃⎕NGET jsonFile</a> <a class="sourceLine" id="cb13-3" title="3"> ns←⎕JSON⊃⎕NGET jsonFile</a>
<a class="sourceLine" id="cb12-4" title="4"> ⍝ We use a simple regex search and replace on the</a> <a class="sourceLine" id="cb13-4" title="4"> ⍝ We use a simple regex search and replace on the</a>
<a class="sourceLine" id="cb12-5" title="5"> ⍝ template.</a> <a class="sourceLine" id="cb13-5" title="5"> ⍝ template.</a>
<a class="sourceLine" id="cb12-6" title="6"> text←↑('@[a-zA-Z]*@'⎕R{ns getval ¯1↓1↓⍵.Match})template</a> <a class="sourceLine" id="cb13-6" title="6"> text←↑('@[a-zA-Z]*@'⎕R{ns getval ¯1↓1↓⍵.Match})template</a>
<a class="sourceLine" id="cb12-7" title="7"></a></code></pre></div> <a class="sourceLine" id="cb13-7" title="7"></a></code></pre></div>
<p>We first read the template and the JSON values from their files. The <a href="https://help.dyalog.com/18.0/index.htm#Language/System%20Functions/nget.htm"><code>⎕NGET</code></a> function read simple text files, and <a href="https://help.dyalog.com/18.0/index.htm#Language/System%20Functions/json.htm"><code>⎕JSON</code></a> extracts the key-value pairs as a namespace.</p> <p>We first read the template and the JSON values from their files. The <a href="https://help.dyalog.com/18.0/index.htm#Language/System%20Functions/nget.htm"><code>⎕NGET</code></a> function read simple text files, and <a href="https://help.dyalog.com/18.0/index.htm#Language/System%20Functions/json.htm"><code>⎕JSON</code></a> extracts the key-value pairs as a namespace.</p>
<p>Assuming all variable names contain only letters, we match the regex <code>@[a-zA-Z]*@</code> to match variable names enclosed between <code>@</code> symbols. The function <code>getval</code> then returns the appropriate value, and we can replace the variable name in the template.</p> <p>Assuming all variable names contain only letters, we match the regex <code>@[a-zA-Z]*@</code> to match variable names enclosed between <code>@</code> symbols. The function <code>getval</code> then returns the appropriate value, and we can replace the variable name in the template.</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb13-1" title="1">∇ val←ns getval var</a> <div class="sourceCode" id="cb14"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb14-1" title="1">∇ val←ns getval var</a>
<a class="sourceLine" id="cb13-2" title="2"> :If ''≡var ⍝ literal '@'</a> <a class="sourceLine" id="cb14-2" title="2"> :If ''≡var ⍝ literal '@'</a>
<a class="sourceLine" id="cb13-3" title="3"> val←'@'</a> <a class="sourceLine" id="cb14-3" title="3"> val←'@'</a>
<a class="sourceLine" id="cb13-4" title="4"> :ElseIf (⊂var)∊ns.⎕NL ¯2</a> <a class="sourceLine" id="cb14-4" title="4"> :ElseIf (⊂var)∊ns.⎕NL ¯2</a>
<a class="sourceLine" id="cb13-5" title="5"> val←⍕ns⍎var</a> <a class="sourceLine" id="cb14-5" title="5"> val←⍕ns⍎var</a>
<a class="sourceLine" id="cb13-6" title="6"> :Else</a> <a class="sourceLine" id="cb14-6" title="6"> :Else</a>
<a class="sourceLine" id="cb13-7" title="7"> val←'???'</a> <a class="sourceLine" id="cb14-7" title="7"> val←'???'</a>
<a class="sourceLine" id="cb13-8" title="8"> :EndIf</a> <a class="sourceLine" id="cb14-8" title="8"> :EndIf</a>
<a class="sourceLine" id="cb13-9" title="9"></a></code></pre></div> <a class="sourceLine" id="cb14-9" title="9"></a></code></pre></div>
<p>This function takes the namespace matching the variable names to their respective values, and the name of the variable.</p> <p>This function takes the namespace matching the variable names to their respective values, and the name of the variable.</p>
<ul> <ul>
<li>If the variable name is empty, we matched the string <code>@@</code>, which corresponds to a literal <code>@</code>.</li> <li>If the variable name is empty, we matched the string <code>@@</code>, which corresponds to a literal <code>@</code>.</li>
@ -150,42 +133,42 @@
<li>Otherwise, we have an unknown variable, so we replace it with <code>???</code>.</li> <li>Otherwise, we have an unknown variable, so we replace it with <code>???</code>.</li>
</ul> </ul>
<h2 id="problem-7-upc">Problem 7 UPC</h2> <h2 id="problem-7-upc">Problem 7 UPC</h2>
<div class="sourceCode" id="cb14"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb14-1" title="1">CheckDigit←{10|-⍵+.×113 1}</a></code></pre></div> <div class="sourceCode" id="cb15"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb15-1" title="1">CheckDigit←{10|-⍵+.×113 1}</a></code></pre></div>
<p>The check digit satisfies the equation <span class="math display">\[ 3 x_{1}+x_{2}+3 x_{3}+x_{4}+3 x_{5}+x_{6}+3 x_{7}+x_{8}+3 x_{9}+x_{10}+3 x_{11}+x_{12} \equiv 0 \bmod 10, \]</span> therefore, <span class="math display">\[ x_{12} \equiv -(3 x_{1}+x_{2}+3 x_{3}+x_{4}+3 x_{5}+x_{6}+3 x_{7}+x_{8}+3 x_{9}+x_{10}+3 x_{11}) \bmod 10. \]</span></p> <p>The check digit satisfies the equation <span class="math display">\[ 3 x_{1}+x_{2}+3 x_{3}+x_{4}+3 x_{5}+x_{6}+3 x_{7}+x_{8}+3 x_{9}+x_{10}+3 x_{11}+x_{12} \equiv 0 \bmod 10, \]</span> therefore, <span class="math display">\[ x_{12} \equiv -(3 x_{1}+x_{2}+3 x_{3}+x_{4}+3 x_{5}+x_{6}+3 x_{7}+x_{8}+3 x_{9}+x_{10}+3 x_{11}) \bmod 10. \]</span></p>
<p>Translated to APL, we just take the dot product between the first 11 digits of the barcode with <code>113 1</code>, negate it, and take the remainder by 10.</p> <p>Translated to APL, we just take the dot product between the first 11 digits of the barcode with <code>113 1</code>, negate it, and take the remainder by 10.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb15-1" title="1">⍝ Left and right representations of digits. Decoding</a> <div class="sourceCode" id="cb16"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb16-1" title="1">⍝ Left and right representations of digits. Decoding</a>
<a class="sourceLine" id="cb15-2" title="2">⍝ the binary representation from decimal is more</a> <a class="sourceLine" id="cb16-2" title="2">⍝ the binary representation from decimal is more</a>
<a class="sourceLine" id="cb15-3" title="3">⍝ compact than writing everything explicitly.</a> <a class="sourceLine" id="cb16-3" title="3">⍝ compact than writing everything explicitly.</a>
<a class="sourceLine" id="cb15-4" title="4">lrepr←⍉(72)13 25 19 61 35 49 47 59 55 11</a> <a class="sourceLine" id="cb16-4" title="4">lrepr←⍉(72)13 25 19 61 35 49 47 59 55 11</a>
<a class="sourceLine" id="cb15-5" title="5">rrepr←~¨lrepr</a></code></pre></div> <a class="sourceLine" id="cb16-5" title="5">rrepr←~¨lrepr</a></code></pre></div>
<p>For the second task, the first thing we need to do is save the representation of digits. To save space, I did not encode the binary representation explicitly, instead using a decimal representation that I then decode in base 2. The right representation is just the bitwise negation.</p> <p>For the second task, the first thing we need to do is save the representation of digits. To save space, I did not encode the binary representation explicitly, instead using a decimal representation that I then decode in base 2. The right representation is just the bitwise negation.</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb16-1" title="1">∇ bits←WriteUPC digits;left;right</a> <div class="sourceCode" id="cb17"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb17-1" title="1">∇ bits←WriteUPC digits;left;right</a>
<a class="sourceLine" id="cb16-2" title="2"> :If (11=≢digits)∧∧/digits∊0,9</a> <a class="sourceLine" id="cb17-2" title="2"> :If (11=≢digits)∧∧/digits∊0,9</a>
<a class="sourceLine" id="cb16-3" title="3"> left←,lrepr[1+6↑digits;]</a> <a class="sourceLine" id="cb17-3" title="3"> left←,lrepr[1+6↑digits;]</a>
<a class="sourceLine" id="cb16-4" title="4"> right←,rrepr[1+6↓digits,CheckDigit digits;]</a> <a class="sourceLine" id="cb17-4" title="4"> right←,rrepr[1+6↓digits,CheckDigit digits;]</a>
<a class="sourceLine" id="cb16-5" title="5"> bits←1 0 1,left,0 1 0 1 0,right,1 0 1</a> <a class="sourceLine" id="cb17-5" title="5"> bits←1 0 1,left,0 1 0 1 0,right,1 0 1</a>
<a class="sourceLine" id="cb16-6" title="6"> :Else</a> <a class="sourceLine" id="cb17-6" title="6"> :Else</a>
<a class="sourceLine" id="cb16-7" title="7"> bits←¯1</a> <a class="sourceLine" id="cb17-7" title="7"> bits←¯1</a>
<a class="sourceLine" id="cb16-8" title="8"> :EndIf</a> <a class="sourceLine" id="cb17-8" title="8"> :EndIf</a>
<a class="sourceLine" id="cb16-9" title="9"></a></code></pre></div> <a class="sourceLine" id="cb17-9" title="9"></a></code></pre></div>
<p>First of all, if the vector <code>digits</code> does not have exactly 11 elements, all between 0 and 9, it is an error and we return <code>¯1</code>.</p> <p>First of all, if the vector <code>digits</code> does not have exactly 11 elements, all between 0 and 9, it is an error and we return <code>¯1</code>.</p>
<p>Then, we take the first 6 digits and encode them with <code>lrepr</code>, and the last 5 digits plus the check digit encoded with <code>rrepr</code>. In each case, adding 1 is necessary because <code>⎕IO←1</code>. We return the final bit array with the required beginning, middle, and end guard patterns.</p> <p>Then, we take the first 6 digits and encode them with <code>lrepr</code>, and the last 5 digits plus the check digit encoded with <code>rrepr</code>. In each case, adding 1 is necessary because <code>⎕IO←1</code>. We return the final bit array with the required beginning, middle, and end guard patterns.</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb17-1" title="1">∇ digits←ReadUPC bits</a> <div class="sourceCode" id="cb18"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb18-1" title="1">∇ digits←ReadUPC bits</a>
<a class="sourceLine" id="cb17-2" title="2"> :If 95≠bits ⍝ incorrect number of bits</a> <a class="sourceLine" id="cb18-2" title="2"> :If 95≠bits ⍝ incorrect number of bits</a>
<a class="sourceLine" id="cb17-3" title="3"> digits←¯1</a> <a class="sourceLine" id="cb18-3" title="3"> digits←¯1</a>
<a class="sourceLine" id="cb17-4" title="4"> :Else</a> <a class="sourceLine" id="cb18-4" title="4"> :Else</a>
<a class="sourceLine" id="cb17-5" title="5"> ⍝ Test if the barcode was scanned right-to-left.</a> <a class="sourceLine" id="cb18-5" title="5"> ⍝ Test if the barcode was scanned right-to-left.</a>
<a class="sourceLine" id="cb17-6" title="6"> :If 0=2|+/bits[3+7]</a> <a class="sourceLine" id="cb18-6" title="6"> :If 0=2|+/bits[3+7]</a>
<a class="sourceLine" id="cb17-7" title="7"> bits←⌽bits</a> <a class="sourceLine" id="cb18-7" title="7"> bits←⌽bits</a>
<a class="sourceLine" id="cb17-8" title="8"> :EndIf</a> <a class="sourceLine" id="cb18-8" title="8"> :EndIf</a>
<a class="sourceLine" id="cb17-9" title="9"> digits←({¯1+lrepr⍵}¨(7/6)⊆42↑3↓bits),{¯1+rrepr⍵}¨(7/6)⊆¯42↑¯3↓bits</a> <a class="sourceLine" id="cb18-9" title="9"> digits←({¯1+lrepr⍵}¨(7/6)⊆42↑3↓bits),{¯1+rrepr⍵}¨(7/6)⊆¯42↑¯3↓bits</a>
<a class="sourceLine" id="cb17-10" title="10"> :If ~∧/digits∊0,9 ⍝ incorrect parity</a> <a class="sourceLine" id="cb18-10" title="10"> :If ~∧/digits∊0,9 ⍝ incorrect parity</a>
<a class="sourceLine" id="cb17-11" title="11"> digits←¯1</a> <a class="sourceLine" id="cb18-11" title="11"> digits←¯1</a>
<a class="sourceLine" id="cb17-12" title="12"> :ElseIf (⊃⌽digits)≠CheckDigit ¯1↓digits ⍝ incorrect check digit</a> <a class="sourceLine" id="cb18-12" title="12"> :ElseIf (⊃⌽digits)≠CheckDigit ¯1↓digits ⍝ incorrect check digit</a>
<a class="sourceLine" id="cb17-13" title="13"> digits←¯1</a> <a class="sourceLine" id="cb18-13" title="13"> digits←¯1</a>
<a class="sourceLine" id="cb17-14" title="14"> :EndIf</a> <a class="sourceLine" id="cb18-14" title="14"> :EndIf</a>
<a class="sourceLine" id="cb17-15" title="15"> :EndIf</a> <a class="sourceLine" id="cb18-15" title="15"> :EndIf</a>
<a class="sourceLine" id="cb17-16" title="16"></a></code></pre></div> <a class="sourceLine" id="cb18-16" title="16"></a></code></pre></div>
<ul> <ul>
<li>If we dont have the correct number of bits, we return <code>¯1</code>.</li> <li>If we dont have the correct number of bits, we return <code>¯1</code>.</li>
<li>We test the first digit for its parity, to determine if its actually a left representation. If its not, we reverse the bit array.</li> <li>We test the first digit for its parity, to determine if its actually a left representation. If its not, we reverse the bit array.</li>
@ -193,51 +176,53 @@
<li>Final checks for the range of the digits (i.e., if the representations could not be found in the <code>lrepr</code> and <code>rrepr</code> vectors), and for the check digit.</li> <li>Final checks for the range of the digits (i.e., if the representations could not be found in the <code>lrepr</code> and <code>rrepr</code> vectors), and for the check digit.</li>
</ul> </ul>
<h2 id="problem-8-balancing-the-scales">Problem 8 Balancing the Scales</h2> <h2 id="problem-8-balancing-the-scales">Problem 8 Balancing the Scales</h2>
<div class="sourceCode" id="cb18"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb18-1" title="1">∇ parts←Balance nums;subsets;partitions</a> <div class="sourceCode" id="cb19"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb19-1" title="1">∇ parts←Balance nums;subsets;partitions</a>
<a class="sourceLine" id="cb18-2" title="2"> ⍝ This is a brute force solution, running in</a> <a class="sourceLine" id="cb19-2" title="2"> ⍝ This is a brute force solution, running in</a>
<a class="sourceLine" id="cb18-3" title="3"> ⍝ exponential time. We generate all the possible</a> <a class="sourceLine" id="cb19-3" title="3"> ⍝ exponential time. We generate all the possible</a>
<a class="sourceLine" id="cb18-4" title="4"> ⍝ partitions, filter out those which are not</a> <a class="sourceLine" id="cb19-4" title="4"> ⍝ partitions, filter out those which are not</a>
<a class="sourceLine" id="cb18-5" title="5"> ⍝ balanced, and return the first matching one. There</a> <a class="sourceLine" id="cb19-5" title="5"> ⍝ balanced, and return the first matching one. There</a>
<a class="sourceLine" id="cb18-6" title="6"> ⍝ are more advanced approach running in</a> <a class="sourceLine" id="cb19-6" title="6"> ⍝ are more advanced approach running in</a>
<a class="sourceLine" id="cb18-7" title="7"> ⍝ pseudo-polynomial time (based on dynamic</a> <a class="sourceLine" id="cb19-7" title="7"> ⍝ pseudo-polynomial time (based on dynamic</a>
<a class="sourceLine" id="cb18-8" title="8"> ⍝ programming, see the &quot;Partition problem&quot; Wikipedia</a> <a class="sourceLine" id="cb19-8" title="8"> ⍝ programming, see the &quot;Partition problem&quot; Wikipedia</a>
<a class="sourceLine" id="cb18-9" title="9"> ⍝ page), but they are not warranted here, as the</a> <a class="sourceLine" id="cb19-9" title="9"> ⍝ page), but they are not warranted here, as the</a>
<a class="sourceLine" id="cb18-10" title="10"> ⍝ input size remains fairly small.</a> <a class="sourceLine" id="cb19-10" title="10"> ⍝ input size remains fairly small.</a>
<a class="sourceLine" id="cb18-11" title="11"></a> <a class="sourceLine" id="cb19-11" title="11"></a>
<a class="sourceLine" id="cb18-12" title="12"> ⍝ Generate all partitions of a vector of a given</a> <a class="sourceLine" id="cb19-12" title="12"> ⍝ Generate all partitions of a vector of a given</a>
<a class="sourceLine" id="cb18-13" title="13"> ⍝ size, as binary mask vectors.</a> <a class="sourceLine" id="cb19-13" title="13"> ⍝ size, as binary mask vectors.</a>
<a class="sourceLine" id="cb18-14" title="14"> subsets←{1↓2⊥⍣¯12*⍵}</a> <a class="sourceLine" id="cb19-14" title="14"> subsets←{1↓2⊥⍣¯12*⍵}</a>
<a class="sourceLine" id="cb18-15" title="15"> ⍝ Keep only the subsets whose sum is exactly</a> <a class="sourceLine" id="cb19-15" title="15"> ⍝ Keep only the subsets whose sum is exactly</a>
<a class="sourceLine" id="cb18-16" title="16"> ⍝ (+/nums)÷2.</a> <a class="sourceLine" id="cb19-16" title="16"> ⍝ (+/nums)÷2.</a>
<a class="sourceLine" id="cb18-17" title="17"> partitions←nums{((2÷⍨+/)=+.×⍵)/⍵}subsetsnums</a> <a class="sourceLine" id="cb19-17" title="17"> partitions←nums{((2÷⍨+/)=+.×⍵)/⍵}subsetsnums</a>
<a class="sourceLine" id="cb18-18" title="18"> :If 0=≢,partitions</a> <a class="sourceLine" id="cb19-18" title="18"> :If 0=≢,partitions</a>
<a class="sourceLine" id="cb18-19" title="19"> ⍝ If no partition satisfy the above</a> <a class="sourceLine" id="cb19-19" title="19"> ⍝ If no partition satisfy the above</a>
<a class="sourceLine" id="cb18-20" title="20"> ⍝ criterion, we return ⍬.</a> <a class="sourceLine" id="cb19-20" title="20"> ⍝ criterion, we return ⍬.</a>
<a class="sourceLine" id="cb18-21" title="21"> parts←⍬</a> <a class="sourceLine" id="cb19-21" title="21"> parts←⍬</a>
<a class="sourceLine" id="cb18-22" title="22"> :Else</a> <a class="sourceLine" id="cb19-22" title="22"> :Else</a>
<a class="sourceLine" id="cb18-23" title="23"> ⍝ Otherwise, we return the first possible</a> <a class="sourceLine" id="cb19-23" title="23"> ⍝ Otherwise, we return the first possible</a>
<a class="sourceLine" id="cb18-24" title="24"> ⍝ partition.</a> <a class="sourceLine" id="cb19-24" title="24"> ⍝ partition.</a>
<a class="sourceLine" id="cb18-25" title="25"> parts←nums{((⊂,(⊂~))⊃↓⍉⍵)/¨2}partitions</a> <a class="sourceLine" id="cb19-25" title="25"> parts←nums{((⊂,(⊂~))⊃↓⍉⍵)/¨2}partitions</a>
<a class="sourceLine" id="cb18-26" title="26"> :EndIf</a> <a class="sourceLine" id="cb19-26" title="26"> :EndIf</a>
<a class="sourceLine" id="cb18-27" title="27"></a></code></pre></div> <a class="sourceLine" id="cb19-27" title="27"></a></code></pre></div>
<h2 id="problem-9-upwardly-mobile">Problem 9 Upwardly Mobile</h2> <h2 id="problem-9-upwardly-mobile">Problem 9 Upwardly Mobile</h2>
<div class="sourceCode" id="cb19"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb19-1" title="1">∇ weights←Weights filename;mobile;branches;mat</a> <p>This is the only problem that I didnt complete. It required parsing the files containing the graphical representations of the trees, which was needlessly complex and, quite frankly, hard and boring with a language like APL.</p>
<a class="sourceLine" id="cb19-2" title="2"> ⍝ Put your code and comments below here</a> <p>However, the next part is interesting: once we have a matrix of coefficients representing the relationships between the weights, we can solve the system of equations. <a href="https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Functions/Matrix%20Divide.htm">Matrix Divide</a> (<code></code>) will find one solution to the system. Since the system is overdetermined, we fix <code>A=1</code> to find one possible solution. Since we want integer weights, the solution we find is smaller than the one we want, and may contain fractional weights. So we multiply everything by the <a href="https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Functions/And%20Lowest%20Common%20Multiple.htm">Lowest Common Multiple</a> (<code></code>) to get the smallest integer weights.</p>
<a class="sourceLine" id="cb19-3" title="3"></a> <div class="sourceCode" id="cb20"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb20-1" title="1">∇ weights←Weights filename;mobile;branches;mat</a>
<a class="sourceLine" id="cb19-4" title="4"> ⍝ Parse the mobile input file.</a> <a class="sourceLine" id="cb20-2" title="2"> ⍝ Put your code and comments below here</a>
<a class="sourceLine" id="cb19-5" title="5"> mobile←↑⊃⎕NGET filename 1</a> <a class="sourceLine" id="cb20-3" title="3"></a>
<a class="sourceLine" id="cb19-6" title="6"> branches←⍸mobile∊'┌┴┐'</a> <a class="sourceLine" id="cb20-4" title="4"> ⍝ Parse the mobile input file.</a>
<a class="sourceLine" id="cb19-7" title="7"> ⍝ TODO: Build the matrix of coefficients mat.</a> <a class="sourceLine" id="cb20-5" title="5"> mobile←↑⊃⎕NGET filename 1</a>
<a class="sourceLine" id="cb19-8" title="8"></a> <a class="sourceLine" id="cb20-6" title="6"> branches←⍸mobile∊'┌┴┐'</a>
<a class="sourceLine" id="cb19-9" title="9"> ⍝ Solve the system of equations (arbitrarily setting</a> <a class="sourceLine" id="cb20-7" title="7"> ⍝ TODO: Build the matrix of coefficients mat.</a>
<a class="sourceLine" id="cb19-10" title="10"> ⍝ the first variable at 1 because the system is</a> <a class="sourceLine" id="cb20-8" title="8"></a>
<a class="sourceLine" id="cb19-11" title="11"> ⍝ overdetermined), then multiply the coefficients by</a> <a class="sourceLine" id="cb20-9" title="9"> ⍝ Solve the system of equations (arbitrarily setting</a>
<a class="sourceLine" id="cb19-12" title="12"> ⍝ their least common multiple to get the smallest</a> <a class="sourceLine" id="cb20-10" title="10"> ⍝ the first variable at 1 because the system is</a>
<a class="sourceLine" id="cb19-13" title="13"> ⍝ integer weights.</a> <a class="sourceLine" id="cb20-11" title="11"> ⍝ overdetermined), then multiply the coefficients by</a>
<a class="sourceLine" id="cb19-14" title="14"> weights←((1∘,)×(∧/÷))mat[;1]⌹1↓[2]mat</a> <a class="sourceLine" id="cb20-12" title="12"> ⍝ their least common multiple to get the smallest</a>
<a class="sourceLine" id="cb19-15" title="15"></a></code></pre></div> <a class="sourceLine" id="cb20-13" title="13"> ⍝ integer weights.</a>
<div class="sourceCode" id="cb20"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb20-1" title="1"> :EndNamespace</a> <a class="sourceLine" id="cb20-14" title="14"> weights←((1∘,)×(∧/÷))mat[;1]⌹1↓[2]mat</a>
<a class="sourceLine" id="cb20-2" title="2">:EndNamespace</a></code></pre></div> <a class="sourceLine" id="cb20-15" title="15"></a></code></pre></div>
<div class="sourceCode" id="cb21"><pre class="sourceCode default"><code class="sourceCode default"><a class="sourceLine" id="cb21-1" title="1"> :EndNamespace</a>
<a class="sourceLine" id="cb21-2" title="2">:EndNamespace</a></code></pre></div>
</section> </section>
</article> </article>
]]></description> ]]></description>

View file

@ -173,34 +173,41 @@ operator (~⍣~), with an initial value of 1.
* Problem 5 -- Future and Present Value * Problem 5 -- Future and Present Value
#+begin_src default First solution: ~((1+⊢)⊥⊣)~ computes the total return for a vector of
⍝ First solution: ((1+⊢)⊥⊣) computes the total return amounts ~~ and a vector of rates ~⍵~. It is applied to every prefix
⍝ for a vector of amounts and a vector of rates subarray of amounts and rates to get all intermediate values. However,
⍝ ⍵. It is applied to every prefix subarray of amounts this has quadratic complexity.
⍝ and rates to get all intermediate values. However,
⍝ this has quadratic complexity.
⍝ rr←(,\⊣)((1+⊢)⊥⊣)¨(,\⊢)
⍝ Second solution: We want to be able to use the #+begin_src default
⍝ recurrence relation (recur) and scan through the rr←(,\⊣)((1+⊢)⊥⊣)¨(,\⊢)
⍝ vectors of amounts and rates, accumulating the total #+end_src
⍝ value at every time step. However, APL evaluation is
⍝ right-associative, so a simple Scan Second solution: We want to be able to use the recurrence relation
⍝ (recur\amounts,¨values) would not give the correct (~recur~) and scan through the vectors of amounts and rates,
⍝ result, since recur is not associative and we need accumulating the total value at every time step. However, APL
⍝ to evaluate it left-to-right. (In any case, in this evaluation is right-associative, so a simple [[https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Operators/Scan.htm][Scan]]
⍝ case, Scan would have quadratic complexity, so would (~recur\amounts,¨values~) would not give the correct result, since
⍝ not bring any benefit over the previous solution.) ~recur~ is not associative and we need to evaluate it
⍝ What we need is something akin to Haskell's scanl left-to-right. (In any case, in this case, Scan would have quadratic
⍝ function, which would evaluate left to right in O(n) complexity, so would not bring any benefit over the previous
⍝ time. This is what we do here, accumulating values solution.) What we need is something akin to Haskell's ~scanl~
⍝ from left to right. (This is inspired from function, which would evaluate left to right in $O(n)$
⍝ dfns.ascan, although heavily simplified.) time[fn:apl-scan]. This is what we do here, accumulating values from
left to right. (This is inspired from [[https://dfns.dyalog.com/c_ascan.htm][~dfns.ascan~]], although heavily
simplified.)
[fn:apl-scan] There is an interesting [[https://stackoverflow.com/a/25100675/8864368][StackOverflow answer]] explaining
the behaviour of Scan, and compares it to Haskell's ~scanl~ function.
#+begin_src default
rr←{recur←{⍵[1]+×1+⍵[2]} ⋄ 1↓⌽⊃{(⊂(⊃⍵)recur),⍵}/⌽⍺,¨⍵} rr←{recur←{⍵[1]+×1+⍵[2]} ⋄ 1↓⌽⊃{(⊂(⊃⍵)recur),⍵}/⌽⍺,¨⍵}
#+end_src #+end_src
For the second task, there is an explicit formula for cashflow
calculations, so we can just apply it.
#+begin_src default #+begin_src default
⍝ Simply apply the formula for cashflow calculations.
pv←{+/⍺÷×\1+⍵} pv←{+/⍺÷×\1+⍵}
#+end_src #+end_src
@ -358,6 +365,20 @@ with the required beginning, middle, and end guard patterns.
* Problem 9 -- Upwardly Mobile * Problem 9 -- Upwardly Mobile
This is the only problem that I didn't complete. It required parsing
the files containing the graphical representations of the trees, which
was needlessly complex and, quite frankly, hard and boring with a
language like APL.
However, the next part is interesting: once we have a matrix of
coefficients representing the relationships between the weights, we
can solve the system of equations. [[https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Functions/Matrix%20Divide.htm][Matrix Divide]] (~⌹~) will find one
solution to the system. Since the system is overdetermined, we fix
~A=1~ to find one possible solution. Since we want integer weights,
the solution we find is smaller than the one we want, and may contain
fractional weights. So we multiply everything by the [[https://help.dyalog.com/18.0/index.htm#Language/Primitive%20Functions/And%20Lowest%20Common%20Multiple.htm][Lowest Common
Multiple]] (~∧~) to get the smallest integer weights.
#+begin_src default #+begin_src default
∇ weights←Weights filename;mobile;branches;mat ∇ weights←Weights filename;mobile;branches;mat
⍝ Put your code and comments below here ⍝ Put your code and comments below here