<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2026-02-20T19:09:20+00:00</updated><id>/feed.xml</id><title type="html">lw’s blog</title><subtitle></subtitle><entry><title type="html">Counting Strings and the Goulden-Jackson Cluster Method</title><link href="/maths/combinatorics/2024/02/10/goulden-jackson.html" rel="alternate" type="text/html" title="Counting Strings and the Goulden-Jackson Cluster Method" /><published>2024-02-10T10:00:00+00:00</published><updated>2024-02-10T10:00:00+00:00</updated><id>/maths/combinatorics/2024/02/10/goulden-jackson</id><content type="html" xml:base="/maths/combinatorics/2024/02/10/goulden-jackson.html"><![CDATA[<p>
<i>A lot of this post was inspired by the papers of <a href="https://sites.math.rutgers.edu/~zeilberg/mamarim/mamarimPDF/gj.pdf">John Noonan &amp; Doron Zeilberger</a> and <a href="https://arxiv.org/pdf/1508.02793.pdf">Zhuang</a> (you can also checkoout the <a href="https://uwaterloo.ca/math/sites/default/files/uploads/documents/gjjlms1979.pdf">original paper</a>, but it's a bit harder to follow)</i>.
</p>

<div id="outline-container-org8a92afc" class="outline-2">
<h2 id="org8a92afc">Intro</h2>
<div class="outline-text-2" id="text-org8a92afc">
<p>
Suppose we want to find the number of strings of length \( n \) (sourced from some given alphabet \( V \)), which don't contain any of a given set of strings \( B \) as a substring.  Is there a fast way to do this?
</p>

<p>
The most basic case is excluding a string of a single character, in which case there are \( n^{\left|V\right| - 1} \) total strings.  But past single character strings, reasoning becomes a bit more difficult.  It's always true (and we will show) that the total number of strings follows a linear recurrence and so calculating the first few results using DP and using Berlekamp Massey will give a fast way, though we will show a way to compute a generating function directly.
</p>
</div>
</div>

<div id="outline-container-orga0d9f1b" class="outline-2">
<h2 id="orga0d9f1b">A Derivation</h2>
<div class="outline-text-2" id="text-orga0d9f1b">
<p>
Let's first define the weight \( W_R \) of some word \( w = w_1 \dots w_n  \in V^* \) of length \( n \), and \( R \in \mathbb{Z}^+  \).  We will define it using the set of variables \( x\left[w'\right] \) for all \( w' \in V^* \) of length \( R \) or less as follows:
</p>

<p>
\[
W_R(w) = \prod_{k = 1}^n \prod_{m = k}^{\min(k + R, n)} x\left[w_k \dots w_m\right]
\]
</p>

<p>
Note some factors may appear more than once, for example:
</p>

<p>
\[
W_2(HELL) = x\left[H\right]x\left[E\right]x\left[L\right]^2x\left[HE\right]x\left[EL\right]x\left[LL\right]
\]
</p>

<p>
Now, we define the generating function over \( x[w] \) where \( w \) has length \( \le R \) as:
</p>

<p>
\[
\Phi_R = \sum_{w \in V^*} W_R(w)
\]
</p>

<p>
Our strategy will be to perform substitutions on \( \Phi_R \) in order to recover the generating functions we want.  For example the mapping:
</p>

\begin{equation}
x[w] \mapsto \left\{
    \begin{array}{ll}
        0, & \text{if } w \in B \text{, e.g. w is a string we want to exclude}\\
        x, & \text{if } w \text{ is a single character string}\\
        1, & \text{otherwise}
    \end{array}\right.
\end{equation}

<p>
Will give us the generating function \( \sum a_n x^n \) where \( a_n \) is the number of words of length \( n \) not containing any \( w \in B \) as a substring.  We'll denote this generating function by \( f_B(x) \).
</p>
</div>

<div id="outline-container-org562732d" class="outline-3">
<h3 id="org562732d">Computing \( \Phi_R \)</h3>
<div class="outline-text-3" id="text-org562732d">
<p>
Let's define:
</p>

<p>
\[
Suff(w) = \{ w' \in V^* : \text{w' ends in w} \}
\]
</p>

<p>
Now, all words in \( V^* \) must either be of length less than \( R \) or end in some string of length \( R \).  Define:
</p>

<p>
\[
\Phi_{R, w} = \sum_{w' \in Suff(w)} W_R(w')
\]
</p>

<p>
Then \( \Phi_R \) is the sum of \( \Phi_{R, w} \) for all words of length \( R \) plus the sum of \( W_R(w) \) for all words of length less than \( R \).  Next, we see that our set of \( \Phi_{R, w} \) form a set of simultaneous equations:
</p>

<p>
\[
 \Phi_{R, w_1 \dots w_R} = W_R(w) + \left(\prod_{i \ge 1} x\left[w_i \dots w_r \right] \right) \sum_{c \in V} \Phi_{R, cw_1 \dots w_{R - 1}}
\]
</p>

<p>
Each equation says in essence, if a word \( w' \) ends in \( w \), then it must either be \( w \) itself, else we can drop the last character of \( w' \) and we are left another word with a suffix of length \( R \).  And so calculating \( \Phi_R \) reduces to solving these equations.  We can also glean from this that \( \Phi_R \) is rational in its variables which implies as we stated in our introduction, \( f_B(x) \) is the GF of a linear recurrence.
</p>

<p>
Note, making the substitution (1) prior to solving the system simplifies computing \( f_B(x) \).  We'll denote (1) applied to \( \Phi_{R, w} \) as \( \Phi_{R, w}(x) \).
</p>
</div>
</div>

<div id="outline-container-org39ed092" class="outline-3">
<h3 id="org39ed092">Example</h3>
<div class="outline-text-3" id="text-org39ed092">
<p>
Consider the binary string of length \( n \) not containing the substring \( 111 \).  We see (making our substitution ahead of time):
</p>

\begin{align*}
\Phi_{3, 000}(x) &= x^3 + x \left(\Phi_{3, 100}(x) + \Phi_{3, 000}(x) \right)\\
\Phi_{3, 001}(x) &= x^3 + x \left(\Phi_{3, 100}(x) + \Phi_{3, 000}(x) \right)\\
\Phi_{3, 010}(x) &= x^3 + x \left(\Phi_{3, 101}(x) + \Phi_{3, 001}(x) \right)\\
\Phi_{3, 011}(x) &= x^3 + x \left(\Phi_{3, 101}(x) + \Phi_{3, 001}(x) \right)\\
\Phi_{3, 100}(x) &= x^3 + x \left(\Phi_{3, 110}(x) + \Phi_{3, 010}(x) \right)\\
\Phi_{3, 101}(x) &= x^3 + x \left(\Phi_{3, 110}(x) + \Phi_{3, 010}(x) \right)\\
\Phi_{3, 110}(x) &= x^3 + x \left(\Phi_{3, 111}(x) + \Phi_{3, 011}(x) \right)\\
\Phi_{3, 111}(x) &= x \left(\Phi_{3, 111}(x) + \Phi_{3, 011}(x) \right)\\
\end{align*}

<p>
Solving, we find that:
</p>

\begin{align*}
\Phi_{3, 000}(x) &= \Phi_{3, 001}(x) = \Phi_{3, 010}(x) = \Phi_{3, 011}(x) = -\frac{x^5 + x^4 + x^3}{x^3 + x^2 + x - 1}\\
\Phi_{3, 100}(x) &= \Phi_{3, 101}(x) = \Phi_{3, 110}(x) = -\frac{x^4 + x^3}{x^3 + x^2 + x - 1}\\
\Phi_{3, 111}(x) &= 0
\end{align*}

<p>
And thus:
</p>

\begin{align*}
f_{\{111\}}(x) &= 1 + 2x + 4x^2 + \frac{4x^5 + 6x^4 + 7x^3}{1 - x^3 - x^2 - x}\\
     &= \frac{x^2 + x + 1}{1 - x^3 - x^2 - x}\\
\end{align*}

<p>
AKA the (shifted) <a href="https://oeis.org/A000073">Tribonacci numbers</a>.
</p>
</div>
</div>
</div>

<div id="outline-container-orgdeaf7c0" class="outline-2">
<h2 id="orgdeaf7c0">The Goulden-Jackson Cluster Method</h2>
<div class="outline-text-2" id="text-orgdeaf7c0">
<p>
For large alphabets and \( R \) the method above will result in a lot of computational effort; our system alone will be of size \( \left|V\right|^R \).  We'll introduce the Goulden-Jackson Cluster method as a means of reducing our work.
</p>

<p>
In this section we'll add a couple of restrictions on our set of bad words \( B \).  Firstly, no bad word should appear as a substring of any other bad word - the bigger bad word can be removed from \( B \) for the same end result.  Secondly, all \( b \in B \) should be of length at least two.  If this is not true, we can equivalently remove \( v \in B \) from our alphabet \( V \).
</p>
</div>

<div id="outline-container-org85c7481" class="outline-3">
<h3 id="org85c7481">Clusters</h3>
<div class="outline-text-3" id="text-org85c7481">
<p>
Given \( w \) and a set of words \( B \), we define a <b>marked word</b> as a pair \( (w, \{ (b_1, i_1), (b_2, i_2) \dots (b_l, i_l) : w_{i_k} \dots w_{i_k + length(b_k) - 1} = b_k \in B \}) \).  For example, for \( B = \{HE, EL, LO \} \), the following is a marked word:
</p>

<p>
\[
(HELLO, \{ (HE, 1), (EL, 2), (LO, 4) \})
\]
</p>

<p>
And we define a <b>cluster</b> as a nonempty marked word for which every letter in \( w \) belongs to at least one bad word, and neighbouring bad words appearing in \( w \) always overlap:
</p>

<p>
\[
(HEL, \{ (HE, 1), (EL, 2) \})
\]
</p>

<p>
Note, every subword of \( B \) in \( w \) needn't be included in the marked word, for example:
</p>

<p>
\[
(HELLO, \{ (HE, 1) \})
\]
</p>

<p>
Is a completely valid marked word.
</p>

<p>
Given \( B \), we'll define \( C_B(w) \) as the set of all clusters on \( w \) (exercise: find \( w, B \) such that this set has size greater than one), \( M_B \) as the set of all marked words, and \( C_B \) as the set of all clusters.
</p>

<p>
The concatenation of two marked words \( m_1, \ m_2 \) will be denoted \( m_1m_2 \), and defined how you would expect.
</p>
</div>
</div>

<div id="outline-container-org6c33ca7" class="outline-3">
<h3 id="org6c33ca7">A Formula</h3>
<div class="outline-text-3" id="text-org6c33ca7">
<p>
First of all, we'll give an equivalent definition of \( f_B(x) \):
</p>

<p>
\[
f_B(x) = \sum_{w \in L_B} x^{length(w)}
\]
</p>

<p>
Where \( L_B \) is the set of all words in \( V^* \), not containing any word in \( B \) as a substring.  We'll focus on calculating \( f_B(x) \) from here on, but other substitutions on \( \Phi_R \) act similarly (and are in examples).
</p>

<p>
Further define the auxiliary generating functions:
</p>

\begin{align*}
F_B(x, t) &= \sum_{(w, S) = m \in M_B} x^{length(w)} t^{\left|S\right|}\\
C_B(x, t) &= \sum_{(w, S) = c \in C_B} x^{length(w)} t^{\left|S\right|}
\end{align*}

<p>
And define \( Q(m = (w, S)) = x^{length(w)}t^{\left|S\right|} \) for brevity (it should be clear that \( Q(m_1m_2) = Q(m_1)Q(m_2) \)).  Next, we see that every marked word \( m = (w, S) \) either ends in a character not present in any bad word in \( S \), or otherwise the last character is part of the last bad word in \( S \) (which itself must be part of a cluster):
</p>

<p>
\[
 M_B = \{ e \} \cup \{ mc : m \in M_B, \ c \in C_B \} \cup \{ mv : m \in M_B, \ v \in V \}\\
\]
</p>
 \begin{align*}
\Rightarrow F_B(x, t) &= 1 + \sum_{m \in M_B} \sum_{c \in C_B} Q(mc) + \sum_{m \in M_B} \sum_{v \in V} Q(mv)\\
                      &= 1 + \sum_{m \in M_B} \sum_{c \in C_B} Q(m)Q(c) + \sum_{m \in M_B} \sum_{v \in V} Q(m)Q(v)\\
                      &= 1 + F_B(x, t)C_B(x, t) + \left|V\right|x \left(F_B(x, t)\right)\\
                      &= \frac{1}{1 - \left|V\right|x - C_B(x, t)}
 \end{align*}

<p>
Where \( e \) is the (unique) empty marked word; note also the union is disjoint.  We also wave hands a bit for \( v \in V \), these always correspond to exactly one marked word given all elements of \( B \) have length greater than one.
</p>

<p>
Thus, calculating \( F_B(x, b) \) reduces to calculating \( C_B(x, t) \).  We can group clusters according to their last bad word \( b \).  For some cluster \( c = (w, S) \), the cluster must then either consist solely of \( b \) (which implies \( w = b \)), else we can remove \( b \) along with some suffix of \( w \) to produce a smaller cluster.
</p>

<p>
For each \( b \in B \) let \( C_B[b] \) denote the set of clusters ending in \( b \), with \( C_B[b](x, t) \) defined similarly.  Then \( C_B[b](x, t) \) form a SLE, for example for \( B = \{HELE, ELEM\} \), we have:
</p>

\begin{align*}
C_B[ELEM](x, t) &= C_B[HELE](x, t)xt + C_B[HELE](x, t)x^3t + x^4t\\
C_B[HELE](x, t) &= x^4t
\end{align*}

<p>
Which results in:
</p>

\begin{align*}
C_B(x, t) &= x^4t + x^4t(xt + x^3t + 1)\\
F_B(x, t) &= \frac{1}{(1 - 26x) - (x^4t + x^4t(xt + x^3t + 1))}
\end{align*}

<p>
Now, recovering \( f_B(x) \) from \( F_B(x, t) \) is equivalent to substituting \( t = -1 \) (exercise!), resulting in:
</p>

<p>
\[
f_B(x) = \frac{1}{1 - x^7 - x^5 - 2x^4 - 26x}
\]
</p>

<p>
Sample Sage implementation:
</p>

<div class="org-src-container">
<pre class="src src-python"><span style="color: #D83441;">import</span> string


<span style="color: #D83441;">def</span> <span style="color: #D8B941;">goulden_jackson</span><span style="color: #3679D8;">(</span>bad_words, alphabet=string.ascii_uppercase<span style="color: #3679D8;">)</span>:
    <span style="color: #86e7d7;">s</span>, <span style="color: #86e7d7;">gfvs</span> = var<span style="color: #3679D8;">(</span><span style="color: #79D836;">"s"</span><span style="color: #3679D8;">)</span>, <span style="color: #3679D8;">{</span>w: var<span style="color: #8041D8;">(</span>f<span style="color: #79D836;">"G_</span>{w}<span style="color: #79D836;">"</span><span style="color: #8041D8;">)</span> <span style="color: #D83441;">for</span> w <span style="color: #D83441;">in</span> bad_words<span style="color: #3679D8;">}</span>
    <span style="color: #86e7d7;">eqns</span> = <span style="color: #3679D8;">[]</span>
    <span style="color: #D83441;">for</span> end_word <span style="color: #D83441;">in</span> bad_words:
        <span style="color: #86e7d7;">eq</span> = -s^<span style="color: #3679D8;">(</span><span style="color: #3679D8;">len</span><span style="color: #8041D8;">(</span>end_word<span style="color: #8041D8;">)</span><span style="color: #3679D8;">)</span>
        <span style="color: #D83441;">for</span> i <span style="color: #D83441;">in</span> <span style="color: #3679D8;">range</span><span style="color: #3679D8;">(</span>1, <span style="color: #3679D8;">len</span><span style="color: #8041D8;">(</span>end_word<span style="color: #8041D8;">)</span> + 1<span style="color: #3679D8;">)</span>:
            <span style="color: #86e7d7;">sub</span> = end_word<span style="color: #3679D8;">[</span>:i<span style="color: #3679D8;">]</span>
            <span style="color: #D83441;">for</span> source_word <span style="color: #D83441;">in</span> bad_words:
                <span style="color: #D83441;">if</span> source_word.endswith<span style="color: #3679D8;">(</span>sub<span style="color: #3679D8;">)</span>:
                    <span style="color: #86e7d7;">eq</span> += -s^<span style="color: #3679D8;">(</span><span style="color: #3679D8;">len</span><span style="color: #8041D8;">(</span>end_word<span style="color: #8041D8;">)</span> - <span style="color: #3679D8;">len</span><span style="color: #8041D8;">(</span>sub<span style="color: #8041D8;">)</span><span style="color: #3679D8;">)</span>*gfvs<span style="color: #3679D8;">[</span>source_word<span style="color: #3679D8;">]</span>
        eqns.append<span style="color: #3679D8;">(</span>eq == 0<span style="color: #3679D8;">)</span>

    <span style="color: #86e7d7;">soln</span> = solve<span style="color: #3679D8;">(</span>eqns, *gfvs.values<span style="color: #8041D8;">()</span><span style="color: #3679D8;">)</span>
    <span style="color: #86e7d7;">CB</span> = <span style="color: #3679D8;">sum</span><span style="color: #3679D8;">(</span>eq.right<span style="color: #8041D8;">()</span> <span style="color: #D83441;">for</span> eq <span style="color: #D83441;">in</span> <span style="color: #8041D8;">(</span>soln<span style="color: #79D836;">[</span>0<span style="color: #79D836;">]</span> <span style="color: #D83441;">if</span> <span style="color: #3679D8;">len</span><span style="color: #79D836;">(</span>bad_words<span style="color: #79D836;">)</span> &gt; 1 <span style="color: #D83441;">else</span> soln<span style="color: #8041D8;">)</span><span style="color: #3679D8;">)</span>
    <span style="color: #86e7d7;">G</span> = 1 / <span style="color: #3679D8;">(</span>1 - <span style="color: #3679D8;">len</span><span style="color: #8041D8;">(</span>alphabet<span style="color: #8041D8;">)</span>*s - CB<span style="color: #3679D8;">)</span>
    <span style="color: #D83441;">return</span> G.numerator<span style="color: #3679D8;">()</span> / G.denominator<span style="color: #3679D8;">()</span>
</pre>
</div>

<p>
Our overlap checking is not optimised, we could do better with a suffix tree when <code>bad_words</code> is large.  We could also further exploit symmetry, e.g. we must always have \( C_B[abb](x, t) = C_B[cbb](x, t) \).
</p>
</div>
</div>
</div>

<div id="outline-container-org0a1ed88" class="outline-2">
<h2 id="org0a1ed88">Examples</h2>
<div class="outline-text-2" id="text-org0a1ed88">
</div>
<div id="outline-container-org6e6100d" class="outline-3">
<h3 id="org6e6100d">PGF for the First Occurrence of a Binary String</h3>
<div class="outline-text-3" id="text-org6e6100d">
<p>
For some binary string \( w = w_1 \dots w_l \), let \( G(x) = \sum_{n = 1} p_n x^n \) where \( p_n \) is defined as the probability that the first occurrence of the string \( w \) in a random infinite binary string starts at \( n \).
</p>

<p>
Then the number of binary strings of length \( n \) where the first occurrence of \( w \) occurs at the last \( l \) characters is given by the number of binary strings of length \( n \) which <b>do</b> contain \( w \) as a substring, minus the the number of binary strings of length \( n - 1 \) which contain \( w \) as a substring:
</p>

\begin{align*}
(2^n - \left[x^n\right]f_{\{w\}}(x)) - (2^{n - 1} - \left[x^{n - 1}\right]f_{\{w\}}(x))
\end{align*}

<p>
Adjusting by \( l \) since we want the character where \( w \) starts:
</p>

\begin{align*}
p_n = \frac{(2^{n + l} - \left[x^{n + l}\right]f_{\{w\}}(x)) - (2^{n + l - 1} - \left[x^{n + l - 1}\right]f_{\{w\}}(x))}{2^{n + l - 1}}
\end{align*}

<p>
Summing and multiplying through by \( x \) to account for moving from \( 0 \) to \( 1 \) indexing:
</p>

\begin{align*}
G(x) &= 2x(1 - x)\frac{\frac{1}{1 - 2x} - f_{\{w\}}(x)}{2^lx^l}\bigg\rvert_{x=\frac{x}{2}}\\
     &= x\left(1 - \frac{x}{2}\right)\frac{\frac{1}{1 - x} - f_{\{w\}}(\frac{x}{2})}{x^l}
\end{align*}
</div>
</div>

<div id="outline-container-org0621058" class="outline-3">
<h3 id="org0621058">A Weighted Penney's Game</h3>
<div class="outline-text-3" id="text-org0621058">
<p>
Consider a game between two players which consists of a set of rounds consisting of tosses of an unfair coin (say heads = \( p \)).  Player 1 wins the round if the result is heads, and player 2 similarly for tails.  A player wins the game if they reach \( k \) consecutive round wins.  What is the probability player 1 wins?  Markov chains may be a bit cleaner for this example, but we'll show how GJ can be applied anyway!
</p>

<p>
We will first calculate the number of strings of length \( n \) containing a given string \( w_1 \), and <i>not</i> containing a second string \( w_2 \) (denote this criteria \( C_1 \)).  This corresponds to a sequence of tosses containing \( k \) \( H \)s in a row, but not \( k \) \( T \)s.  Then we see how this allows us to calculate number of strings of length \( n \) containing a given string \( w_1 \) only as a suffix, and not containing a second string \( w_2 \) (\( C_2 \)), which will give us our result.
</p>

<p>
Let \( S_n \) consist of the set of strings satisfying \( C_1 \).  Then if \( V_n \) is the set of strings of length \( n \) not containing \( w_2 \), and \( U_n \) is the set of strings of length \( n \) not containing \( w_1 \) or \( w_2 \), what is \( W_n = V_n - U_n \)?
</p>

<p>
We'll show by the classic subset argument \( W_n = S_n \).  Suppose \( w \) is a target string, e.g. it contains \( w_1 \) and not \( w_2 \).  Then \( w \in V_n \) since it doesn't contain \( w_2 \), and also \( w \not \in U_n \) since it contains \( w_1 \), which implies \( S_n \subseteq W_n \).  Similarly, if \( w \in V_n\) then \( w \) does not contain \( w_2 \), and \( w \not \in U_n \) implies \( w \) must contain \( w_1 \) since we now it doesn't contain \( w_2 \); thus \( W_n \subseteq S_n \).
</p>

<p>
Since \( U_n \subseteq V_n \) we must have:
</p>

<p>
\[
\left|S_n\right| = \left|V_n\right| - \left|U_n\right|
\]
</p>

<p>
For brevity let \( x_n = \left|X_n\right| \). Since \( v_n, u_n \) are just substring exclusion problems, we can use our methods to calculate \( s_n \).  But now how do we calculate the number of substrings of length \( n \) which don't contain \( w_2 \), and contain \( w_1 \) only as a suffix?  Like in the previous example, we may be tempted to say "subtract \( 2s_{n - 1} \) from \( s_n \) to account for adding \( H \) or \( T \) to any \( w \in S_{n - 1} \)", but this is not correct since appending \( T \) to \( w \in S_{n - 1} \) may result in a string ending in \( k\  T\)s.
</p>

<p>
Let \( S(x, y) = \sum_{n, m} s_{n, m} x^ny^m \) where \( s_{n, m} \) is the number of strings with \( n \) \( H \)s and \( m \) \( T \)s satisfying \( C_1 \) (we know this one).  Further let \( T(x, y) = \sum_{n, m} t_{n, m} x^ny^m \) where \( t_{n,m} \) is as like \( s_{n, m} \), but with added condition that the string ends in \( T \); and let Further let \( K(x, y) = \sum_{n, m} k_{n, m} x^ny^m \) where \( k_{n,m} \) is as like \( s_{n, m} \), but with added condition that the string ends in \( k - 1 \) lots of \( T \)s.  Then the following holds:
</p>

\begin{align*}
T(x, y) &= yS(x, y) - yK(x, y)\\
K(x, y) &= y^4S(x, y) - y^4T(x, y)\\
P(x, y) &= (1 - x - y)S(x, y) + K(x, y)
\end{align*}

<p>
Where \( P(x, y) \) is the generating function we want (e.g. satisfying \( C_2 \)), which results in the following:
</p>

<p>
\[
P(x, y) = \left(1 - x - y + y \frac{y^{k - 1} - y^k}{1 - y^k}\right)S(x, y)
\]
</p>

<p>
Now the probability of player 1 winning is just \( P(p, (1 - p)) \).
</p>
</div>
</div>
</div>

<div id="outline-container-orged6aaba" class="outline-2">
<h2 id="orged6aaba">Questions</h2>
<div class="outline-text-2" id="text-orged6aaba">
<ol class="org-ol">
<li>Is the following equivalent to our definition of a cluster: "Define \( (w, S) \) as a cluster if it cannot be decomposed as the concatenation (defined how you would expect) of two nonempty marked words"?</li>
<li>How may we find the generating function of the number of words of length \( n \) in which every letter must be contained in a bad word?</li>
</ol>
</div>
</div>

<div id="outline-container-org1e75b00" class="outline-2">
<h2 id="org1e75b00">Links</h2>
<div class="outline-text-2" id="text-org1e75b00">
<ul class="org-ul">
<li><a href="https://uwaterloo.ca/math/sites/default/files/uploads/documents/gjjlms1979.pdf">https://uwaterloo.ca/math/sites/default/files/uploads/documents/gjjlms1979.pdf</a> (original paper)</li>
<li><a href="https://sites.math.rutgers.edu/~zeilberg/mamarim/mamarimPDF/gj.pdf">https://sites.math.rutgers.edu/~zeilberg/mamarim/mamarimPDF/gj.pdf</a></li>
<li><a href="https://arxiv.org/pdf/1508.02793.pdf">https://arxiv.org/pdf/1508.02793.pdf</a></li>
<li><a href="https://en.wikipedia.org/wiki/Penney%27s_game">https://en.wikipedia.org/wiki/Penney%27s_game</a></li>
</ul>
</div>
</div>]]></content><author><name>Laurence Warne</name></author><category term="maths" /><category term="combinatorics" /><summary type="html"><![CDATA[Counting Strings and the Goulden-Jackson Cluster Method]]></summary></entry><entry><title type="html">Exploring Proced</title><link href="/emacs/programming/2022/12/26/exploring-proced.html" rel="alternate" type="text/html" title="Exploring Proced" /><published>2022-12-26T10:00:00+00:00</published><updated>2022-12-26T10:00:00+00:00</updated><id>/emacs/programming/2022/12/26/exploring-proced</id><content type="html" xml:base="/emacs/programming/2022/12/26/exploring-proced.html"><![CDATA[<p>
I was searching in Github in vain for a tool which would I could use as a process monitor, until I found that a tool already exists, and is in fact already shipped with Emacs: <code>proced.el</code> (written by Roland Winkler).  To start, we can kick off a Proced buffer by <code>M-x proced</code>, and by default we'll be greeted by something like:
</p>


<div id="org55c04ad" class="figure">
<p><img src="https://user-images.githubusercontent.com/17688577/210267266-d63a08b6-001d-4ebe-9680-9572034c288b.png" alt="210267266-d63a08b6-001d-4ebe-9680-9572034c288b.png" />
</p>
</div>

<p>
Within this buffer, we can perform many useful process management operations:
</p>

<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">


<colgroup>
<col  class="org-left" />

<col  class="org-left" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Key</th>
<th scope="col" class="org-left">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>k</code>, <code>x</code></td>
<td class="org-left">Send a signal to the process under point</td>
</tr>

<tr>
<td class="org-left"><code>f</code></td>
<td class="org-left">Filter processes (for example, <code>user-running</code> will only show processes owned by you which are running)</td>
</tr>

<tr>
<td class="org-left"><code>F</code></td>
<td class="org-left">Choose between a collection of preset and user-defined attributes to show for each process (called <b>formats</b>)</td>
</tr>

<tr>
<td class="org-left"><code>&lt;ENTER&gt;</code></td>
<td class="org-left">Refine the current list of processes according to attribute of the process under point (see <code>proced-grammar-alist</code> for some more information on how this works - for example pressing <code>ENTER</code> on the memory column of a given process will change it so that only processes with memory <code>&gt;=</code> to the given process will be shown)</td>
</tr>

<tr>
<td class="org-left"><code>m</code> / <code>u</code></td>
<td class="org-left">Mark/unmark the process at point, <code>M</code> / <code>U</code> mark/unmark all processes</td>
</tr>

<tr>
<td class="org-left"><code>P</code></td>
<td class="org-left">Mark a process and its parents</td>
</tr>

<tr>
<td class="org-left"><code>t</code></td>
<td class="org-left">Toggles marks</td>
</tr>

<tr>
<td class="org-left"><code>r</code></td>
<td class="org-left">Renice process at point</td>
</tr>
</tbody>
</table>

<p>
Many of these commands will use marked processes instead of the process at point if any marked processes exist.
</p>

<p>
By default, processes will by sorted by CPU usage, this can be changed using <code>s</code>, followed by one of <code>c</code> to sort by CPU, <code>m</code> to sort by memory, <code>p</code> to sort by process ID, <code>s</code> to sort by start time, <code>t</code> to sort by time (= system time + user time), <code>u</code> to sort by user, and finally <code>S</code> will prompt you to choose a sort time based on all process attributes (even if they aren't present in the current format).
</p>

<div id="outline-container-org05ff819" class="outline-2">
<h2 id="org05ff819">Customisation</h2>
<div class="outline-text-2" id="text-org05ff819">
<p>
Off the bat, by default the Proced buffer will <b>not</b> update automatically.  An update can be manually triggered via <code>g</code>, but to emulate something similar to <code>top</code> / <code>htop</code> behaviour we can set:
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span style="color: #3679D8;">(</span><span style="color: #D83441;">setq-default</span> <span style="color: #86e7d7;">proced-auto-update-flag</span> t<span style="color: #3679D8;">)</span>
<span style="color: #3679D8;">(</span><span style="color: #D83441;">setq</span> <span style="color: #86e7d7;">proced-auto-update-interval</span> 1<span style="color: #3679D8;">)</span>
</pre>
</div>

<p>
<code>proced-auto-update-flag</code> enables auto updating the Proced buffer (by default) every five seconds, and we use <code>proced-auto-update-interval</code> to shorten this to every second.  We need <code>setq-default</code> for the first of these rather than <code>setq</code> since <code>proced-auto-update-flag</code> is a <a href="https://stackoverflow.com/questions/18172728/the-difference-between-setq-and-setq-default-in-emacs-lisp">buffer-local variable</a> (we can make use of this by calling <code>proced-toggle-auto-update</code> within a Proced buffer which will toggle auto-update without changing the global value of <code>proced-auto-update-flag</code>).  I'm also not a fan of the default formats, but it's easy to define one yourself and set this as the default:
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span style="color: #3679D8;">(</span><span style="color: #8041D8;">add-to-list</span>
 '<span style="color: #86e7d7;">proced-format-alist</span>
 '<span style="color: #8041D8;">(</span>custom user pid ppid sess tree pcpu pmem rss start time state <span style="color: #79D836;">(</span>args comm<span style="color: #79D836;">)</span><span style="color: #8041D8;">)</span><span style="color: #3679D8;">)</span>
<span style="color: #3679D8;">(</span><span style="color: #D83441;">setq-default</span> <span style="color: #86e7d7;">proced-format</span> 'custom<span style="color: #3679D8;">)</span>
</pre>
</div>
<p>
The <code>car</code> of the value you're adding is the name of the new format, and the other symbols are values which appear in <code>list-system-processes</code> (for more information see <code>proced-format-alist</code>).  <code>list-system-processes</code> also gives a nice rundown on the meaning of each attribute.  You can also add your own custom attributes, here's a great example I found in <a href="https://github.com/legoscia/dotemacs/blob/master/dotemacs.org#proced-erlang-magic">legoscia's Emacs config</a>.
</p>

<p>
Something else you may notice is that moving down a row also sets the column you're in to <code>args</code>, personally I find this annoying, but you can turn this off:
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span style="color: #3679D8;">(</span><span style="color: #D83441;">setq</span> <span style="color: #86e7d7;">proced-goal-attribute</span> nil<span style="color: #3679D8;">)</span>
</pre>
</div>

<p>
The final cherry on top is that from Emacs 29 onwards, you can enable colouring for various attributes:
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span style="color: #3679D8;">(</span><span style="color: #D83441;">setq</span> proced-enable-color-flag t<span style="color: #3679D8;">)</span>
</pre>
</div>

<p>
Which, using our new default format, leaves us with:
</p>


<div id="org9d5c3ea" class="figure">
<p><img src="https://user-images.githubusercontent.com/17688577/212047844-7531d1be-6920-45ef-b7b5-6b3cdb03c7a2.png" alt="212047844-7531d1be-6920-45ef-b7b5-6b3cdb03c7a2.png" />
</p>
</div>

<p>
Full customisation (using <code>use-package</code>'s <code>:custom</code> to handle the vagaries of global and buffer-local variable customisation, thanks to u/deaddyfreddy from reddit for this)
</p>
<div class="org-src-container">
<pre class="src src-elisp"><span style="color: #3679D8;">(</span><span style="color: #D83441;">use-package</span> <span style="color: #8041D8;">proced</span>
  <span style="color: #86e7d7;">:ensure</span> nil
  <span style="color: #86e7d7;">:commands</span> proced
  <span style="color: #86e7d7;">:bind</span> <span style="color: #8041D8;">(</span><span style="color: #79D836;">(</span><span style="color: #79D836;">"C-M-p"</span> . proced<span style="color: #79D836;">)</span><span style="color: #8041D8;">)</span>
  <span style="color: #86e7d7;">:custom</span>
  <span style="color: #8041D8;">(</span>proced-auto-update-flag t<span style="color: #8041D8;">)</span>
  <span style="color: #8041D8;">(</span>proced-goal-attribute nil<span style="color: #8041D8;">)</span>
  <span style="color: #8041D8;">(</span>proced-show-remote-processes t<span style="color: #8041D8;">)</span>
  <span style="color: #8041D8;">(</span>proced-enable-color-flag t<span style="color: #8041D8;">)</span>
  <span style="color: #8041D8;">(</span><span style="color: #8041D8;">proced-format</span> 'custom<span style="color: #8041D8;">)</span>
  <span style="color: #86e7d7;">:config</span>
  <span style="color: #8041D8;">(</span><span style="color: #8041D8;">add-to-list</span>
   '<span style="color: #86e7d7;">proced-format-alist</span>
   '<span style="color: #79D836;">(</span>custom user pid ppid sess tree pcpu pmem rss start time state <span style="color: #AB11D8;">(</span>args comm<span style="color: #AB11D8;">)</span><span style="color: #79D836;">)</span><span style="color: #8041D8;">)</span><span style="color: #3679D8;">)</span>
</pre>
</div>
</div>
</div>

<div id="outline-container-org490cb89" class="outline-2">
<h2 id="org490cb89">Rolling Your Own Formatting for Attributes</h2>
<div class="outline-text-2" id="text-org490cb89">
<p>
<code>proced-grammar-alist</code> opens the door for a lot of control over how attributes are shown in Proced buffers.  The documentation goes into a lot of detail, but I'll provide a quick example here to give an idea.
</p>

<p>
Suppose our goal is to set the colour of Java executables in the <code>args</code> column to that strange orangey-brown colour that everyone seems to associate with Java.  We can start by first defining our format function:
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span style="color: #3679D8;">(</span><span style="color: #D83441;">defun</span> <span style="color: #D8B941;">my-format-java-args</span> <span style="color: #8041D8;">(</span>args<span style="color: #8041D8;">)</span>
  <span style="color: #8041D8;">(</span><span style="color: #D83441;">pcase-let*</span> <span style="color: #79D836;">(</span><span style="color: #AB11D8;">(</span>base <span style="color: #2D9574;">(</span><span style="color: #8041D8;">proced-format-args</span> args<span style="color: #2D9574;">)</span><span style="color: #AB11D8;">)</span>
               <span style="color: #AB11D8;">(</span>`<span style="color: #2D9574;">(</span>,exe . ,rest<span style="color: #2D9574;">)</span> <span style="color: #2D9574;">(</span><span style="color: #8041D8;">split-string</span> base<span style="color: #2D9574;">)</span><span style="color: #AB11D8;">)</span>
               <span style="color: #AB11D8;">(</span>exe-prop
                <span style="color: #2D9574;">(</span><span style="color: #D83441;">if</span> <span style="color: #3679D8;">(</span><span style="color: #8041D8;">string=</span> exe <span style="color: #79D836;">"java"</span><span style="color: #3679D8;">)</span>
                    <span style="color: #3679D8;">(</span><span style="color: #8041D8;">propertize</span> exe 'font-lock-face '<span style="color: #8041D8;">(</span><span style="color: #79D836;">(</span>t <span style="color: #AB11D8;">(</span><span style="color: #3679D8;">:foreground</span> <span style="color: #79D836;">"#f89820"</span><span style="color: #AB11D8;">)</span><span style="color: #79D836;">)</span><span style="color: #8041D8;">)</span><span style="color: #3679D8;">)</span>
                  exe<span style="color: #2D9574;">)</span><span style="color: #AB11D8;">)</span><span style="color: #79D836;">)</span>
    <span style="color: #79D836;">(</span><span style="color: #8041D8;">mapconcat</span> #'identity <span style="color: #AB11D8;">(</span><span style="color: #8041D8;">cons</span> exe-prop rest<span style="color: #AB11D8;">)</span> <span style="color: #79D836;">" "</span><span style="color: #79D836;">)</span><span style="color: #8041D8;">)</span><span style="color: #3679D8;">)</span>
</pre>
</div>

<p>
Now, we just need to tell <code>proced-grammar-alist</code> to use this function for the <code>args</code> attribute:
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span style="color: #3679D8;">(</span><span style="color: #D83441;">setf</span> <span style="color: #8041D8;">(</span><span style="color: #8041D8;">alist-get</span> 'args <span style="color: #86e7d7;">proced-grammar-alist</span><span style="color: #8041D8;">)</span>
      '<span style="color: #8041D8;">(</span><span style="color: #79D836;">"Args"</span>               <span style="color: #767676; font-style: italic;">; </span><span style="color: #767676; font-style: italic;">name of the column</span>
        my-format-java-args  <span style="color: #767676; font-style: italic;">; </span><span style="color: #767676; font-style: italic;">format function</span>
        left                 <span style="color: #767676; font-style: italic;">; </span><span style="color: #767676; font-style: italic;">alignment within column</span>
        proced-string-lessp  <span style="color: #767676; font-style: italic;">; </span><span style="color: #767676; font-style: italic;">defines the sort method (ascending)</span>
        nil                  <span style="color: #767676; font-style: italic;">; </span><span style="color: #767676; font-style: italic;">non-nil reverses sort order</span>
       <span style="color: #79D836;">(</span>args pid<span style="color: #79D836;">)</span>            <span style="color: #767676; font-style: italic;">; </span><span style="color: #767676; font-style: italic;">sort scheme</span>
       <span style="color: #79D836;">(</span>nil t nil<span style="color: #79D836;">)</span><span style="color: #8041D8;">)</span><span style="color: #3679D8;">)</span>         <span style="color: #767676; font-style: italic;">; </span><span style="color: #767676; font-style: italic;">refiner for custom refinement logic - see proced-refine</span>
</pre>
</div>

<p>
And you should see the results straight away:
</p>


<div id="orgff31136" class="figure">
<p><img src="https://user-images.githubusercontent.com/17688577/212048912-991ba757-f3e3-4abb-b386-0b90fc5dc901.png" alt="212048912-991ba757-f3e3-4abb-b386-0b90fc5dc901.png" /> 
</p>
</div>
</div>
</div>

<div id="outline-container-org83302c7" class="outline-2">
<h2 id="org83302c7">Remote Systems</h2>
<div class="outline-text-2" id="text-org83302c7">
<p>
Thanks to Michael Albinus, from Emacs 29 onwards invoking <code>proced</code> when <code>default-directory</code> is remote (for example, your current buffer points to a remote file) and <code>proced-show-remote-processes</code> is non-nil, will prompt Proced to show processes from the remote system instead of your local machine, which can make <code>proced</code> a lot more useful when working with <code>tramp</code>.
</p>
</div>
</div>

<div id="outline-container-org2869ff4" class="outline-2">
<h2 id="org2869ff4">See Also</h2>
<div class="outline-text-2" id="text-org2869ff4">
<ul class="org-ul">
<li><a href="https://www.masteringemacs.org/article/displaying-interacting-processes-proced">https://www.masteringemacs.org/article/displaying-interacting-processes-proced</a></li>
<li><a href="https://emacsredux.com/blog/2013/05/02/manage-processes-with-proced/">https://emacsredux.com/blog/2013/05/02/manage-processes-with-proced/</a></li>
</ul>
</div>
</div>]]></content><author><name>Laurence Warne</name></author><category term="emacs" /><category term="programming" /><summary type="html"><![CDATA[Exploring Proced]]></summary></entry><entry><title type="html">Ponder This Nov 22</title><link href="/maths/programming/2022/11/09/ponder-this-nov-22.html" rel="alternate" type="text/html" title="Ponder This Nov 22" /><published>2022-11-09T10:18:00+00:00</published><updated>2022-11-09T10:18:00+00:00</updated><id>/maths/programming/2022/11/09/ponder-this-nov-22</id><content type="html" xml:base="/maths/programming/2022/11/09/ponder-this-nov-22.html"><![CDATA[<div id="outline-container-orgebe4493" class="outline-2">
<h2 id="orgebe4493">The Question</h2>
<div class="outline-text-2" id="text-orgebe4493">
<p>
You can view the question here: <a href="https://research.ibm.com/haifa/ponderthis/challenges/November2022.html">https://research.ibm.com/haifa/ponderthis/challenges/November2022.html</a>.  It asks suppose we are given a draw of \( b \) socks with \( a \) comfortable items and the remaining \( b - a \) uncomfortable, what is the smallest value of \( b \) of at least 100 digits such that the probability of drawing two comfortable socks is exactly \( \frac{1}{974170} \)?
</p>
</div>
</div>

<div id="outline-container-org78e957f" class="outline-2">
<h2 id="org78e957f">Solution</h2>
<div class="outline-text-2" id="text-org78e957f">
<p>
For brevity, lets let \( k = 974170 \).  Now, the first part of question is equivalent to finding \( a,b \) such that:
\[
\frac{a}{b} * \frac{a - 1}{b - 1} = \frac{1}{k} 
\]
</p>

<p>
Multiplying out:
</p>

\begin{align*}
ka(a - 1) = b(b - 1) &\iff b^2 + (-b) + (-ka^2 + ka) = 0 \\
                     &\iff b = \frac{1 \pm \sqrt{1 + 4ka^2 -4ka}}{2}
\end{align*}

<p>
Where the second step just follows from the quadratic formula.  Clearly, if \( b \) is positive we can disregard the negative sign, and note that radicand is always odd, hence if it's square, then the root will also be odd and thus the numerator even, and hence \( b \) will be a whole number.
</p>

<p>
So our problem reduces to finding \( a \) values such that the expression \( 1 + 4ka^2 -4ka \) is itself square.  Now suppose \( 1 + 4ka^2 - 4ka = x^2 \) for some \( x \).  Then we can complete and square and rearrange to obtain:
</p>

\begin{align}
x^2 - k(2a - 1)^2 = -k + 1
\end{align}

<p>
Which is of the form of a <a href="https://en.wikipedia.org/wiki/Pell%27s_equation#Generalized_Pell's_equation">generalised Pell's equation</a> (letting \( y = 2a - 1, -k + 1 = N \)), which are quite tricky to solve.  Solutions generalised Pell's equations can be grouped into seperate classes, and the fundamental solutions of each class can then be used to generate all solutions for that particular class.  A fast method for solving these equations can be found <a href="http://web.archive.org/web/20120309013237/http://www.jpr2718.org/pell.pdf">here</a>.
</p>

<p>
We find the fundamental solutions for each class in our case to be:
</p>

<p>
\[
(x, y) \in \{(-229969, 233), (-1, 1), (1, 1), (229969, 233), (974169, 987)\}
\]
</p>

<p>
In order to determine all solutions for each class, consider \( r = x + y\sqrt{974170} \).  We see \( (x, y) \) is a solution to (1) iff \( M(r) := r \bar{r}  = (x + y\sqrt{974170})(x - y\sqrt{974170}) = -974169 \).  Now it is straighforward to show \( M: \mathbb{Z}[\sqrt{974170}] \to \mathbb{Z} \) is multiplicative, and so if we can find an \( r' = a + b\sqrt{974170} \in \mathbb{Z}[\sqrt{974170}] \) such that \( M(r') = 1 \) we can generate an infinite stream of solutions.
</p>

<p>
However, \( M(r') = 1 \iff (a + b\sqrt{974170})(a - b\sqrt{974170}) = 1 \iff a^2 -974170b^2 = 1 \) which is just a regular Pell's equation!  This has fundamental solution \( (a, b) = (1948339, 1974) \) and so we can formulate new solutions to (1) using \( x_n + y_n\sqrt{974170} = (1948339 + 1974\sqrt{974170})^n(x + y\sqrt{974170}) \) and it turns out all solutions are of this form when \( (x, y) \) are the fundamental solutions to (1).
</p>

<p>
\( (x_n, y_n) \) grow exponentially in relation to \( n \), so computing \( y \) as to make \( b \) of at least 100 digits can be done extremely quickly.  The smallest such \( (x, y) \) are:
</p>

\begin{align*}
x &= 358215987739182004690086378181625469679573777244481977174053689999534311804982937308746736066326142199 \\
y &= 362933945169315204684486536809603899412307756418124003349633249331941231267453010603520849884063709
\end{align*}

<p>
Finding the corresponding \( a \) and \( b \) is left to the reader (:
</p>
</div>
</div>]]></content><author><name>Laurence Warne</name></author><category term="maths" /><category term="programming" /><summary type="html"><![CDATA[A solution to the November 2022 IBM Ponder This]]></summary></entry><entry><title type="html">Text Wrap Hacks for Markdown</title><link href="/programming/python/2022/06/18/text-wrap-hacks.html" rel="alternate" type="text/html" title="Text Wrap Hacks for Markdown" /><published>2022-06-18T00:00:00+00:00</published><updated>2022-06-18T00:00:00+00:00</updated><id>/programming/python/2022/06/18/text-wrap-hacks</id><content type="html" xml:base="/programming/python/2022/06/18/text-wrap-hacks.html"><![CDATA[<div id="outline-container-org2ae7b5f" class="outline-2">
<h2 id="org2ae7b5f">The <code>textwrap</code> Module</h2>
<div class="outline-text-2" id="text-org2ae7b5f">
<p>
The Python standard library ships a neat little module for line wrapping text:
</p>

<div class="org-src-container">
<pre class="src src-python">&gt;&gt;&gt; <span style="color: #D83441;">import</span> textwrap
&gt;&gt;&gt; textwrap.wrap<span style="color: #3679D8;">(</span><span style="color: #79D836;">"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</span><span style="color: #3679D8;">)</span>
<span style="color: #3679D8;">[</span><span style="color: #79D836;">'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do'</span>,
 <span style="color: #79D836;">'eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad'</span>,
 <span style="color: #79D836;">'minim veniam, quis nostrud exercitation ullamco laboris nisi ut'</span>,
 <span style="color: #79D836;">'aliquip ex ea commodo consequat. Duis aute irure dolor in'</span>,
 <span style="color: #79D836;">'reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla'</span>,
 <span style="color: #79D836;">'pariatur. Excepteur sint occaecat cupidatat non proident, sunt in'</span>,
 <span style="color: #79D836;">'culpa qui officia deserunt mollit anim id est laborum.'</span><span style="color: #3679D8;">]</span>
</pre>
</div>

<p>
And it's pretty extensible too, you can subclass <code>textwrap.TextWrapper</code> to control how words are split amongst <a href="https://docs.python.org/3/library/textwrap.html">other things</a>.
</p>
</div>
</div>

<div id="outline-container-orgafeb395" class="outline-2">
<h2 id="orgafeb395">Hacking: Markdown</h2>
<div class="outline-text-2" id="text-orgafeb395">
<p>
This is nice and all, but what if I was wrapping some kind of markdown, specifically <a href="https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax">Github Markdown</a>?  The biggest problem here would be wrapping links, whose character length far exceeds the length of the link description (which would be rendered):
</p>

<div class="org-src-container">
<pre class="src src-python">&gt;&gt;&gt; <span style="color: #D83441;">import</span> textwrap
&gt;&gt;&gt; textwrap.wrap<span style="color: #3679D8;">(</span><span style="color: #79D836;">"`avy` is a GNU Emacs package for jumping to visible text using a char-based decision tree.  See also [ace-jump-mode](https://github.com/winterTTr/ace-jump-mode) and [vim-easymotion](https://github.com/Lokaltog/vim-easymotion) - `avy` uses the same idea."</span><span style="color: #3679D8;">)</span>
<span style="color: #3679D8;">[</span><span style="color: #79D836;">'`avy` is a GNU Emacs package for jumping to visible text using a'</span>,
 <span style="color: #79D836;">'char-based decision tree.  See also'</span>,
 <span style="color: #79D836;">'[ace-jump-mode](https://github.com/winterTTr/ace-jump-mode) and'</span>,
 <span style="color: #79D836;">'[vim-easymotion](https://github.com/Lokaltog/vim-easymotion) - `avy`'</span>,
 <span style="color: #79D836;">'uses the same idea.'</span><span style="color: #3679D8;">]</span>
</pre>
</div>

<p>
But if we were to use this, it would be rendered as:
</p>

<pre class="example">
`avy` is a GNU Emacs package for jumping to visible text using a
char-based decision tree.  See also
ace-jump-mode and
vim-easymotion - `avy`
uses the same idea.
</pre>

<p>
Essentially, we want the length of Github links to be taken from the length of their descriptions alone.  It isn't immediately clear how this can be achieved looking at <code>textwrap.TextWrapper</code>, but digging a little deeper in the <code>textwrap</code> module source code we see:
</p>

<div class="org-src-container">
<pre class="src src-python"><span style="color: #D83441;">while</span> <span style="color: #86e7d7;">chunks</span>:
    l = <span style="color: #3679D8;">len</span><span style="color: #3679D8;">(</span>chunks<span style="color: #8041D8;">[</span>-1<span style="color: #8041D8;">]</span><span style="color: #3679D8;">)</span>

    <span style="color: #767676; font-style: italic;"># </span><span style="color: #767676; font-style: italic;">Can at least squeeze this chunk onto the current line.</span>
    <span style="color: #D83441;">if</span> cur_len + l &lt;= <span style="color: #86e7d7;">width</span>:
        cur_line.append<span style="color: #3679D8;">(</span>chunks.pop<span style="color: #8041D8;">()</span><span style="color: #3679D8;">)</span>
        cur_len += l

    <span style="color: #767676; font-style: italic;"># </span><span style="color: #767676; font-style: italic;">Nope, this line is full.</span>
    <span style="color: #D83441;">else</span>:
        <span style="color: #D83441;">break</span>
</pre>
</div>

<p>
And further, <code>chunks</code> is set from a <code>TextWrapper._split</code> call.  This suggests if we create our own <code>TextWrapper</code> subclass and identify links in our <code>_split</code> method, we can set the length by somehow jumbling link strings so they return the length of their description rather than their true length on a <code>len</code> call.  We can do this by subclassing <code>str</code>:
</p>

<div class="org-src-container">
<pre class="src src-python"><span style="color: #D83441;">import</span> re
<span style="color: #D83441;">from</span> textwrap <span style="color: #D83441;">import</span> TextWrapper


<span style="color: #D83441;">class</span> <span style="color: #3679D8;">MarkdownLink</span><span style="color: #3679D8;">(</span><span style="color: #3679D8;">str</span><span style="color: #3679D8;">)</span>:
    <span style="color: #D83441;">def</span> <span style="color: #D8B941;">__new__</span><span style="color: #3679D8;">(</span>cls, url, description<span style="color: #3679D8;">)</span>:
        <span style="color: #86e7d7;">obj</span> = <span style="color: #3679D8;">str</span>.__new__<span style="color: #3679D8;">(</span>cls, f<span style="color: #79D836;">"[</span>{description}<span style="color: #79D836;">](</span>{url}<span style="color: #79D836;">)"</span><span style="color: #3679D8;">)</span>
        obj.<span style="color: #86e7d7;">url</span> = url
        obj.<span style="color: #86e7d7;">description</span> = description
        <span style="color: #D83441;">return</span> obj

    <span style="color: #D83441;">def</span> <span style="color: #D8B941;">__len__</span><span style="color: #3679D8;">(</span><span style="color: #D83441;">self</span><span style="color: #3679D8;">)</span>:
        <span style="color: #D83441;">return</span> <span style="color: #3679D8;">len</span><span style="color: #3679D8;">(</span><span style="color: #D83441;">self</span>.description<span style="color: #3679D8;">)</span>


<span style="color: #D83441;">class</span> <span style="color: #3679D8;">MarkdownTextWrapper</span><span style="color: #3679D8;">(</span>TextWrapper<span style="color: #3679D8;">)</span>:
    <span style="color: #9ae168; font-style: italic;">"""A TextWrapper which handles markdown links."""</span>

    <span style="color: #86e7d7;">LINK_REGEX</span> = re.<span style="color: #3679D8;">compile</span><span style="color: #3679D8;">(</span>r<span style="color: #79D836;">"(\[.*?\]\(\S+\))"</span><span style="color: #3679D8;">)</span>
    <span style="color: #86e7d7;">LINK_PARTS_REGEX</span> = re.<span style="color: #3679D8;">compile</span><span style="color: #3679D8;">(</span>r<span style="color: #79D836;">"^\[(.*?)\]\((\S+)\)$"</span><span style="color: #3679D8;">)</span>

    <span style="color: #D83441;">def</span> <span style="color: #D8B941;">_split</span><span style="color: #3679D8;">(</span><span style="color: #D83441;">self</span>, text<span style="color: #3679D8;">)</span>:
        <span style="color: #86e7d7;">split</span> = re.split<span style="color: #3679D8;">(</span><span style="color: #D83441;">self</span>.LINK_REGEX, text<span style="color: #3679D8;">)</span>
        <span style="color: #86e7d7;">chunks</span>: List<span style="color: #3679D8;">[</span><span style="color: #3679D8;">str</span><span style="color: #3679D8;">]</span> = <span style="color: #3679D8;">[]</span>
        <span style="color: #D83441;">for</span> item <span style="color: #D83441;">in</span> <span style="color: #86e7d7;">split</span>:
            match = re.match<span style="color: #3679D8;">(</span><span style="color: #D83441;">self</span>.LINK_PARTS_REGEX, item<span style="color: #3679D8;">)</span>
            <span style="color: #D83441;">if</span> match:
                chunks.append<span style="color: #3679D8;">(</span>MarkdownLink<span style="color: #8041D8;">(</span>match.group<span style="color: #79D836;">(</span>2<span style="color: #79D836;">)</span>, match.group<span style="color: #79D836;">(</span>1<span style="color: #79D836;">)</span><span style="color: #8041D8;">)</span><span style="color: #3679D8;">)</span>
            <span style="color: #D83441;">else</span>:
                chunks.extend<span style="color: #3679D8;">(</span><span style="color: #3679D8;">super</span><span style="color: #8041D8;">()</span>._split<span style="color: #8041D8;">(</span>item<span style="color: #8041D8;">)</span><span style="color: #3679D8;">)</span>
        <span style="color: #D83441;">return</span> chunks
</pre>
</div>

<p>
Lets use it:
</p>

<div class="org-src-container">
<pre class="src src-python">&gt;&gt;&gt; <span style="color: #D83441;">import</span> textwrap
&gt;&gt;&gt; textwrap.wrap<span style="color: #3679D8;">(</span><span style="color: #79D836;">"`avy` is a GNU Emacs package for jumping to visible text using a char-based decision tree.  See also [ace-jump-mode](https://github.com/winterTTr/ace-jump-mode) and [vim-easymotion](https://github.com/Lokaltog/vim-easymotion) - `avy` uses the same idea."</span><span style="color: #3679D8;">)</span>
<span style="color: #3679D8;">[</span><span style="color: #79D836;">'`avy` is a GNU Emacs package for jumping to visible text using a char-based'</span>,
 <span style="color: #79D836;">'decision tree.  See also [ace-jump-mode](https://github.com/winterTTr/ace-jump-mode) and [vim-easymotion](https://github.com/Lokaltog/vim-easymotion) - `avy` uses the same'</span>,
<span style="color: #79D836;">'idea.'</span><span style="color: #3679D8;">]</span>
</pre>
</div>

<p>
Which renders as:
</p>

<pre class="example">
`avy` is a GNU Emacs package for jumping to visible text using a char-based
decision tree.  See also ace-jump-mode and vim-easymotion - `avy` uses the same
idea
</pre>

<p>
Nice! 👌
</p>
</div>
</div>]]></content><author><name>Laurence Warne</name></author><category term="programming" /><category term="python" /><summary type="html"><![CDATA[textwrap for markdown]]></summary></entry><entry><title type="html">Row-Spanning for ImageMagick montage, Sort of…</title><link href="/programming/2021/11/05/image-magick-montage-row-span.html" rel="alternate" type="text/html" title="Row-Spanning for ImageMagick montage, Sort of…" /><published>2021-11-05T14:24:00+00:00</published><updated>2021-11-05T14:24:00+00:00</updated><id>/programming/2021/11/05/image-magick-montage-row-span</id><content type="html" xml:base="/programming/2021/11/05/image-magick-montage-row-span.html"><![CDATA[<div id="outline-container-orgfea0df2" class="outline-2">
<h2 id="orgfea0df2">Montage</h2>
<div class="outline-text-2" id="text-orgfea0df2">
<p>
ImageMagick ships the <code>montage</code> command as a way of creating <b>composite</b> images.  For example (stolen from their site):
</p>


<div id="org38dbd97" class="figure">
<p><img src="https://imagemagick.org/image/frame.jpg" alt="frame.jpg" />
</p>
</div>

<p>
For <a href="https://github.com/LaurenceWarne/libro-finito/">libro-finito</a>, I'm interested in stitching several images together on a grid to try and replicate something like the image  Goodreads' year in books:
</p>


<div id="org97933a3" class="figure">
<p><img src="https://inti-revista.org/img/10cc471f86b043291bdecc2996dc2254.jpg" alt="10cc471f86b043291bdecc2996dc2254.jpg" />
</p>
</div>

<p>
Essentially books tiled together with some appearing larger according to some heuristic (rating would be a good choice!).
</p>
</div>
</div>

<div id="outline-container-org400e464" class="outline-2">
<h2 id="org400e464">Let's Start 🔨</h2>
<div class="outline-text-2" id="text-org400e464">
<p>
Given some images, if we want three images per row, something like:
</p>

<div class="org-src-container">
<pre class="src src-bash">montage -geometry +0+0 starship-troopers.jpeg a-spell-for-a-chameleon-l.jpeg the-caves-of-steel.jpeg the-count-of-monte-cristo.jpeg a-wizard-of-earthsea.jpeg tmp.jpeg
</pre>
</div>

<p>
Gives us:
</p>


<div id="org98a4f6b" class="figure">
<p><img src="https://user-images.githubusercontent.com/17688577/140427293-5f587a19-5afb-47e6-aabe-d13e098249bc.jpeg" alt="140427293-5f587a19-5afb-47e6-aabe-d13e098249bc.jpeg" />
</p>
</div>

<p>
ImageMagick has done its best to set the distance between images as zero, but this appears to have lead to inconsitency of column sizes.  Generally different sized images aren't going to work too nicely with one another.
</p>

<p>
In the example above I've made it so that larger images are 4x the size of the smaller ones (ie 2x width and 2x height).  A "nice" tiling is possible if we make all of the images the same size&#x2026; by splitting up the larger images into quarters.
</p>

<p>
We split larger images into four smaller ones, taking care that we always align the bottom two images on the same columns below the top two images.  I've offloaded this tiling specification of our "split" images to a <a href="https://github.com/LaurenceWarne/libro-finito/blob/master/bin/montage.py">script</a>.
</p>

<p>
But does this work?  Yes!
</p>


<div id="org66bcdca" class="figure">
<p><img src="https://raw.githubusercontent.com/LaurenceWarne/libro-finito/26e0044595fa933ecade67fce2add7cf1ec9c374/bin/montage.png" alt="montage.png" />
</p>
</div>
</div>
</div>]]></content><author><name>Laurence Warne</name></author><category term="programming" /><summary type="html"><![CDATA[ImageMagick montage]]></summary></entry><entry><title type="html">Integral Polynomial Interpolation</title><link href="/maths/2021/07/30/integral-polynomial-interpolation.html" rel="alternate" type="text/html" title="Integral Polynomial Interpolation" /><published>2021-07-30T19:48:00+00:00</published><updated>2021-07-30T19:48:00+00:00</updated><id>/maths/2021/07/30/integral-polynomial-interpolation</id><content type="html" xml:base="/maths/2021/07/30/integral-polynomial-interpolation.html"><![CDATA[<div id="outline-container-org506285e" class="outline-2">
<h2 id="org506285e">Question</h2>
<div class="outline-text-2" id="text-org506285e">
<p>
It's well known that given some sequence points of \( n \) points \( (x_i, y_i) \) with \( x_i \) distinct, that there exists a unique polynomial \( P \) of degree \( d < n \) such that for all \( i \), \( P(x_i) = y_i \), the <b>Lagrange Interpolating Polynomial</b>.
</p>

<p>
If all \( x_i, y_i \) are integers, we can glean from the <a href="https://en.wikipedia.org/wiki/Lagrange_polynomial">Lagrange Interpolation Formula</a> that it is guaranteed that \( P(X) \in \mathbb{Q}[X] \).  But does there exist a polynomial \( F(X) \) of higher degree satisfying the same property (\( F(x_i) = y_i \)) such that its coefficients are all integers?
</p>
</div>
</div>

<div id="outline-container-orge5ed3e5" class="outline-2">
<h2 id="orge5ed3e5">Solution</h2>
<div class="outline-text-2" id="text-orge5ed3e5">
<p>
Strangely enough there exists no such polynomial if \( P \) has some non integer coefficient.  Proof is thanks to <a href="https://mathoverflow.net/questions/169083/lagrange-interpolation-and-integer-polynomials">this</a> mathoverflow answer:
</p>

<p>
First define \( D(X) \in \mathbb{Z}[X] \) as \( D(X) =  \prod (X - x_i) \), ie the monic polynomial of degree \( n \) whose roots are the \( x \) coordinates of our points.
</p>

<p>
Next, suppose \( F(X) \) has coefficients all integers.  Since \( D(X) \) is monic we can write:
</p>

<p>
\[
F(X) = D(X)Q(X) + R(X)
\]
</p>

<p>
Where \( Q(X), R(X) \in \mathbb{Z}[X] \), and also \( deg(R(X)) < deg(D(X)) \).
</p>

<p>
Now we must have \( F(x_i) = R(x_i) \), but this implies that \( R(X) \) is the Lagrange interpolating polynomial since it has degree less than \( n \) and satisfies \( R(x_i) = P(x_i) \) for all \( i \).  Thus we can re-write:
</p>

<p>
\[
P(X) = F(X) - D(X)Q(X)
\]
</p>

<p>
Which implies that \( P(X) \in \mathbb{Z}[X] \) since that latter set is closed under addition and multiplication.
</p>
</div>
</div>]]></content><author><name>Laurence Warne</name></author><category term="Maths" /><category term="Question" /><summary type="html"><![CDATA[A question on polynomial interpolation]]></summary></entry><entry><title type="html">An Accumulated Sequence</title><link href="/maths%20combinatorics/2020/04/08/accumulated-sequence.html" rel="alternate" type="text/html" title="An Accumulated Sequence" /><published>2020-04-08T00:00:00+00:00</published><updated>2020-04-08T00:00:00+00:00</updated><id>/maths%20combinatorics/2020/04/08/accumulated-sequence</id><content type="html" xml:base="/maths%20combinatorics/2020/04/08/accumulated-sequence.html"><![CDATA[<div id="outline-container-org8b89d7d" class="outline-2">
<h2 id="org8b89d7d">Question</h2>
<div class="outline-text-2" id="text-org8b89d7d">
<p>
Define the sequence \( (a_n)_n = 1 \). Now consider taking the first 4 elements of
the sequence:
\[ 1 \ \ 1 \ \ 1 \ \ 1 \]
Now throw away the first element to get:
\[ 1 \ \ 1 \ \ 1 \]
Set the new second element to the sum of the first element and old second element,
and similarly set the new third element to the sum of the old third element and
new second element and so on to get:
\[ 1 \ \ 2 \ \ 3 \]
If we then apply the same process to this new sequence we get:
\[ 2 \ \ 5 \]
And so if we apply the process until we are left with one element we get 5. This can
easily be generalised to starting with n lots of ones, and applying the process n - 1
times to be left with one element, \( f(n) \). Can we find a closed form for \( f(n) \)?
</p>
</div>
</div>

<div id="outline-container-org7121598" class="outline-2">
<h2 id="org7121598">Recursions</h2>
<div class="outline-text-2" id="text-org7121598">
<p>
If we stack each pass of the process on top of one another, we obtain the diagram:
</p>

\begin{array}{|c|c|c|c|}
\hline
  1 & 1 & 1 & 1 \\\hline
    & 1 & 2 & 3 \\\hline
    &   & 2 & 5 \\\hline
    &   &   & 5 \\\hline
\end{array}

<p>
Note starting with more 1s in the first row simply extends the diagram to the right
and does not change the triangle left of the new column. It can be seen from
our definition above, each element in the diagram (above the first row) is equal to
the sum of the element above it and the element immediately to the left of it, save
for the elements we are interested in, which are equal solely to the elements above
them.
</p>

<p>
However, we can incorporate these elements into
the relation by making the following edit to our diagram:
</p>

\begin{array}{|c|c|c|c|}
  \hline
  1 & 1 & 1 & 1 \\\hline
  0 & 1 & 2 & 3 \\\hline
    & 0 & 2 & 5 \\\hline
    &   & 0 & 5 \\\hline
\end{array}

<p>
Let \( n \) span accross the columns, and \( k \) span accross the rows (like Pascal's triangle), ie so that \( f(3, 1) = 3 \) and consider the diagram again. We obtain:
</p>

<p>
Formally:
</p>

\begin{align*}
&f(n, 0)       = 1                          &\forall n     \\
&f(n, k=n + 1) = 0                          &\forall n > 0 \\
&f(n, k)       = f(n - 1, k) + f(n, k - 1)  &1 \le k \le n \\
\end{align*}

<p>
We can reason from the above recursion that each number in the diagram can be written
as some sum of the leftmost nonzero elements on each row, added to some sum of
elements in the first row (\( k = 0 \)), which also happen to be equal to the leftmost
element of the first row (\( f(0, 0) = 1 \)). These are the numbers we are interested
in. ie:
</p>

<p>
\[ f(n) = \sum_{r=1}^{n-1} A_r * f(r) \]
</p>

<p>
Where \( A_r \) is some constant to be determined. Now we can consider how each 
\( f(r) \) contributes to \( f(n) \) via the following diagram:
</p>

\begin{array}{|c|c|c|c|}
  \hline
  f(r) \rightarrow & f(r) + B_1 \rightarrow \downarrow & f(r) + C_1 \rightarrow \downarrow & f(r) + D_1 \rightarrow \downarrow  \\\hline
  0  & f(r + 1) & f(r) + B_2 \rightarrow & 2f(r) + C_2 \rightarrow \downarrow \\\hline
  & 0 & f(r + 2) & 2f(r) + B_3 \rightarrow \\\hline
\end{array}

<p>
Where \( C, B, D \) are constants consisting of sums of other \( f(s) \). Note we
do not arrow constributions to \( f(r+1) \) as these are the source of the
contributions and we need to keep these "atomic". We can observe from this diagram
that:
</p>

<p>
\[ A_r = f(n - r) \]
</p>

<p>
This also works for the base row, as we can just rewrite 1 = f(1) (thus all 
constants are 0), and hence:
</p>

<p>
\[ f(n) = \sum_{r=1}^{n - 1} f(r)*f(n - r) \]
</p>
</div>
</div>

<div id="outline-container-org7bbfe4f" class="outline-2">
<h2 id="org7bbfe4f">To Closed Form</h2>
<div class="outline-text-2" id="text-org7bbfe4f">
<p>
First of all lets let \( f(0) = 0 \) which will make things a little simpler, now
let's define the generating function:
</p>

<p>
\[ F(x) = \sum_{n=0} f(n)x^n \]
</p>

<p>
And now sum our recursion over all \( n \) where it's valid (\( n > 2 \)):
</p>

<p>
\[ \sum_{n=2} f(n)x^n = \sum_{n=2}\sum_{r=0}^{n} f(r)*f(n - r)x^n \]
</p>

<p>
Simplifying the LHS and using the definition of multiplication in the ring of 
formal power series on the RHS:
</p>

<p>
\[ F(x) - x = \sum_{n=0}f(n)x^n \sum_{n=0}f(n)x^n \]
</p>

<p>
Simplifying and collecting terms:
</p>

<p>
\[ F(x)^2 - F(x) + x = 0 \]
</p>

<p>
Quadratic formula (neglecting + sign, this will give us \( f(0) = 1 \) ):
</p>

<p>
\[ F(x) = \frac{1 - \sqrt{1 - 4x}}{2} \]
</p>

<p>
Attempt to extract \( x \) coefficients using binomial expansion:
</p>

<p>
\[ F(x) = \frac{-1}{2}\left( \frac{\frac{1}{2}}{1!}\left(-4x\right) + \frac{\frac{1}{2}\frac{-1}{2}}{2!}\left(-4x\right)^2 + ... \right) \]
</p>

<p>
After some arduous simplifications, we find the general \( x \) coefficient is given
by:
</p>

<p>
\[ \frac{(2n - 2)!}{n! * (n - 1)!} \]
</p>

<p>
Which is the (n - 1)th Catalan number, ie \( f(n) = C_{n - 1} \).
</p>
</div>
</div>]]></content><author><name>Laurence Warne</name></author><category term="Maths Combinatorics" /><category term="Question" /><summary type="html"><![CDATA[A question on the all ones sequence]]></summary></entry><entry><title type="html">Splitting Up a Number</title><link href="/maths%20optimisation/2020/04/06/maximal_number_partition.html" rel="alternate" type="text/html" title="Splitting Up a Number" /><published>2020-04-06T00:00:00+00:00</published><updated>2020-04-06T00:00:00+00:00</updated><id>/maths%20optimisation/2020/04/06/maximal_number_partition</id><content type="html" xml:base="/maths%20optimisation/2020/04/06/maximal_number_partition.html"><![CDATA[<div id="outline-container-org2418bc2" class="outline-2">
<h2 id="org2418bc2">Question</h2>
<div class="outline-text-2" id="text-org2418bc2">
<p>
Given some \( n \in N \), how can I partition \( n \) into other natural numbers 
which sum n such that the total product of all elements in the partition is 
maxmimised?
</p>
</div>
</div>

<div id="outline-container-org4de19d5" class="outline-2">
<h2 id="org4de19d5">Solution</h2>
<div class="outline-text-2" id="text-org4de19d5">
<p>
Consider some valid partition \( P \) of \( n \):
</p>

<p>
\[ P = (a_1, a_2, ...) \]
</p>

<p>
And let:
</p>

<p>
\[ f(P) = a_1 * a_2 * ... \]
</p>

<p>
Note that all natural numbers &gt; 1 can be written as a sum of 2s and 3s exclusively, ie
</p>

<p>
\[ a_1 = 2 + 2 + ... + 3 + 3 + ... \]
</p>

<p>
What we will now show is that taking all the elements in the partition and breaking
them up into 2s and 3s, will give a better partition.<br />
</p>

<p>
<b>Lemma 1:</b>
The product of some sequence of 2s and 3s is always greater or equal to the 
corresponding sum with equality holding iff the sequence is (2, 2), (2,) or (3,). 
Proof: 
</p>

<p>
\[ 2 * 2 = 2 + 2 \]
\[ 3 * 2 > 3 + 2 \]
\[ 3 * 3 > 3 + 3 \]
</p>

<p>
Hence if:
</p>

<p>
\[ P_a_1 = (2, 2, ..., 3, 3, ...) \]
</p>

<p>
Then
</p>

<p>
\[ ka_1 \leq k f(P_a_1) \ \forall k \in R+ \]
</p>

<p>
With equality holding iff \( a_1 < 5 \). From this it is clear that the optimal
partition will consist of some sequence of 2s and 3s. For most numbers however 
there are many ways to split a number into sums of 2s and 3s. We will now show how
to find the optimal partition. Note:
</p>

<p>
\[ 3 + 3 = 2 + 2 + 2 \]
\[ 3 * 3 > 2 * 2 * 2 \]
</p>

<p>
This implies that there will be no more than two lots of 2s in the optimal partition. 
If \( 3 | n \) then the optimal partition is three lots of \( \frac{n}{3} \). If we
consider trying to improve upon this partition by breaking up a 3 into a 2 and a 1
, we decrease the product. And if we try to improve upon the partition by combining
3s we decrease the product by lemma 1. Therefore the partition is optimal in this case.
Now consider:
</p>

<p>
\[ 1) n \equiv 1 \ mod \ 3 \Rightarrow \exists k \in N \ s.t \ n = 3k + 1 \]
\[ 2) n \equiv 2 \ mod \ 3 \Rightarrow \exists k \in N \ s.t \ n = 3k + 2 \]
</p>

<p>
For 1) we can choose from (1, 3 k times) or (2, 2, 3 (k - 1)) times. Given 2 * 2 &gt; 3 * 1
we can identify the latter case as optimal. <br />
</p>

<p>
For 2) the only option containing no ones or less than three 2s is (2, 3 k times).
</p>
</div>
</div>


<div id="outline-container-orgba028ad" class="outline-2">
<h2 id="orgba028ad">Question Extension</h2>
<div class="outline-text-2" id="text-orgba028ad">
<p>
What if \( n \in R+ \) and the elements of the partition can be any positive real?
</p>
</div>
</div>

<div id="outline-container-orgbbcba64" class="outline-2">
<h2 id="orgbbcba64">Extension Solution</h2>
<div class="outline-text-2" id="text-orgbbcba64">
<p>
Unlike the previous solution we will use some calculus. Consider:
</p>

<p>
\[ (x, x), \ (x - a, x + a) \]
</p>

<p>
Where \( x, a \in R^+ , \ x > a \). <br />
</p>

<p>
Note the two tuples have the same sum but:
</p>

<p>
\[ x^2 > x^2 - a^2 \]
</p>

<p>
From this it is apparent that all elements of the optimal partition must be the same
number. Let this number be \( k_n \) Consider the function:
</p>

<p>
\[ f(x) = x^\frac{n}{x} \]
</p>

<p>
For some constant \( n \). Then \( k_n \) is the maximum of this function with the
added restriction that \( x | n \). <br />
</p>

<p>
Rewrite \( f(x) \):
</p>

<p>
\[ f(x) = e^\frac{n\ln{x}}{x} \]
</p>

<p>
We find the stationary point by differentiating and equating to 0:
</p>

<p>
\[ \left(\frac{n}{x^2} - \frac{n\ln{x}}{x^2}\right) e^\frac{n\ln{x}}{x} = 0 \]
</p>

<p>
\( f(x) \not = 0 \ \forall x \in R \) hence we have:
</p>

<p>
\[ \left(\frac{n}{x^2} - \frac{n\ln{x}}{x^2}\right) = 0 \]
</p>

<p>
\[ \Rightarrow  ln{x} = 1 \]
</p>

<p>
\[ \Rightarrow  x = e \]
</p>

<p>
Hence the sole stationary point of the function occurs at \( x = e \) and is
independent of \( n \). If we note that:
</p>

<p>
\[ \lim_{x \to 0+}f(x) = \lim_{x \to \infty}f(x) = 0 \]
</p>

<p>
Then we can identify the stationary point as a global maximum of the function, and
reason that our desired k<sub>n</sub> lies somewhere around \( e \).
</p>
</div>
</div>]]></content><author><name>Laurence Warne</name></author><category term="Maths Optimisation" /><category term="Question" /><summary type="html"><![CDATA[A question on number partitions.]]></summary></entry></feed>