Skip to content

Commit

Permalink
tama editorial changes
Browse files Browse the repository at this point in the history
  • Loading branch information
kcvajgf committed Oct 30, 2023
1 parent cc27f7a commit e65c947
Show file tree
Hide file tree
Showing 13 changed files with 121 additions and 34 deletions.
2 changes: 2 additions & 0 deletions 2023/reve/ever/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ <h2 id="solution-writeup">Solution Writeup</h2>
<strong>Problem Statement:</strong> Kevin Atienza, Cisco Ortega<br />
<strong>Test Data Preparation:</strong> Kevin Atienza<br />
<strong>Solution Writeup:</strong> Kevin Atienza</p>
<div class="editorial-section">
<p>Sorry, I won’t decrypt the editorial for you. 😉 But...I made a simple web page to help you solve cryptograms! See <a href="https://kcvajgf.github.io/cryptogram/" class="uri">https://kcvajgf.github.io/cryptogram/</a></p>
</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>

Expand Down
3 changes: 2 additions & 1 deletion 2023/reve/ever/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
**Solution Writeup:** Kevin Atienza


<div class="editorial-section">
Sorry, I won&rsquo;t decrypt the editorial for you. &#128521; But...I made a simple web page to help you solve cryptograms! See [https://kcvajgf.github.io/cryptogram/](https://kcvajgf.github.io/cryptogram/)

</div>
8 changes: 7 additions & 1 deletion 2023/tama-practice/mod-pow/eulerthm.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
<title></title>
<title>Euler’s Theorem</title>
<style type="text/css">code{white-space: pre;}</style>
<script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_CHTML-full" type="text/javascript"></script>

Expand All @@ -30,11 +30,16 @@

<!--
<div id="header">
<h1 class="title">Euler’s Theorem</h1>
</div>
-->


<div class="editorial container">
<h1 id="eulers-theorem">Euler’s Theorem</h1>
<div class="editorial-section">
<p>This page contains a proof of <a href="https://en.wikipedia.org/wiki/Euler%27s_theorem"><strong>Euler's theorem</strong></a>:<a href="#fn1" class="footnoteRef" id="fnref1"><sup>1</sup></a></p>
<div class="theorem">
<p><strong>Euler’s Theorem</strong>. Let <span class="math inline">\(a\)</span> and <span class="math inline">\(m\)</span> be coprime integers. Then, <span class="math display">\[a^{\varphi(m)} \equiv 1 \pmod m\]</span> where <span class="math inline">\(\varphi\)</span> is Euler’s Totient function, and <span class="math inline">\(\varphi(m)\)</span> counts the number of non-negative integers less than <span class="math inline">\(m\)</span> which are coprime to it.</p>
Expand All @@ -59,6 +64,7 @@
</ul>
<p>Thus, we can partition <span class="math inline">\(S\)</span> using this equivalence relation <span class="math inline">\(\sim\)</span>. Note that every equivalence class contains exactly <span class="math inline">\(k\)</span> elements, because for every <span class="math inline">\(v \in S\)</span>, the following numbers (mod <span class="math inline">\(m\)</span>) are all the elements equivalent to <span class="math inline">\(v\)</span> via <span class="math inline">\(\sim\)</span>: <span class="math display">\[\{v, va, va^2, \ldots, va^{k-1} \}.\]</span> Note that further powers of <span class="math inline">\(a\)</span> don't yield new elements because <span class="math inline">\(a^k \equiv 1 \pmod{m}\)</span>, and these are all distinct because if <span class="math inline">\(va^i \equiv va^j \pmod{m}\)</span> for <span class="math inline">\(0 \le i &lt; j &lt; k\)</span>, then multiplying by the inverses of <span class="math inline">\(v\)</span> and <span class="math inline">\(a^i\)</span> (which are coprime to <span class="math inline">\(m\)</span>) yields <span class="math inline">\(a^{j-i} \equiv 1 \pmod{m}\)</span> with <span class="math inline">\(j - i &lt; k\)</span>, contradicting the fact that <span class="math inline">\(k\)</span> is the smallest one such that <span class="math inline">\(a^k \equiv 1 \pmod{m}\)</span>.</p>
<p>Therefore, all the <span class="math inline">\(\phi(m)\)</span> elements of <span class="math inline">\(S\)</span> are partitioned into equivalence classes, each of which is of size <span class="math inline">\(k\)</span>. So if there are <span class="math inline">\(c\)</span> equivalence classes, we have the equation <span class="math display">\[\phi(m) = kc\]</span> (i.e., <span class="math inline">\(k\)</span> divides <span class="math inline">\(\phi(m)\)</span>), and therefore we have <span class="math display">\[a^{\phi(m)} = a^{kc} = (a^k)^c \equiv 1^c = 1 \pmod{m}.\]</span> </details></p>
</div>
<div class="footnotes">
<hr />
<ol>
Expand Down
7 changes: 7 additions & 0 deletions 2023/tama-practice/mod-pow/eulerthm.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
% Euler&rsquo;s Theorem


# Euler&rsquo;s Theorem

<div class="editorial-section">
This page contains a proof of [**Euler's theorem**](https://en.wikipedia.org/wiki/Euler%27s_theorem):[^1]


Expand Down Expand Up @@ -77,6 +83,7 @@ $$\phi(m) = kc$$
$$a^{\phi(m)} = a^{kc} = (a^k)^c \equiv 1^c = 1 \pmod{m}.$$
</details>

</div>

[^1]: also known as the **Fermat-Euler theorem** because Fermat proved a
special case (with $m$ prime), and also because Euler already has so
Expand Down
2 changes: 2 additions & 0 deletions 2023/tama/ever/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ <h2 id="solution-writeup">Solution Writeup</h2>
<strong>Problem Statement:</strong> Kevin Atienza, Cisco Ortega<br />
<strong>Test Data Preparation:</strong> Kevin Atienza<br />
<strong>Solution Writeup:</strong> Kevin Atienza</p>
<div class="editorial-section">
<p>Sorry, I won’t decrypt the editorial for you. 😉 But...I made a simple web page to help you solve cryptograms! See <a href="https://kcvajgf.github.io/cryptogram/" class="uri">https://kcvajgf.github.io/cryptogram/</a></p>
</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>

Expand Down
3 changes: 2 additions & 1 deletion 2023/tama/ever/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
**Solution Writeup:** Kevin Atienza


<div class="editorial-section">
Sorry, I won&rsquo;t decrypt the editorial for you. &#128521; But...I made a simple web page to help you solve cryptograms! See [https://kcvajgf.github.io/cryptogram/](https://kcvajgf.github.io/cryptogram/)

</div>
2 changes: 1 addition & 1 deletion 2023/tama/griddy/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ <h2 id="solution-writeup">Solution Writeup</h2>
<p><details class="editorial-section"><summary class="h2">Subtask 1</summary></p>
<p><strong>Disclaimer:</strong> The first solution we’ll describe is the simplest one conceptually, but is not necessarily the easiest one to implement. Nonetheless, we’re covering it anyway because the ideas we’ll encounter will be useful for later.</p>
<h3 id="a-straightforward-approach">A straightforward approach</h3>
<p>Anyway, the most straightforward solution would be to <em>just do it</em> as stated, a.k.a., <em>brute force</em>: enumerate all <span class="math inline">\(2^{rc}\)</span> grids, compute <span class="math inline">\(B(G)\)</span> for each of them, and then sum up all these <span class="math inline">\(B(G)^3\)</span>. Enumerating grids is relatively straightforward with backtracking, and for the first subtask, <span class="math inline">\(2^{rc} = 2^{25} = 33554432\)</span> which is quite manageable for a computer. The only missing ingredient to fully implement this solution is being able to compute <span class="math inline">\(B(G)\)</span> for a given grid <span class="math inline">\(G\)</span> in the first place.</p>
<p>Anyway, the most straightforward solution would be to <em>just do it</em> as stated, a.k.a., <em>brute force</em>: enumerate all <span class="math inline">\(2^{rc}\)</span> grids, compute <span class="math inline">\(B(G)\)</span> for each of them, and then sum up all these <span class="math inline">\(B(G)^3\)</span>. Enumerating grids is relatively straightforward with backtracking, and for the first subtask, <span class="math inline">\(2^{rc} = 2^{25} = 33554432\)</span> which is quite manageable for a computer. The only missing ingredient to fully implement this solution is being able to compute <span class="math inline">\(B(G)\)</span> for a given grid <span class="math inline">\(G\)</span>.</p>
<h3 id="computing-bg">Computing <span class="math inline">\(B(G)\)</span></h3>
<p>We are given a grid with <span class="math inline">\(r\)</span> rows and <span class="math inline">\(c\)</span> columns, and we want to make it <em>based</em>, i.e., change it so that every row and every column has an even number of cringe memes.</p>
<p>Let’s convert a cool meme (🗿) into a <span class="math inline">\(0\)</span> and a cringe meme (😬) into a <span class="math inline">\(1\)</span>, so the condition translates to: the sum of every row and every column is even.</p>
Expand Down
2 changes: 1 addition & 1 deletion 2023/tama/griddy/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

### A straightforward approach

Anyway, the most straightforward solution would be to *just do it* as stated, a.k.a., *brute force*: enumerate all $2^{rc}$ grids, compute $B(G)$ for each of them, and then sum up all these $B(G)^3$. Enumerating grids is relatively straightforward with backtracking, and for the first subtask, $2^{rc} = 2^{25} = 33554432$ which is quite manageable for a computer. The only missing ingredient to fully implement this solution is being able to compute $B(G)$ for a given grid $G$ in the first place.
Anyway, the most straightforward solution would be to *just do it* as stated, a.k.a., *brute force*: enumerate all $2^{rc}$ grids, compute $B(G)$ for each of them, and then sum up all these $B(G)^3$. Enumerating grids is relatively straightforward with backtracking, and for the first subtask, $2^{rc} = 2^{25} = 33554432$ which is quite manageable for a computer. The only missing ingredient to fully implement this solution is being able to compute $B(G)$ for a given grid $G$.


### Computing $B(G)$
Expand Down
46 changes: 36 additions & 10 deletions 2023/tama/lucas/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ <h2 id="solution-writeup">Solution Writeup</h2>
<strong>Testing:</strong> Paolo Estavillo, Vincent dela Cruz<br />
<strong>Statement:</strong> Cisco Ortega<br />
<strong>Test Data Preparation:</strong> Kevin Atienza<br />
<strong>Solution Writeup:</strong> Cisco Ortega</p>
<strong>Solution Writeup:</strong> Cisco Ortega, Kevin Atienza</p>
<p><details class="editorial-section"><summary class="h2">Subtasks 1 &amp; 2</summary></p>
<p><strong>Just do it.</strong> With <span class="math inline">\(n = 10^6 + 2023 &lt; 10^8\)</span>, we have more than enough time to simply generate all of the first <span class="math inline">\(n\)</span> Lucas numbers and add up the squares of the even ones. Also, <span class="math inline">\(n=30\)</span> is small enough that you could do the first subtask by hand, if you feel compelled.</p>
<p>There is one caveat. Lucas numbers grow exponentially quickly, so we need to make sure to take mods at all intermediate steps, i.e., compute the Lucas numbers modulo <span class="math inline">\(m\)</span> as we go along, instead of only at the end:</p>
Expand Down Expand Up @@ -137,28 +137,54 @@ <h3 id="pen-and-paper-insight">Pen-and-paper insight</h3>
2, 1, 3, 4, 7, 1, 8, 9, 7, 6, 3, 9, \textbf{2, 1}, 3, 4, 7, 1, 8, 9, 7, 6, 3, 9, ...
\]</span> Note that when we see <span class="math inline">\((2, 1)\)</span> again, it’s the signal that the sequence devolves to just repeating the chunk <span class="math inline">\(2, 1, 3, 4, 7, 1, 8, 9, 7, 6, 3, 9\)</span> from that point on.</p>
<p>In fact, whenever this sequence start to repeat itself, the period <em>always</em> begins with <span class="math inline">\(2\)</span> and <span class="math inline">\(1\)</span>. Can you see why? <strong>Hint:</strong> If you know two consecutive terms in the Lucas number, you can determine the next term, but you can also determine the <em>previous</em> term.</p>
<p>If this period is sufficiently small (spoiler: it <em>is</em> for Subtask 3 :D), then you can abuse it to compute things like sums (of even squares) even for very large <span class="math inline">\(n\)</span>, because the period behaves predictably.</p>
<p>If this period is sufficiently small (spoiler: it <em>is</em> for Subtask 3 😀), then you can abuse it to compute things like sums (of even squares) even for very large <span class="math inline">\(n\)</span>, because the period behaves predictably.</p>
<p></details></p>
<p><details class="editorial-section"><summary class="h2">Subtasks 4 &amp; 5</summary></p>
<p>Without spoiling the full details, I will remark that there are two primary approaches that you could use in solving these subtasks. One is <strong>far more painful</strong> than the other.</p>
<h3 id="painful-number-theory">Painful number theory</h3>
<p><details class="editorial-section"><summary class="h2">Subtask 4</summary></p>
<p>We can push our solution for Subtask 3 further using a couple extra insights. First, there’s actually a reasonable bound for the periodicity of the solution modulo a prime <span class="math inline">\(p\)</span>:</p>
<div class="theorem">
<p><strong>Theorem:</strong> If <span class="math inline">\(p\)</span> is prime, then the answers mod <span class="math inline">\(p\)</span> are periodic with period at most <span class="math inline">\(3(p+1)\)</span>.</p>
</div>
The proof of this needs a certain amount of number theory, so we’ll skip it. (Feel free to ask in Discord if you want to hear more about it.) Without too much difficulty, it can be extended to prime power moduli as follows:
<div class="theorem">
<p><strong>Theorem:</strong> If <span class="math inline">\(p\)</span> is prime and <span class="math inline">\(k &gt; 0\)</span>, then the answers mod <span class="math inline">\(p^k\)</span> are periodic with period at most <span class="math inline">\(3(p+1)p^{k-1}\)</span>.</p>
</div>
<p>We can even extend this further to general moduli using the Chinese remainder theorem. However, we won’t state the corresponding theorem here, because we can also just use the Chinese remainder theorem in a different way. If the modulus <span class="math inline">\(m\)</span> has factorization <span class="math display">\[m = p_1^{k_1}\cdot p_2^{k_2} \cdots p_r^{k_r},\]</span> then we can simply solve the problem for each prime power modulus <span class="math inline">\(p_i^{k_i}\)</span>, and then stitch them together using the Chinese remainder theorem to get the full answer modulo <span class="math inline">\(m\)</span>.</p>
<p>So to solve the problem, we factor the modulus into prime powers, and if the prime power factors are small enough, we can simply find the exact period directly, say by generating the sequence until it repeats! Once we have the exact period, computing the answer for any <span class="math inline">\(n\)</span> becomes pretty fast.</p>
<p>The running time of this solution is more-or-less proportional to the largest prime power factor of <span class="math inline">\(m\)</span>, which it turns out is small enough for Subtask 4. However, the modulus for Subtask 5 has a large prime factor, making this solution infeasible.</p>
<div class="caution">
<p><strong>Warning:</strong> When looking for the period, make sure that the sequence really cycles! It’s actually surprisingly tricky to figure out when the sequence repeats. Generally, you want to check that a long-enough contiguous subsequence repeats—it’s not enough for it to repeat a single number. It turns out that in our problem, checking that <span class="math inline">\(4\)</span> consecutive numbers repeat is enough (but that’s tricky to prove!). Alternatively, you could use a stronger version of the theorem which says that the period <em>divides</em> either <span class="math inline">\(3(p-1)p^k\)</span> or <span class="math inline">\(3(p+1)p^k\)</span> (which one it is depends on <span class="math inline">\(p^2 \bmod 5\)</span>), though that’s also tricky to prove.</p>
</div>
<p></details></p>
<p><details class="editorial-section"><summary class="h2">Subtask 5</summary></p>
<p>Without spoiling the full details, I will remark that there are two primary approaches that you could use in solving this subtask. One is more painful than the other.</p>
<h3 id="number-theory-painful">Number theory (painful 😐)</h3>
<p>In one solution, you use the explicit formula of the Lucas numbers, expand it out, then use a sum-of-geometric-series formula.</p>
<p>The problem with this is, of course, the <span class="math inline">\(\sqrt{5}\)</span> in the explicit formula of the Lucas numbers. To handle this, you have to:</p>
<ul>
<li>First, factorize the modulus into prime powers.</li>
<li>First, factorize the modulus into prime powers.
<ul>
<li>The small moduli can be brute-forced with period bashing, as in Subtask 3.</li>
<li>The large moduli are, conveniently, all prime, so we can proceed!</li>
<li>Now, for each prime <span class="math inline">\(p\)</span> in the factorization, use Euler’s criterion to determine if <span class="math inline">\(x^2 \equiv 5 \pmod{p}\)</span> has a solution.</li>
</ul></li>
<li>Now, for each prime <span class="math inline">\(p\)</span> in the factorization, use Euler’s criterion to determine if <span class="math inline">\(x^2 \equiv 5 \pmod{p}\)</span> has a solution.
<ul>
<li>If yes, solve for it using a modulo square root algorithm like Cipolla’s.</li>
<li>If no, instead start working in the field extension with numbers of the form <span class="math inline">\(a + b \sqrt{5}\)</span> (kind of like what we do with the complex numbers)</li>
<li>If no, instead start working in the field extension with numbers of the form <span class="math inline">\(a + b \sqrt{5}\)</span> (kind of like what we do with the complex numbers).<a href="#fn1" class="footnoteRef" id="fnref1"><sup>1</sup></a></li>
<li>Then, proceed with the rest of your solution.</li>
<li>Finally, use the Chinese Remainder Theorem to stitch all your answers together into the true answer modulo <span class="math inline">\(m\)</span>.</li>
</ul></li>
<li>Finally, use the Chinese remainder theorem to stitch all your answers together into the true answer modulo <span class="math inline">\(m\)</span>.</li>
</ul>
<p>If you want to code this, go ahead! It’s a fun series of standard (still a bit obscure?) algorithms in number theory. If not, you can try considering another solution...</p>
<h3 id="using-matrices-to-solve-linear-recurrence-neat-very-nice">Using matrices to solve linear recurrence (neat, very nice)</h3>
<h3 id="using-matrices-to-solve-linear-recurrence-neat-very-nice">Using matrices to solve linear recurrence (neat, very nice 🙂)</h3>
<p>Using standard matrix techniques, you should be able to compute the sum of even Lucas numbers.</p>
<p>Does this technique also work for Lucas <strong>squares</strong>? It could work if the squares of Lucas numbers also form a linear recurrence relation... do they?</p>
<p></details></p>
<div class="footnotes">
<hr />
<ol>
<li id="fn1"><p>Adjoining a <span class="math inline">\(\sqrt{5}\)</span> sometimes still works even if <span class="math inline">\(5\)</span> already has a square root modulo <span class="math inline">\(p\)</span>. You’re simply working on a <em>ring</em> extension instead of a field extension. This works if you’re somehow lucky that you don’t divide by some problematic numbers (called “zero divisors”).<a href="#fnref1"></a></p></li>
</ol>
</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
Expand Down
Loading

0 comments on commit e65c947

Please sign in to comment.