tag:blogger.com,1999:blog-66541305268293073802023-11-16T13:40:14.106+00:00Arthur's BlogMathematics, Computer Algorithms, Fell Walking Write-upsArthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.comBlogger33125tag:blogger.com,1999:blog-6654130526829307380.post-86714287390933725142022-12-23T10:56:00.008+00:002023-01-11T16:37:21.000+00:00Factorisation<div class="separator"></div><p> After looking at some dismal online factorisation algorithms, I wondered whether I could do a better job, so I wrote a Javascript version, which is mainly a port of my Python factorisation algorithm, with a port and modification of a Python ECM implementation (acknowledgement in the website).</p><p>The algorithm implements Miller-Rabin primality testing, and factorisation using trial division by small primes, Pollard Rho algorithm and Elliptic Curve Method (ECM) using Montgomery curves.<br /><br />The factorisation website is <a href="https://factorisation.netlify.app/" target="_blank">here</a>.</p><p></p><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://factorisation.netlify.app/" style="margin-left: 1em; margin-right: 1em;" target="_blank"><img border="0" data-original-height="420" data-original-width="635" height="265" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq0BbeI_Sdm_TcBVuQ7iyqYPpoIjnaypRyNQlKjuz2zgX3qpygZk8JbUJfvt88ymHZWqoETIRuo3GrLcyIl0WrAzJLvyHKnXTHypgWOwSAZhm0IKltzB1QMSESB_mOsh5V4J6QkB9v8j5fnsG2KZNDJEmOOUqBt5dP4oyEkMXOR699Rl-lQSgcDaRuSQ/w400-h265/Thumbnail.png" width="400" /></a></div><br /><p style="margin-left: 1em; margin-right: 1em; text-align: center;"><br /></p><p></p><p><br /></p><p><br /></p>Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-66088103968381909152020-05-13T10:40:00.002+01:002020-05-13T10:40:46.486+01:00Pi CalculatorThe Covid19 lockdown has given me the opportunity to do a few projects, one of which is an interactive \( \pi \) calculator, which I have placed in a separate tab on this blog.<br />
<br />
<a href="https://pi-calculator.netlify.app/" target="_blank">Here</a> is a link to the calculator.Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-69725671183029745282018-06-15T17:21:00.002+01:002018-06-17T10:18:57.322+01:00Sunday Times Teaser 2907, Combinatorial Cards<a href="https://sites.google.com/site/sundaytimesteasers/teaser-index-1/2018-q2/teaser-2907" target="_blank">Sunday Times Teaser 2907</a> asks <span style="font-size: small;">how many cards there would be in a set with eight images per
card, each image appearing on exactly eight cards and the total number
of images being the same as the number of cards.</span><br />
<br />
<span style="font-size: small;">Astute readers will recognise this as an example of a finite projective plane, and may also recognise the set of cards as being similar to the game Doppel or Spot It!</span><br />
<span style="font-size: small;"><br /></span>
<span style="font-size: small;">Jim Randell produced a Python module to generate a set of cards, and a similar Python program by Joel Grus can be found <b><a href="http://joelgrus.com/2015/06/12/on-the-mathematics-of-spot-it/" target="_blank">here</a></b></span><br />
<span style="font-size: small;"><br /></span>
<span style="font-size: small;">I thought I would try to produce a Python version that allows sets of cards to be produced based on a projective plane associated with a finite field of the form GF(p^n) for arbitrary prime p an positive integer n.</span><br />
<span style="font-size: small;"><br /></span>
<span style="font-size: small;">The tricky bit if being able to do multiplication in the finite field, which requires an irreducible polynomial of degree n over the field. My code achieves this for values of n up to 3, and for a few other combinations of p and n that have pre-calculated irreducibles.</span><br />
<span style="font-size: small;"><br /></span>
<span style="font-size: small;">The code can be found <a href="https://drive.google.com/drive/folders/1qYhH8fxWYH86-e-CXJ6KlQkqN6uOrq_S?usp=sharing" target="_blank"><b>her</b>e</a>. It consists of </span><br />
<ul>
<li><span style="font-size: small;">a general purpose finite field module (adapted from the one I created for <a href="http://arthurvause.blogspot.com/2014/06/feeler-gauges-and-magic-circles.html" target="_blank">Sunday Times Teaser 777 )</a></span></li>
<li><span style="font-size: small;">a module to generate sets of cards based on the projective plane of GF(p^n)</span><span style="font-size: small;"> </span></li>
</ul>
Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-35554817315949499102017-05-09T13:10:00.000+01:002017-05-10T22:40:54.228+01:00Three PandigitalsA problem in <a href="http://www.contestcen.com/digits.htm">Contest
Center</a> asks:<br />
<i><br />
Find the smallest whole number N=ABC such that A, B and C each
contain all of the digits 0 to 9 at least once, </i><i>and N
contains all of the digits 0 to 9 at least three times.</i><br />
<br />
Here is a description of my code to solve the problem:<br />
<br />
Any solution, N, is at least a 30 digit number, and therefore too
large to be represented by 64 bits, but by using a C++ 128 bit
unsigned integer class, all numbers up to 38 decimal digits can be
represented, which is hopefully large enough to search for
solutions.<br />
<br />
I used the 128 bit C++ class <a href="https://github.com/calccrypto/uint128_t">https://github.com/calccrypto/uint128_t
</a>developed by Jason Lee, adding some performance and functional
improvements to help solve the three pandigitals puzzle, notably:<br />
<ul>
<li>Add a function decimal_string to construct the decimal
representation of a 128 bit number more quickly.<br />
</li>
<li>Using the intrinsic _umul128 to improve performance of 128 bit
number multiplication<br />
</li>
</ul>
<br />
<br />
The structure of the solution is as follows.<br />
<br />
Pre-calculate P<sub>10 , </sub> a sorted list of the 10-digit
pandigitals from 1023456789 to 9876543210<br />
<br />
Define M to be the smallest triple pandigital, $ M =
100011222333444555666777888999 $<br />
<br />
Define $\hat{N}$ to be the best solution found so far. Initially set
$\hat{N} = 999888777666555444333222111000 $ (so assuming there is a
30 digit solution)<br />
<br />
for A in P<sub>10</sub><br />
for B in P<sub>10 </sub>in the range A to
$ \left \lfloor \sqrt{\frac{\hat{N}}{A}} \right \rfloor $<br />
for C in the range $
\left \lceil \frac{M}{AB} \right \rceil $ to $ \left
\lfloor \frac{\hat{N}}{AB}\right \rfloor $<br />
if C is
pandigital and ABC is triple-pandigital<br />
set $ \hat{N} = ABC $<br />
<br />
This has been implemented as a Visual Studio C++ solution <a href="https://drive.google.com/file/d/0B1sb6hz7jmZ7bGFtdThORWduNnM/view?usp=sharing">Three
Pandigitals.zip</a><br />
<br />
The code contains a function to quickly determine whether a value of
C is pandigital, and a function added to the uint128_t class to more
quickly convert a 128 bit number to a decimal string, used in the
test to determine whether ABC is a triple pandigital.<br />
<br />
As the search takes several hours, the main program can be run with
two arguments: the starting value of A and the best value $\hat{N}$
found so far, allowing the program to be stopped and then restarted
where it left off.<br />
<br />
Running the program without any input arguments, this value of
$\hat{N}$ <br />
<br />
$\hat{N} = 1023456789 * 7694082153 * 12700546398
= 100011222449737853847658995366 $<br />
<br />
is found almost immediately, vastly reducing the range of values of
C that need to be subsequently searched. As smaller values of
$\hat{N}$ are found, the range of C values is reduced further.<br />
<br />
The program avoids performing 128 bit multiplication as much as
possible, and avoids 128 bit division completely by pre-calculating
the inverse of all 10 digit pandigitals, stored as doubles, which are then used to calculate a double that approximates $ \frac{M}{AB} $. A uint128_t cast of this approximation is then refined by addition or subtraction.Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-2193914117963981712017-02-17T11:56:00.002+00:002017-02-18T16:06:33.110+00:00IBM Ponder This, January 2017The <a href="https://www.research.ibm.com/haifa/ponderthis/challenges/January2017.html">IBM
Ponder This puzzle for January 2017</a> asked for a rational
solution for x<sup>y</sup>=y<sup>x</sup>, where the last eight
digits of x are different from each other, and for a bonus asked for
a solution where the last eight digits of x are a permutation of
1,2,3,4,5,6,7,8.<br />
<br />
It is possible to do better than this, and construct a solution
where the last nine digits of x are are a permutation of
1,2,3,4,5,6,7,8,9 , and a solution where the last ten digits of x
are are a permutation of 0,1,2,3,4,5,6,7,8,9.<br />
<br />
<h3>
Original Problem and Bonus</h3>
Goldbach and Euler proved that a set of 2 rationals {x,y} satisfies
x<sup>y</sup>=y<sup>x </sup>iff $
\{x,y\} = \{ (\frac{n+1}{n})^n , (\frac{n+1}{n})^{n+1} \} $
for integer n. <a href="http://www.cut-the-knot.org/wiki-math/index.php?n=Algebra.RationalSolutionOfXYYX">[1]</a>,
[2]<br />
<br />
If these numbers are to have last digits, n must be of the form $ n
= 2^t 5^f $<br />
<br />
$ \frac{n+1}{n}$ has $ d =
max(t,f) $ decimal places.<br />
<br />
$ \frac{(n+1)10^d}{n} $ is an integer whose last
digits are the last decimal digits of $ \frac{n+1}{n}$<br />
<br />
The last $D$ digits of $x,y$ are <br />
<blockquote>
$ (\frac{(n+1)10^d}{n})^{n+k} $ mod $ 10^D $, for
$k = 0,1 $
</blockquote>
Which can be calculated as <br />
<blockquote>
$ ((n+1)2^{d-t}5^{d-f})^{n+k} $ mod $ 10^D$, for
$k = 0,1 $</blockquote>
or<br />
<blockquote>
$ (10^d +2^{d-t}5^{d-f})^{n+k} $ mod $ 10^D$, for
$k = 0,1 $
...... (1)</blockquote>
For modest values of n, it is easy to calculate these residues using
modular exponentiation, for example in C or Python. <a href="https://drive.google.com/file/d/0B1sb6hz7jmZ7Y0g2dk1raHkxM2M/view?usp=sharing">This
Python program</a> searches for solutions to both problems.<br />
<br />
The first problem has a solution for $n=2^4 \cdot 5^1 =80$, $x =(
\frac{81}{80})^{80} $<br />
<br />
The bonus problem has a solution for $n= 5^5 = 3125$, $x =(
\frac{3126}{3125})^{3126} $<br />
<br />
<h3>
Extending the Problems</h3>
Now the more interesting problems: find a solution where the
last nine digits of x are are a permutation of 1,2,3,4,5,6,7,8,9 ,
and a solution where the last ten digits of x are are a permutation
of 0,1,2,3,4,5,6,7,8,9.<br />
<br />
Here we need to examine larger values of $n$, so expression (1) becomes impractical to use and we have to find a better way of determining the last digits of $ (\frac{(n+1)10^d}{n})^{n+k} $<br />
<br />
If $d \ge D$, then (1) can be reduced to <br />
<blockquote>
$ (2^{d-t}5^{d-f})^{n+k} $ mod $ 10^D$, for $k =
0,1 $ </blockquote>
<br />
There are two cases to consider:<br />
<ol>
</ol>
<h3>
$f>t$</h3>
<blockquote>
$ (2^{d-t}5^{d-f})^{n+k} $ mod $ 10^D = (
2^{f-t})^{n+k} $ mod $ 10^D = 2^{(f-t)(n+k)} $ mod $ 10^D $<br />
<br />
Now <a href="http://www.exploringbinary.com/cycle-length-of-powers-of-two-mod-powers-of-ten/">[3]</a>
shows that powers of 2 mod $10^D$ cycle with a period of $P = 4
\cdot 5^{D-1}$, starting at $2^D$ </blockquote>
<blockquote>
so if $ (f-t)(n+k) = (f-t)(2^t 5^f+k) \ge D $,</blockquote>
<blockquote>
$2^{(f-t)(n+k)} $ mod $ 10^D $ = $ 2^{ D + ((f-t)(2^t 5^f+k) - D) \: mod \: P } $ mod $ 10^D
$
..... (2)<br />
<br /></blockquote>
<h3>
$t >f$</h3>
<blockquote>
$ (2^{d-t}5^{d-f})^{n+k} $ mod $ 10^D = ( 5^{t-f})^{n+k}
$ mod $ 10^D = 5^{(t-f)(n+k)} $ mod $ 10^D $<br />
<br />
<a href="http://www.exploringbinary.com/cycle-length-of-powers-of-five-mod-powers-of-ten/">[4]</a>
shows that powers of 5 mod $10^D$ cycle with a period of
$P=2^{D-2}$, starting at $5^D$ <a href="http://www.exploringbinary.com/cycle-length-of-powers-of-five-mod-powers-of-ten/"></a><br />
<br />
so if $ (t-f)(n+k) = (t-f)(2^t 5^f+k) \ge D $,</blockquote>
<br />
<blockquote>
$5^{(t-f)(n+k)} $ mod $ 10^D $ = $ 5^{ D + ((t-f)(2^t 5^f+k) - D) \: mod \: P } $ mod $
10^D $
..... (3)</blockquote>
<blockquote>
<br />
<br /></blockquote>
<br />
The residues in (2) and (3) can be calculated using modular
exponentiation without the need to handle excessively large numbers.
<a href="https://drive.google.com/file/d/0B1sb6hz7jmZ7OHI3bmQxM241NXM/view?usp=sharing">This
Python program</a> searches for solutions to both problems, finding the following solutions:<br />
<br />
For $n = 5^{267}$, the last ten digits of $( \frac{n+1}{n})^{n+1} $
are 3628975104<br />
<br />
For $n = 2^2 \cdot 5^{957}$, the last nine digits of $(
\frac{n+1}{n})^{n+1} $ are 247315968<br />
<br />
[1] <a href="http://www.cut-the-knot.org/wiki-math/index.php?n=Algebra.RationalSolutionOfXYYX">Cut
The Knot, Rational Solutions to x^y = y^x</a><br />
<br />
[2] Sved, Marta. “On the Rational Solutions of x<sup>y</sup> = y<sup>x</sup>.”
<i>Mathematics Magazine</i>, vol. 63, no. 1, 1990, pp. 30–33., <a href="http://www.jstor.org/stable/2691508">http://www.jstor.org/stable/2691508</a>.<br />
<br />
[3] Exploring Binary, <a href="http://www.exploringbinary.com/cycle-length-of-powers-of-two-mod-powers-of-ten/">Cycle
Length of Powers of Two Mod Powers of Ten</a>, Rick Regan,
November 6th, 2009<br />
<br />
[4] Exploring Binary, <a href="http://www.exploringbinary.com/cycle-length-of-powers-of-five-mod-powers-of-ten/">Cycle
Length of Powers of Five Mod Powers of Ten</a>, Rick Regan,
December 22nd, 2009<br />
<br />Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-58149297876086807332015-05-10T20:09:00.000+01:002015-05-11T09:27:02.549+01:00Cheryl's BirthdayThe puzzle, originally set in the 2015 Singapore and Asian Schools Math Olympiad, know as <a href="http://en.wikipedia.org/wiki/Cheryl%27s_Birthday" target="_blank">Cheryl's Birthday</a>, has generated a lot of interest over the past few weeks.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://static01.nyt.com/images/2015/04/15/science/15mathproblem_toned/15mathproblem_toned-articleLarge.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://static01.nyt.com/images/2015/04/15/science/15mathproblem_toned/15mathproblem_toned-articleLarge.jpg" height="208" width="320" /></a></div>
<br />
A discussion of the puzzle <a href="https://sites.google.com/site/sundaytimesteasers/teaser-index-1/2015-q2/teaser-2745" target="_blank">here</a> queried the meaning of the term "day" in the statement "Cheryl then tells Albert and Bernard separtely the month and day of her birthday respectively".<br />
<br />
The generlly accepted interpretation is that it is the day of the month, but I wondered whether the puzzle could be solved if "day" were interpreted as the day of the week, as suggested in the discussion.<br />
<br />
The solution, assuming the "day of the month" interpretation, looks like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPhF_UBPQYJbDUaEOXmCF2aXWvalK7-AzyDBe5Sd5SVgKMI0N0BUZ0WV3Ne8RRsEGgmjZZRKaOpzQLk8EjhCvOiE5tkJrxTR_YOCHS9iaIa5-CRMJeRtK0tudP59M4lodni4nV0itsbK-B/s1600/Cheryls+birthday+1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="291" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPhF_UBPQYJbDUaEOXmCF2aXWvalK7-AzyDBe5Sd5SVgKMI0N0BUZ0WV3Ne8RRsEGgmjZZRKaOpzQLk8EjhCvOiE5tkJrxTR_YOCHS9iaIa5-CRMJeRtK0tudP59M4lodni4nV0itsbK-B/s400/Cheryls+birthday+1.PNG" width="400" /></a></div>
The days of the week associated with each date in 2015 are:<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGg_uPxM6dk2QYkYHed4Z0RtlM5jbkO13JhHA39G0HXm7wIriIHqXsjwJD8mVM6vOFZ1VY-kPyPKrJsh8AyNp-pI_HBeKYS69FkQst0pBqN9YgCQKHiS4ExYUGCCPOgI5WvIGJbpGXTpAz/s1600/Cheryls+birthday+2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGg_uPxM6dk2QYkYHed4Z0RtlM5jbkO13JhHA39G0HXm7wIriIHqXsjwJD8mVM6vOFZ1VY-kPyPKrJsh8AyNp-pI_HBeKYS69FkQst0pBqN9YgCQKHiS4ExYUGCCPOgI5WvIGJbpGXTpAz/s320/Cheryls+birthday+2.PNG" width="136" /> </a></div>
<div class="separator" style="clear: both; text-align: left;">
Now suppose Albert and Bernard are told all these dates, Albert is told the month of Cheryl's birthday and Bernard is told the day of the week. A solution can still be derived, as follows:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmPgKMoB8z21QpvknbmTX1u93df5Go8y2ZGbpdv8IsiSoS6dYNvrPL5VnxpVODcMmkoov0uZ9gwo29uxoLVlh4qDwx4owWTmyZOirn70VT024wKMc0czPS5pBz6OMZBLRv4FK9XX5sDlDE/s1600/Cheryls+birthday+3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmPgKMoB8z21QpvknbmTX1u93df5Go8y2ZGbpdv8IsiSoS6dYNvrPL5VnxpVODcMmkoov0uZ9gwo29uxoLVlh4qDwx4owWTmyZOirn70VT024wKMc0czPS5pBz6OMZBLRv4FK9XX5sDlDE/s400/Cheryls+birthday+3.PNG" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
A solution with this structure would work for any other year, as the days of the week would all be offset by the same amount.</div>
<br />
<br />Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-12642280876445599642015-01-27T12:49:00.003+00:002022-11-05T12:12:28.686+00:00Factoring numbers in Python and C++While trying to solve the "Squares on a Cube" puzzle on <a href="http://www.contestcen.com/expert.htm" target="_blank">Contest
Center</a>, I became sidetracked into writing an efficient program
to produce the prime factors of a number, an exercise that most
programmers will have attempted at some time.<br />
<br />
The hybrid Python / C++ code presented here combines well known
techniques, Miller Rabin and Brent's variation of Pollard Rho, together with a modern fast
technique for modular reduction developed by Rutten and Eekelen.<br />
<br />
<h2>
<span style="font-size: large;">Python implementation</span></h2>
After a bit of experimenting, I settled on this mixture for a Python
implementation:<br />
<ul>
<li>Lookup tables for numbers below 10<sup>6</sup></li>
<li>Trial division of primes below 300</li>
<li>Miller-Rabin primality test (deterministic up to the published
limit)</li>
<li>Brent's variant of the Pollard Rho algorithm, by default
running for up to 1 second</li>
<li>Elliptic Curve Method (ECM) if the Brent algorithm fails to
find a factor within its time limit. </li>
</ul>
<br />
<h2>
<span style="font-size: large;">C++ implementation</span></h2>
While the Python version is reasonably fast, a C++ version is
much faster. My C++ code factors numbers below 2<sup>64</sup>, where
Brent Pollard Rho can be used without having to use ECM or Multiple
Polynomial Quadratic Sieve.<br />
<br />
The performance of Brent Pollard Rho and Miller Rabin is ultimately
dominated by modular multiplication, so any improvement of modular
multiplication time is reflected in the overall performance of the
factorisation algorithm. Here are my attempts to speed up
modular multiplication:<br />
<br />
<h3>
I. Shift and add<br />
</h3>
To calculate $a \times b$ mod $m$ I initially used an intricate, and
relatively slow, shift and add method. Several implementations of this can be found on the internet. The version I used was stolen
from Craig McQueen's <a href="http://stackoverflow.com/questions/10076011/overflow-aa-mod-n" target="_blank">post on stackexchange.</a> This version is
valid for any $ m < 2^{64} $<br />
<br />
<span class="post_title"></span>Function modmulSA implements this
technique.<br />
<br />
<h3>
II, Repeated reduction of most significant 64 bits </h3>
My first attempt to speed up modular multiplication, valid
for a modulus $m < 2^{63}$, uses the following techniques:<br />
<blockquote>
<h4>
a) Division by multiplication</h4>
If a modulus of the same denominator needs to be obtained many
times, as in the Brent algorithm and the Miller Rabin test, an
efficient technique is to construct an inverse $M=2^k/m$ of
the denominator $m$ once (M is often termed a "magic number"),
then perform division by $m$ by multiplying the numerator by M and
bit shifting to divide by $2^k$. Of course it's a bit more
complicated than that, and is described comprehensively by Henry
S. Warren Jr in <a href="http://www.hackersdelight.org/" target="_blank">Hackers Delight</a>, (Chapter 10, Integer
Division by Constants), and explained in a readable form by
Ridiculous Fish in <a href="http://ridiculousfish.com/blog/posts/labor-of-division-episode-i.html" target="_blank">Labor of Division (Episode I).</a><br />
<br />
C++ functions magicu2 and magicdiv (stolen from Hackers Delight)
and magicmod implement these techniques. <br />
<br />
<h4>
<span class="post_title">b) Modular multiplication </span></h4>
<ol>
<li><span class="post_title">Reduce a and b modulo m (using the
division by multiplication technique)</span> </li>
<li><span class="post_title">Construct the product $c = a \times
b$. If $a$ and $b$ are 64 bit numbers, $c$ is a 128 bit
number. I used the MS VC++ intrinsic function for this
calculation, but if this is not available, </span><span class="post_title"><a href="https://www.blogger.com/null" target="_blank">Hackers Delight</a></span><span class="post_title"> function <a href="http://www.hackersdelight.org/hdcodetxt/mont64.c.txt" target="_blank">mulul64</a> can be used.</span></li>
<li><span class="post_title">Repeatedly find the most
significant 64 bits of $c$ and reduce them modulo $m$ (again
using division by multiplication), until c is reduced to a
number less than $m$</span></li>
</ol>
<ol>
</ol>
</blockquote>
Function modmulRR implements this technique.<br />
<br />
<h3>
III, Assembler</h3>
On 64 bit Intel processors, the multiply instruction multiplies two
64 bit numbers and stores the 128 bit result in two registers,
rdx:rax. The divide instruction divides a 128 bit number stored in
rdx:rax by a 64 bit number and stores the 64 bit quotient in rax and
the 64 bit remainder in rdx.<br />
<br />
So these instruction are ideal for modular multiplication. However,
the intrinsic function to perform division of a 128 bit number is
not available in MS Visual Studio, so a few lines of assembler
(mod64.asm) have to be written.<br />
<br />
The assembler version has the advantage of being valid for a modulus
up to $2^{64}-1$, and is noticeably faster than repeated reduction,
and of course much faster than the shift and add method.<br />
<br />
Function modmulAS is the C interface to this function.<br />
<br />
<br />
<h3>
IV. Rutten-Eekelen<br />
</h3>
An even faster method of modular multiplication than assembler, for
a modulus $m<2^{63}$, uses the algorithm described in <a data-blogger-escaped-target="_blank" href="http://www.researchgate.net/publication/220493198_Efficient_and_formally_proven_reduction_of_large_integers_by_small_moduli">Efficient
and
formally proven reduction of large integers by small moduli</a> by
Luc M. W. J. Rutten and Marko C. J. D. van Eekelen. This method
requires the pre-calculation of a similar, but slightly different,
magic number to the one described above, and then makes use of this
number in an intricate algorithm whose correctness has been verified
using a computer generated proof.<br />
<br />
Function modmulRE implements this function.<br />
<br />
<h2>
<span class="post_title"><span style="font-size: large;">Performance
<br />
</span></span></h2>
<table border="0" cellpadding="2" cellspacing="2" style="width: 100%px;">
<tbody>
<tr>
<td valign="top" width="300">This graph shows the average time
to factor numbers in the range $10^n$ to $10^n+10000$
(giving a representative mix of easy and hard
factorisations) for all my C++ versions, and for reference,
a Python implementation of Brent Pollard and Miller Rabin.<br />
<br />
The graph shows that the shift and add version has
performance no better than the Python version, and that the
Rutten-Eekelen version beats the Assembler version, for
numbers below $2^{63}$</td>
<td valign="top"><div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2DuZdJ-fxr7fMnEySewRfmfxK8QMDcWhmluSJX9Obcrn1YZ_wkhHU1zmJ-Dowz7TkSIKb6J3EzMqN9LZATewURX9QhOBGqTvr8hPk5j0UvPMcA2p9Eh_MGOVO2xPjXYPuLcHADXIKnpqj/s1600/Average+times+to+factorise.PNG" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2DuZdJ-fxr7fMnEySewRfmfxK8QMDcWhmluSJX9Obcrn1YZ_wkhHU1zmJ-Dowz7TkSIKb6J3EzMqN9LZATewURX9QhOBGqTvr8hPk5j0UvPMcA2p9Eh_MGOVO2xPjXYPuLcHADXIKnpqj/s1600/Average+times+to+factorise.PNG" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br /></td>
</tr>
</tbody>
</table>
<br />
<h2>
<span class="post_title"><span style="font-size: large;">C++ /
Python integration</span> </span></h2>
The ctypes module integrates Python with a DLL of the C++
implementation. Calling a DLL from Python incurs an overhead
of about 1.5µs, so it is faster to use the Python implementation for
small numbers that are factored using a lookup table. For larger
numbers, the overhead soon becomes negligible compared to the time
to factorise the number.<br />
<br />
Rutten-Eekelen has the best performance for a modulus $m<2^{63}$,
even beating the assembler version. For a modulus $2^{63} \le m \lt
2^{64}$ the assembler version is fastest, so the final C++ version
called from Python uses a hybrid of these two methods.<br />
<br />
<table border="0" cellpadding="2" cellspacing="2" style="width: 100%px;">
<tbody>
<tr>
<td valign="top" width="300">To verify that the Brent Pollard
Rho algorithm copes with difficult cases, this graph shows
the average and worst case times to factorise numbers within
$ \pm 5000$ of various baselines.<br />
<br />
Note the jump in worst case factorisation times for numbers
$ \ge 2^{63}$, where the algorithm switches from
Rutten-Eekelen to Assembler.<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
</td>
<td valign="top"><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEic7wEtf3ff4swI161ortzBPTMvhXjjk54z0DPE8yaxZ0caFGSDVwMZXlVXRUz-VBBKX8xEgoPvEEta_xBVxQ1ZJGSS1DBMbl0-zq5ls0DptjCUaBwghPB0gY5luP97tGYr5hoTPRaHgNJx/s1600/Average+and+worst+case+graph.PNG" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEic7wEtf3ff4swI161ortzBPTMvhXjjk54z0DPE8yaxZ0caFGSDVwMZXlVXRUz-VBBKX8xEgoPvEEta_xBVxQ1ZJGSS1DBMbl0-zq5ls0DptjCUaBwghPB0gY5luP97tGYr5hoTPRaHgNJx/s1600/Average+and+worst+case+graph.PNG" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
</td>
</tr>
</tbody>
</table>
The worst cases are listed <a href="https://drive.google.com/file/d/0B1sb6hz7jmZ7OE9Jd01wOXE2SGM/view?usp=sharing" target="_blank">here</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<h2>
<span class="post_title"><span style="font-size: large;">Source
Code </span></span></h2>
<ul>
</ul>
<span class="post_title">All the source code is located <a href="https://github.com/armchaircaver/Factoring-in-Python" target="_blank">here</a>, except for the optional ECM algorithm,
for which I used the Sourceforge implementation<a href="http://sourceforge.net/projects/pyecm/"> pyecm.py</a>.</span><span class="post_title"><span class="post_title"></span></span><br />
<br />
<span class="post_title"><span class="post_title">A stand-alone
Python module, <b>factors.py</b> </span>can be run without the
C++ DLL or the ECM module being present. </span><span class="post_title"><br />
This module has the following principal functions:</span> <br />
<table bgcolor="#ffffff" border="1" cellpadding="3" cellspacing="3" style="background-color: #ffffcc; height: 192px;">
<tbody>
<tr>
<td align="center" bgcolor="#ccccff" valign="top"><b>Description</b><b><br />
</b></td>
<td align="center" bgcolor="#ccccff" valign="top"><b>Example</b><b>
call</b><b><br />
</b></td>
<td align="center" bgcolor="#ccccff" valign="top"><b>Return
value</b><b><br />
</b></td>
</tr>
<tr>
<td bgcolor="#ffffff" valign="top"><b>all_factors(n) <br />
</b>returns a list of all the factors of n<br />
<br />
The function chooses whether to use the Python or C++
version depending on the size of n. </td>
<td bgcolor="#ffffff" valign="top">all_factors(12) </td>
<td bgcolor="#ffffff" valign="top">[1,2,3,4,6,12]</td>
</tr>
<tr>
<td bgcolor="#ffffff" valign="top"><b>totient(n)<br />
</b>returns the Euler totient function</td>
<td bgcolor="#ffffff" valign="top">totient(30) </td>
<td bgcolor="#ffffff" valign="top">8</td>
</tr>
<tr>
<td bgcolor="#ffffff" valign="top"><b>factorise(n,
maxBrentTime=1.0) </b><br />
returns a list of the prime factors of n<br />
<br />
maxBrentTime determines how many seconds the Brent algorithm
should run before reverting to ECM (if available).<br />
<br />
The function chooses whether to use the Python or C++
version depending on the size of n. </td>
<td bgcolor="#ffffff" valign="top">factorise(12) </td>
<td bgcolor="#ffffff" valign="top">[2,2,3]</td>
</tr>
</tbody>
</table>
<span class="post_title"> </span><br />
<span class="post_title">A DLL, <b>FactorsDLL.dll</b>, built
on Windows 7 64 bit, is included, together with a Python module <b>factorsDLL.py</b>
to call the DLL from Python. I'm not sure whether the DLL will
work on other machines. In case it doesn't, the source code to
build the DLL is also included.</span><br />
<br />
<h2>
<span class="post_title" style="font-size: large;"> Implementation
notes</span></h2>
<span class="post_title">The Miller Rabin test can occasionally
derive a factor of a composite number, when testing witness $a$
for the primality of $n$ encouters the situation</span><br />
<div style="text-align: center;">
<span class="post_title">$a^{2^rd}
\ne \pm 1$ mod $n$ and </span><span class="post_title">$a^{2^{r+1}d} =1$ mod $n$</span></div>
<br />
<span class="post_title">In this situation </span><span class="post_title">$gcd(a^{2^rd}-1,n)$ produces a factor of $n$. I
have included this test, even though the condition rarely occurs
in practice.</span><br />
<br />
The Brent Pollard Rho algorithm occasionally fails to find a factor
of a composite, so I simply run the algorithm again. The random
selection of parameters seems to ensure that the algorithm does not
have to be run too many times to obtain a factor.<br />
<br />
<br />
<h2>
<span class="post_title"><span style="font-size: large;"><span style="font-size: large;">Postscript</span></span></span></h2>
Even though the program vastly reduced the time to factorise a
number, I still haven't solved the Contest Center problem that
motivated me to write it.Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-78492202031412345542014-10-07T16:04:00.000+01:002014-10-08T23:05:16.989+01:00Calculating square roots on a pinwheel calculator
Before electronic calculators became affordable, complex
calculations were often done using pinwheel calculators. These were
manufactured by several companies, for example, Odhner, Brunsviga,
Thales, Schubert, all based on designs of Frank Baldwin and Willgodt
Odhner in the 19th century.<br>
<br>
<table style="width: 600px;" cellpadding="2" cellspacing="2"
border="0">
<tbody>
<tr>
<td valign="top">
<table class="tr-caption-container" style="float: left;
margin-right: 1em; text-align: left;" cellpadding="0"
cellspacing="0" align="center">
<tbody>
<tr>
<td style="text-align: center;"><a
href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGOPiQ7-IzP2GzeM7CwtFgB4tyRnCa8j6lgNJ9MM7vUpP4HN7mWIgqOMf6DkH9OZfN4FV2HC6iIU23eURaIeMpAGcih0wHbp4VD96Qn75BsIu8u5ylGpZCiy2gWrdAjF1Fgbl-L7yaHaBt/s1600/IMG_8815.JPG"
imageanchor="1" style="margin-left: auto;
margin-right: auto;"><img
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGOPiQ7-IzP2GzeM7CwtFgB4tyRnCa8j6lgNJ9MM7vUpP4HN7mWIgqOMf6DkH9OZfN4FV2HC6iIU23eURaIeMpAGcih0wHbp4VD96Qn75BsIu8u5ylGpZCiy2gWrdAjF1Fgbl-L7yaHaBt/s1600/IMG_8815.JPG"
border="0" height="150" width="200"></a></td>
</tr>
<tr>
<td class="tr-caption" style="text-align: center;">Original
Odhner
127</td>
</tr>
</tbody>
</table>
</td>
<td valign="top">
<table class="tr-caption-container" style="float: left;
margin-right: 1em; text-align: left;" cellpadding="0"
cellspacing="0" align="center">
<tbody>
<tr>
<td style="text-align: center;"><a
href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZxn8nYeSzzZupgMVmQwO74dgRrQRp4mGk0mxGFyv8uDSLqDSsPgGRsqIhAdZf-2pb9UHLe5ySgghR39rozZgdoyS-ycNu_CZp9d1WThX_AuwAjiH67WzE2K3IJ4elcBs5kkjRrjnGNJ9C/s1600/20140817_101335.jpg"
imageanchor="1" style="margin-left: auto;
margin-right: auto;"><img
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZxn8nYeSzzZupgMVmQwO74dgRrQRp4mGk0mxGFyv8uDSLqDSsPgGRsqIhAdZf-2pb9UHLe5ySgghR39rozZgdoyS-ycNu_CZp9d1WThX_AuwAjiH67WzE2K3IJ4elcBs5kkjRrjnGNJ9C/s1600/20140817_101335.jpg"
border="0" height="150" width="200"></a></td>
</tr>
<tr>
<td class="tr-caption" style="text-align: center;">Original
Odhner
227</td>
</tr>
</tbody>
</table>
</td>
<td valign="top">
<div>
<table class="tr-caption-container" style="float: left;
margin-right: 1em; text-align: left;" cellpadding="0"
cellspacing="0">
<tbody>
<tr>
<td style="text-align: center;"><a
href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilewLGYvlMYndxxzurtQ86L8OD50sZLwvF400YVP7VG4VDl4tj0qnSHjQObYXwMciRPVGK11ODCa-9RWGfYoogYoeZpbJbIfDM0RYOzZjx-Pq7267Cu3QEgzX7ebphqB5YaivM1XX7FI8i/s1600/IMG_9672.JPG"
imageanchor="1" style="clear: left;
margin-bottom: 1em; margin-left: auto;
margin-right: auto;"><img
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilewLGYvlMYndxxzurtQ86L8OD50sZLwvF400YVP7VG4VDl4tj0qnSHjQObYXwMciRPVGK11ODCa-9RWGfYoogYoeZpbJbIfDM0RYOzZjx-Pq7267Cu3QEgzX7ebphqB5YaivM1XX7FI8i/s1600/IMG_9672.JPG"
border="0" height="150" width="200"></a></td>
</tr>
<tr>
<td class="tr-caption" style="text-align: center;">Brunsviga
20</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<table style="width: 100%px;" cellpadding="2" cellspacing="2"
border="0">
<tbody>
<tr>
<td valign="top"><br>
Having recently acquired three of these calculators, I set
about investigating what they were capable of. As well as
the four basic arithmetic operations, addition, subtraction,
multiplication and division, square roots can also be
calculated.<br>
<br>
The instruction manual for the Original Odhner 227 describes
the procedure to extract the square root of 966289. <br>
<br>
At first glance, the instructions look like an alchemist's
spell, but they are performing the following calculations to
derive <span style="-webkit-text-stroke-width: 0px;
background-color: white; color: #222222; display: inline
!important; float: none; font-family: arial, sans-serif;
font-size: 16px; font-style: normal; font-variant: normal;
font-weight: normal; letter-spacing: normal; line-height:
19.2000007629395px; orphans: auto; text-align: left;
text-indent: 0px; text-transform: none; white-space:
normal; widows: auto; word-spacing: 0px;">√</span>966289 =
983:<br>
<br>
</td>
<td valign="top">
<table class="tr-caption-container" style="float: right;
margin-left: 1em; text-align: right;" cellpadding="0"
cellspacing="0">
<tbody>
<tr>
<td style="text-align: center;"><a
href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMwICOsqS5VIb7MwpXno42MCQGwpMExf4-CuDLAbBo_hDLqYYjX5Wftl4Nw4AJiV_vWN0K6kkzEWiPZo0BW8drrCKixtFGBX-CnSCx13WS5HL5gCY-L7tUA0h5V2TKhgxmyXb7XFd33T-N/s1600/Square+root+extraction.jpg"
imageanchor="1" style="clear: right;
margin-bottom: 1em; margin-left: auto;
margin-right: auto;"><img
src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMwICOsqS5VIb7MwpXno42MCQGwpMExf4-CuDLAbBo_hDLqYYjX5Wftl4Nw4AJiV_vWN0K6kkzEWiPZo0BW8drrCKixtFGBX-CnSCx13WS5HL5gCY-L7tUA0h5V2TKhgxmyXb7XFd33T-N/s1600/Square+root+extraction.jpg"
border="0" height="283" width="320"></a></td>
</tr>
<tr>
<td class="tr-caption" style="text-align: center;">From
Odhner
227
instructions
(click
to enlarge)</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<br>
<table style="width: 100%px;" cellpadding="2" cellspacing="2"
border="1">
<tbody>
<tr>
<td valign="top" width="50"><b>c)</b><b><br>
</b></td>
<td valign="top" width="500"><small><b><big> 966289<br>
</big><span style="color: #cc33cc;">- <big><big>1</big></big>0000
-
<big><big>3</big></big>0000 - <big><big>5</big></big>0000
-
<big><big>7</big></big>0000 - <big><big>9</big></big>0000
-<big><big>11</big></big>0000 - <big><big>13</big></big>0000
-
<big><big>15</big></big>0000 - <big><big>17</big></big>0000</span>
<big><br>
= </big></b><big><b>156289</b></big></small></td>
<td valign="middle">(<b><big><big> 9 </big></big></b>subtractions)</td>
</tr>
<tr>
<td valign="top" width="50"><b>d) & </b><b>e)</b><b><br>
</b></td>
<td valign="top" width="500"><small><b><big>156289<br>
</big><span style="color: #000099;">- <big><big>181</big></big>00
-
<big><big>183</big></big>00 - <big><big>185</big></big>00
-
<big><big>187</big></big>00 - <big><big>189</big></big>00
-
<big><big>191</big></big>00 - <big><big>193</big></big>00
-
<big><big>195</big></big>00</span> <br>
= </b><big><b>5889</b></big></small></td>
<td valign="middle"><big><big><small><small>( </small></small><b>8</b></big></big>
subtractions)</td>
</tr>
<tr>
<td valign="top" width="50"><b>f)</b><b><br>
</b></td>
<td valign="top" width="500"><small><b><big>5889 <br>
<span style="color: #009900;"><small>- <big><big>1961
</big></big>-
<big><big>1963 </big></big>-</small></span><big><span
style="color: #009900;">1965</span> <br>
</big>= 0</big></b></small></td>
<td valign="middle">(<b><big><big> 3</big></big></b>
subtractions)</td>
</tr>
</tbody>
</table>
<br>
The algorithm is based on the fact that the square of <i><b>n</b></i>
is the sum of the first <i><b>n</b></i> odd numbers:
<br>
<table cellpadding="2" cellspacing="2" border="0" width="100%">
<tbody>
<tr>
<td valign="top" width="300">
<blockquote>
<span style="font-family: Helvetica, Arial, sans-serif;"><span
style="color: blue; font-size: large;"><b>1<sup>2</sup>
=
1 = 1</b></span><br>
<span style="color: blue; font-size: large;"><b>2<sup>2</sup>
=
4 = 1+3</b></span><br>
<span style="color: blue; font-size: large;"><b>3<sup>2</sup>
=
9 = 1+3+5</b></span><br>
<span style="color: blue; font-size: large;"><b>4<sup>2</sup></b><b> </b><b>=
16 = 1+3+5+7</b></span><br>
<span style="color: blue; font-size: large;"><b>5<sup>2</sup>
=
25 = 1+3+5+7+9<br>
etc.</b></span></span></blockquote>
</td>
<td valign="top"><img
src="data:image/png;base64,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"
alt="" height="216" width="217"></td>
</tr>
</tbody>
</table>
<br>
<table style="width: 100%px;" cellpadding="2" cellspacing="2"
border="0">
<tbody>
<tr>
<td valign="top" width="420">The square root of a number can
therefore be
calculated by<br>
subtracting successive odd numbers until the
sum is zero. <br>
The square root is the number of subtractions performed.<br>
<br>
For example, to find the square root of 64,<br>
successively
subtract 1,3,5,... until zero is reached.<br>
The number of subtractions required, in this case 8,<br>
is the
square root of the number.<br>
<br>
For large numbers, e.g. <span
style="-webkit-text-stroke-width: 0px; background-color:
white; color: #222222; display: inline !important; float:
none; font-family: arial, sans-serif; font-size: 16px;
font-style: normal; font-variant: normal; font-weight:
normal; letter-spacing: normal; line-height:
19.2000007629395px; orphans: auto; text-align: left;
text-indent: 0px; text-transform: none; white-space:
normal; widows: auto; word-spacing: 0px;"></span>966289,
this would obviously be<br>
impractical,
but we can attack large numbers one pair of digits<br>
at a
time, to produce one digit of the square root at a time:</td>
<td align="left" bgcolor="#ffffcc" valign="middle" width="200">
<div style="text-align: center;">
<blockquote>
<span style="background-color: transparent; font-family:
'Courier New', Courier, monospace;">64 - 1 = 63</span><br>
<span style="background-color: transparent;"><span
style="font-family: Courier New, Courier,
monospace;">63 - 3 = 60</span></span><br>
<span style="background-color: transparent;"><span
style="font-family: Courier New, Courier,
monospace;">60 - 5 = 55</span></span><br>
<span style="background-color: transparent;"><span
style="font-family: Courier New, Courier,
monospace;">55 - 7 = 48</span></span><br>
<span style="background-color: transparent;"><span
style="font-family: Courier New, Courier,
monospace;">48 - 9 = 39</span></span><br>
<span style="background-color: transparent;"><span
style="font-family: Courier New, Courier,
monospace;">39 - 11 = 28</span></span><br>
<span style="background-color: transparent;"><span
style="font-family: Courier New, Courier,
monospace;">28 - 13 = 15</span></span><br>
<span style="background-color: transparent;"><span
style="font-family: Courier New, Courier,
monospace;">15 - 15 = 0</span></span></blockquote>
</div>
</td>
</tr>
</tbody>
</table>
<br>
To find the first digit of the square root of <span
style="background-color: white; display: inline ! important;
float: none; font-family: arial,sans-serif; font-size: 16px;
font-style: normal; font-variant: normal; font-weight: normal;
letter-spacing: normal; line-height: 19.2px; text-align: left;
text-indent: 0px; text-transform: none; white-space: normal;
word-spacing: 0px;"></span>966289, subtract odd ten thousands:
10000, 30000, 50000, ... until the point just before the
result would turn negative, so subtract
10000+30000+...+170000. Now, 1+3+...+17 = 9<sup>2 </sup>, so
10000+30000+...+170000 = 900<sup>2 </sup>. The first digit of
the square root is 9.<br>
<br>
To find the first two digits of the square root, we could start with<span
style="-webkit-text-stroke-width: 0px; background-color: white;
color: #222222; display: inline !important; float: none;
font-family: arial, sans-serif; font-size: 16px; font-style:
normal; font-variant: normal; font-weight: normal; letter-spacing:
normal; line-height: 19.2000007629395px; orphans: auto;
text-align: left; text-indent: 0px; text-transform: none;
white-space: normal; widows: auto; word-spacing: 0px;"></span>
966289 and subtract odd hundreds: 100, 300, 500,... up to 19500.
However, we have already subtracted 900<sup>2</sup>, which is equal
to 100+300+500+...+17700+17900, so we can start subtracting at
18100, subtracting only 18100+18300+...+19500. We have now
subtracted a total of 980<sup>2</sup>.<br>
<br>
Similarly to find the first three digits of the square root (i.e.
the complete square root), we could start with 966289 and subtract
1, 3, 5,...up to 1965. But we have already subtracted 980<sup>2 </sup>=
1+3+5+...+1959, so we can start subtracting at 1961, only needing to
subtract 1961+1963+1965<br>
<br>
<table style="width: 100%px;" cellpadding="2" cellspacing="2"
border="0">
<tbody>
<tr>
<td valign="top" width="150"><span style="color: #cc33cc;"><b><b>10000+30000+...+170000 </b></b></span></td>
<td valign="top" width="330"><br>
</td>
<td valign="top"><span style="color: #cc33cc;"><b><b>= 900</b><b><sup>2
</sup></b></b></span></td>
</tr>
<tr>
<td valign="top" width="150"><span style="color: #000099;"><b><b>18100+18300+...+19500 </b></b></span></td>
<td valign="top" width="330"><span style="color: #000099;"><b><b>
=
(100+300+...+19500) - (100+300+...+17900) </b></b></span></td>
<td valign="top"><span style="color: #000099;"><b><b>= 980</b><b><sup>2</sup></b><b>
- </b><b>900</b><b><sup>2</sup></b></b></span></td>
</tr>
<tr>
<td valign="top" width="150"><span style="color: #009900;"><b>1961+1963+1965 </b></span></td>
<td valign="top" width="330"><span style="color: #009900;"><b>
=
(1+3+...+1965) - (1+3+...+1959)</b></span></td>
<td valign="top"><span style="color: #009900;"><b>= 983<sup>2</sup>
-
980</b><b><b><sup>2</sup></b></b></span></td>
</tr>
</tbody>
</table>
<br>
<b><span style="color: #cc33cc;"> </span></b><sup><br>
</sup><big><sup>The algorithm can also be used to calculate
approximations to the square root of numbers that are not
perfect squares</sup></big><big><sup>. <a
href="https://www.youtube.com/watch?v=Bz8_tNDUDog">Here is a
video</a> by James Grime (singingbanana) and Hugh Hunt that
demonstrates an
Original Odhner being used to calculate </sup></big><big><sup><span
style="-webkit-text-stroke-width: 0px; background-color:
white; color: #222222; display: inline !important; float:
none; font-family: arial, sans-serif; font-size: 16px;
font-style: normal; font-variant: normal; font-weight: normal;
letter-spacing: normal; line-height: 19.2000007629395px;
orphans: auto; text-align: left; text-indent: 0px;
text-transform: none; white-space: normal; widows: auto;
word-spacing: 0px;">√</span>2. </sup></big><br>
<div class="separator" style="clear: both; text-align: center;">
</div>
Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com5tag:blogger.com,1999:blog-6654130526829307380.post-40195851897522859412014-06-12T14:55:00.003+01:002017-07-29T17:27:40.602+01:00Feeler Gauges and Magic CirclesI recently came across <a href="http://brg.a2hosted.com/?page_id=2084" target="_blank">Sunday Times Teaser puzzle, 777</a> on Brian Gladman's <a href="http://brg.a2hosted.com/" target="_blank">Puzzling In Python</a> site:<br />
<blockquote>
<span style="font-size: x-small;"><i>I have half-a-dozen feeler gauges on a ring like keys on a key ring. They are attached in a certain order and by selecting a single gauge or combinations of adjacent gauges it is possible to measure from 1 to 31 thousandths of an inch (thou) inclusive in steps of 1 thou. If I remove two adjacent gauges, replace them with a single gauge and rearrange the five on the ring I can now measure from 1 to 21 thou inclusive in steps of 1 thou with these five gauges by again selecting a single gauge or combinations of adjacent gauges.</i>
</span><br />
<span style="font-size: x-small;"><i><br /></i>
<i>What are the thicknesses of the gauges and the order of arrangement on the ring in each case? (start with gauge of unit thickness and then its thinner neighbour for the sets).</i></span></blockquote>
The puzzle is based on some interesting but relatively obscure mathematics, <a href="http://mathworld.wolfram.com/PerfectDifferenceSet.html" target="_blank">Perfect Difference Sets</a>, described in <a href="http://www.jstor.org/stable/1990067" target="_blank">A Theorem in Finite Projective Geometry and Some Applications to Number Theory</a>, James Singer, Transactions of the American Mathematical Society Vol. 43, No. 3 (May, 1938), pp. 377-385, but initially analysed by the splendidly titled Rev. Thomas P. Kirkman, A.M., F.R.S., Rector of Croft with Southworth, and Honorary Member of the Literary and Philosophical Society of Manchester, in a paper entitled <b><a href="http://archive.org/stream/transactions15chesgoog#page/n166/mode/1up" target="_blank">On the Perfect r-Partitions of $r^2-r+1$,</a></b> Transactions of the Historical Society of Lancashire and Cheshire, vol 9 (1857), pp 127-142.<br />
<br />
The puzzle is slightly contrived, as in reality feeler gauges allow non-adjacent gauges to be combined. The restriction of using only adjacent gauges makes the puzzle equivalent to finding Perfect Difference Sets of length 5 and 6.<br />
<br />
<h2>
Perfect Difference Sets</h2>
<span style="font-family: inherit;"><span style="background-color: white;">A Perfect Difference Set </span></span>(PDS) <span style="background-color: white; font-family: inherit;"> is a set of $k+1$ residues ${a_1,...,a_{k+1}}$ modulo $n=k^2+k+1$ </span><span style="background-color: white; font-family: inherit;">such that every </span><span style="font-family: inherit;">nonzero</span><span style="background-color: white; font-family: inherit;"> </span><span style="font-family: inherit;">residue</span><span style="background-color: white; font-family: inherit;"> can be uniquely expressed in the form $a_i - a_j$</span><br />
<span style="font-family: inherit;"><span style="background-color: white;"><br /></span></span>
<span style="background-color: white;">For example, t</span><span style="background-color: white;">he set {0,1,4,6} is a perfect difference set for $n=3^2+3+1=13$.</span><br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">A PDS can also be expressed as the sequence of gaps between successive numbers in the sorted PDS with </span><span style="background-color: white;">$n=k^2+k+1$ added to the set</span><span style="background-color: white;">. For the PDS {0,1,4,6} the sequence of gaps is 1,3,2,7. If the sequence is wrapped round (as in feeler gauges on a ring), sums of adjacent numbers produce all the numbers from 1 to 13. These sequences will be referred to as magic circles.</span><br />
<span style="background-color: white;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOCovEeoUb31F38P6Eg8wUlZvO-8GJhIwaQnSVxhdHAe6p1sL31yXvhJCzZHldzpbFD4g94mcJMbDB3sWesODhNGSW_qslYzR3tkQPNg9gMGBydkrIK0v8qXmWnyBySqFYJKu-IaFl_nw3/s1600/Example+PDS.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="322" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOCovEeoUb31F38P6Eg8wUlZvO-8GJhIwaQnSVxhdHAe6p1sL31yXvhJCzZHldzpbFD4g94mcJMbDB3sWesODhNGSW_qslYzR3tkQPNg9gMGBydkrIK0v8qXmWnyBySqFYJKu-IaFl_nw3/s1600/Example+PDS.PNG" width="640" /></a></div>
<span style="background-color: white;"><br /></span>
<br />
<span style="background-color: white;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<h2>
<span style="background-color: white;">Magic Circles</span></h2>
<span style="background-color: white;">The article <a href="http://www.jstor.org/stable/2689795" target="_blank">Magic Circles</a>, David A. James, </span>Mathematics Magazine, Vol. 54, No. 3 (May, 1981), pp. 122-125,<span style="background-color: white;"> describes a related puzzle, where</span><span style="background-color: white;"> Evariste Galois challenges 18 soldiers to arrange themselves around a circular pond with circumference 307 (=$17^2+17+1$) paces so that the number of paces between any two soldiers is unique. The soldiers would of course form a PDS to achieve this.</span><br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">The article describes an algorithm to construct a PDS for $p^s+1$ numbers (prime p), using Galois fields (a.k.a. finite fields), and explains the mathematics behind the algorithm. The steps are:</span><br />
<ol><span style="background-color: white;">
<li>Construct the Galois Field $GF(p^{3s})$, by finding an irreducible polynomial over GF(p) of degree $3s$. <br /><br />For s=1 this is straightforward, as a reducible polynomial of degree 3 always has a factor of degree one, so a polynomial $I(x)$ of degree 3 is irreducible if and only if $ I(x) \ne 0$ mod p for $x = 0,...,p-1$.<br /><br />For $s > 1$, finding an irreducible polynomial of degree 3s is more involved, so I cheated and pre-programed some that I obtained from the University of Victoria's <a href="http://theory.cs.uvic.ca/gen/poly.html" target="_blank">Polynomial Generator</a></li>
<li>Find a generator, $g$ of the related cyclic group $GF^*(p^{3s})$.<br /><br />This is best done by making random guesses. I tested guesses by brute force, checking that $g^i \ne 1$ for $1 \leq i \leq p^{3s}/2$. Typically a generator is found in one or two guesses.</li>
<br />
<li>Find elements of the subgroup $GF^*(p^s)$ in $GF^*(p^{3s})$<br /><br />These are the elements $g^i$ for values of $i$ that are multiples of $p^{2s}+p^s+1$ = <span style="font-size: large;">$\frac{p^{3s}-1}{p^s-1}$</span></li>
<li style="text-align: left;">Find integers $i$ that satisfy $g^i - g \in GF^*(p^s)$ .</li>
</span>These integers, modulo $p^{2s}+p^s+1$ , together with zero, form a PDS for $p^s+1$</ol>
<div style="text-align: left;">
<span style="background-color: white;"><br /></span></div>
<div style="text-align: left;">
<span style="background-color: white;">This algorithm will find a single PDS. Other PDS's of the same order can be found by multiplying this PDS by each number between 1 and </span><span style="background-color: white;">$ p^{2s}+p^s+1$ that is coprime to </span><span style="background-color: white;">$p^{2s}+p^s+1$.</span><br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">Each PDS found can be be coverted to a magic circle, which can then be arranged to start with 1 followed by its smaller neighbour. Different PDS's can result in the same magic circle when this rearrangement is applied. </span>For all the cases that I have tested, each magic circle is created by $3s$ different PDSs.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
In fact, Golay, <span style="background-color: white;">in </span><a href="http://jlms.oxfordjournals.org/content/s2-4/4/729.full.pdf" target="_blank">Notes on the Representation of 1,2, ……, N by differences</a>, J. London Math. Soc. (1972) s2-4 (4): 729-734, claims that there are <span style="font-size: large;">$ \frac{\phi(p^{2s}+p^s+1)}{3s}$</span> magic circles.<br />
<br />
<br /></div>
<div style="text-align: left;">
<h2>
Python Code</h2>
<div>
Python code is located <b><a href="https://drive.google.com/folderview?id=0B1sb6hz7jmZ7NVJGVlp6VmlMb28&usp=sharing" target="_blank">in this folder</a>. </b>The folder contains:</div>
<div>
<br /></div>
<div>
<b>finitefield.py</b> - implements Galois fields, representing polynomials $a_0+a_1x+...+a_nx^n$ by a python list $[a_0,a_1,...,a_n]$. The module contains procedures to multiply, divide, add, subtract polynomials modulo a prime and to multiply polynomials modulo an irreducible. The module also contains procedures to find an irreducible polynomial (for a limited range of $p^n$) and to find a generator of $GF^*(p^n)$</div>
</div>
<div>
<br /></div>
<div>
<b>magiccircles.py</b> - implements the algorithm described above and uses the algorithm to solve the Sunday Times Teaser, and to generate magic circles for a range of values including $17^1+1 =18$, Evarise Galois' soldiers. <span style="background-color: white;">My algorithm </span>eliminates reflections, producing <span style="font-size: large;">$ \frac{\phi(p^{2s}+p^s+1)}{6s}$</span> magic circles.</div>
Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-73899749365379011842014-04-26T14:52:00.000+01:002014-08-15T11:28:56.638+01:00Three anglesA puzzle recently posted in Enigmatic Code, <a href="http://enigmaticcode.wordpress.com/2014/04/26/enigma-1329-height-of-ignorance/" target="_blank">Enigma 1329: Height of ignorance</a>, reminded me of a related puzzle: For three squares laid side by side as shown in the diagram, prove tha<span style="font-family: inherit;">t </span> α = β + γ<br />
<span style="background-color: #f9f9f9; font-family: sans-serif; font-size: 17px; line-height: 26.8799991607666px; text-align: center;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhStzV_317le3GcY4X8Wx19pR8b8W8rpRSkCjUyov3GP7i95mGY847uLX-hJgltyFS_3rqFZHy6RsVW-OPB7t5tPsuUREUeBaQBU0kIS9dhiY9e3Bo_PJA2ueFQF3OJmqHFYvuBTApQbIQp/s1600/Three+angles+puzzzle.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhStzV_317le3GcY4X8Wx19pR8b8W8rpRSkCjUyov3GP7i95mGY847uLX-hJgltyFS_3rqFZHy6RsVW-OPB7t5tPsuUREUeBaQBU0kIS9dhiY9e3Bo_PJA2ueFQF3OJmqHFYvuBTApQbIQp/s1600/Three+angles+puzzzle.PNG" height="145" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: inherit;"><br /></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: inherit;">Clearly </span> α = 45<sup>0</sup>. The obvious approach is to use multiple angle formulae, but there is a more elegant geometrical solution.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<center>
<a href="https://drive.google.com/file/d/0B1sb6hz7jmZ7M2RINTNIZW9nM2c/edit?usp=sharing" style="font-family: inherit; line-height: 26.8799991607666px;" target="_blank"><b>Click here to see the geometrical solution</b></a></center>
<br />
The solution of this puzzle can be used to solve Enigma 1329.<br />
<br />
<span style="font-family: inherit;"><span style="background-color: white; line-height: 16.799999237060547px; text-align: justify;">There is also a simple solution using complex numbers which </span></span><span style="background-color: white; line-height: 16.799999237060547px; text-align: justify;">consists of 17 symbols</span><span style="background-color: white; font-family: inherit; line-height: 16.799999237060547px; text-align: justify;">: </span><br />
<span style="background-color: white; font-family: inherit; line-height: 16.799999237060547px; text-align: justify;"><br /></span>
<div style="text-align: center;">
<span style="background-color: white; font-family: inherit; font-size: large; line-height: 16.799999237060547px; text-align: justify;"><b>$(3+i)(2+i) = 5(1+i)$</b></span><br />
<span style="background-color: white; font-family: inherit; font-size: large; line-height: 16.799999237060547px; text-align: justify;"><b><br /></b></span>
<span style="background-color: white; line-height: 16.799999237060547px; text-align: justify;">Does this count as a haiku?</span></div>
<div style="text-align: center;">
<br /></div>
Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-37981025720947979882014-04-07T15:18:00.001+01:002016-11-10T10:17:29.418+00:00Countdown Numbers GameSeveral people have already written programs based on the <a href="http://en.wikipedia.org/wiki/Countdown_%28game_show%29#Numbers_round" target="_blank">Numbers Game</a> from the TV program <a href="http://en.wikipedia.org/wiki/Countdown_%28game_show%29" target="_blank">Countdown</a>, but anyway here is another one, written in Python.<br />
<br />
As has been noted elsewhere, a set of 2 large + 4 small or 1 large + 5 small typically covers a large proportion of target numbers (101 to 999), and there are typically many ways of expressing each target using some or all of the 6 numbers.<br />
<br />
These sets each cover all targets from 101 to 999. The lists of solutions (<img border="0" height="20" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI6OjkW6h0QaMBO1ETM7A8-z0E1lgAchFSQgGJl33GLoR3_juFZ-9dn7_Ge_K3nG_ArHaHaTTWmQW4S88o7QTqdQ3TMWEMna-K3TWUwSrU7qKb6mmyQR9h1zpT-audxI7wEmwOeJuU2-KY/s1600/Link+symbol.jpg" />) contain all targets from 0 until a gap above 999 is reached:<br />
<blockquote>
<span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 5 </span><span style="background-color: white;"> </span><span style="background-color: #6fa8dc;"> 6 </span><span style="background-color: white;"> </span><span style="background-color: #6fa8dc;"> 7 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 8 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 9 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 75 </span></b></span></span> (five consecutive numbers) <a href="https://drive.google.com/file/d/0B1sb6hz7jmZ7aEtQTnRXZ3dGTWs/edit?usp=sharing" target="_blank"><img border="0" height="20" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI6OjkW6h0QaMBO1ETM7A8-z0E1lgAchFSQgGJl33GLoR3_juFZ-9dn7_Ge_K3nG_ArHaHaTTWmQW4S88o7QTqdQ3TMWEMna-K3TWUwSrU7qKb6mmyQR9h1zpT-audxI7wEmwOeJuU2-KY/s1600/Link+symbol.jpg" /></a><br />
<br />
<span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 2 </span><span style="background-color: white;"> </span><span style="background-color: #6fa8dc;"> 5 </span><span style="background-color: white;"> </span><span style="background-color: #6fa8dc;"> 7 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 8 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 9 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 10 </span></b></span></span> (six small numbers) <a href="https://drive.google.com/file/d/0B1sb6hz7jmZ7U2JWU05YdE91ZHM/edit?usp=sharing" target="_blank"><img border="0" height="20" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI6OjkW6h0QaMBO1ETM7A8-z0E1lgAchFSQgGJl33GLoR3_juFZ-9dn7_Ge_K3nG_ArHaHaTTWmQW4S88o7QTqdQ3TMWEMna-K3TWUwSrU7qKb6mmyQR9h1zpT-audxI7wEmwOeJuU2-KY/s1600/Link+symbol.jpg" /></a><br />
<br />
<span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 4 </span><span style="background-color: white;"> </span><span style="background-color: #6fa8dc;"> 7 </span><span style="background-color: white;"> </span><span style="background-color: #6fa8dc;"> 7 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 10 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 25 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;">100</span></b></span></span> (a repeated number) <a href="https://drive.google.com/file/d/0B1sb6hz7jmZ7a1QySUY2VmdwY1k/edit?usp=sharing" target="_blank"><img border="0" height="20" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI6OjkW6h0QaMBO1ETM7A8-z0E1lgAchFSQgGJl33GLoR3_juFZ-9dn7_Ge_K3nG_ArHaHaTTWmQW4S88o7QTqdQ3TMWEMna-K3TWUwSrU7qKb6mmyQR9h1zpT-audxI7wEmwOeJuU2-KY/s1600/Link+symbol.jpg" /></a><br />
<br /></blockquote>
<span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 6 </span><span style="background-color: white;"> </span><span style="background-color: #6fa8dc;"> 7 </span><span style="background-color: white;"> </span><span style="background-color: #6fa8dc;"> 7 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 9 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 9 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;">100</span></b></span></span> is perhaps more noteworthy, covering every target number except the number 367 <a href="https://drive.google.com/file/d/0B1sb6hz7jmZ7bmRubmNlQWEyMVk/edit?usp=sharing" target="_blank"><img border="0" height="20" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI6OjkW6h0QaMBO1ETM7A8-z0E1lgAchFSQgGJl33GLoR3_juFZ-9dn7_Ge_K3nG_ArHaHaTTWmQW4S88o7QTqdQ3TMWEMna-K3TWUwSrU7qKb6mmyQR9h1zpT-audxI7wEmwOeJuU2-KY/s1600/Link+symbol.jpg" /></a><br />
<br />
<span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 8 </span><span style="background-color: white;"> </span><span style="background-color: #6fa8dc;"> 9 </span><span style="background-color: white;"> </span><span style="background-color: #6fa8dc;"> 25 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 50 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 75 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;">100</span></b></span></span> is the best set containing all four large numbers, covering 885 targets <a href="https://drive.google.com/file/d/0B1sb6hz7jmZ7NGxOeV9fVDg0N1k/edit?usp=sharing" target="_blank"><img border="0" height="20" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI6OjkW6h0QaMBO1ETM7A8-z0E1lgAchFSQgGJl33GLoR3_juFZ-9dn7_Ge_K3nG_ArHaHaTTWmQW4S88o7QTqdQ3TMWEMna-K3TWUwSrU7qKb6mmyQR9h1zpT-audxI7wEmwOeJuU2-KY/s1600/Link+symbol.jpg" /></a><br />
<br />
<br />
The code constructs solutions for a few games that have appeared on the TV show:<br />
<ul>
<li><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 3 </span><span style="background-color: white;"> </span><span style="background-color: #6fa8dc;"> 6 </span><span style="background-color: white;"> </span><span style="background-color: #6fa8dc;"> 25 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 50 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 75 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;">100</span></b></span></span> with a target of <span style="font-size: large;"><i style="background-color: black; color: #6aa84f; font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"> </i><span style="color: #6aa84f; font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;"><i style="background-color: black;">952 </i></span></span>, <a href="https://www.youtube.com/watch?v=6mCgiaAFCu8" target="_blank">the James Martin 952 game</a>, which has 2 solutions, (3×75×(6+100)-50)÷25 which was found by the contestant, and 25+(6×75×(3+100))÷50.<br /></li>
<li><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 1 </span><span style="background-color: white;"> </span><span style="background-color: #6fa8dc;"> 4 </span><span style="background-color: white;"> </span><span style="background-color: #6fa8dc;"> 8 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 9 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><span style="color: white;"><span style="color: white; font-family: "trebuchet ms" , sans-serif;"><b><span style="background-color: #6fa8dc;"> 10 </span></b></span></span><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: white;"> </span></b><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: #6fa8dc;"> 50</span></b><b style="color: white; font-family: 'Trebuchet MS', sans-serif;"><span style="background-color: #6fa8dc;"> </span></b> with a target of <span style="font-size: large;"><i style="background-color: black; color: #6aa84f; font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"> </i><span style="color: #6aa84f; font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;"><i style="background-color: black;">500 </i></span></span> ,<a href="https://www.youtube.com/watch?v=d3I2lafp9LY" target="_blank">possibly the easiset game ever?</a> for which my program finds 21 distinct solutions <a href="https://drive.google.com/file/d/0B1sb6hz7jmZ7SHJuRUxOQkJLaVU/edit?usp=sharing" target="_blank"><img border="0" height="20" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI6OjkW6h0QaMBO1ETM7A8-z0E1lgAchFSQgGJl33GLoR3_juFZ-9dn7_Ge_K3nG_ArHaHaTTWmQW4S88o7QTqdQ3TMWEMna-K3TWUwSrU7qKb6mmyQR9h1zpT-audxI7wEmwOeJuU2-KY/s1600/Link+symbol.jpg" /></a>.<br /></li>
<li> Some games solved by <a href="https://www.youtube.com/watch?v=DYW1c41Aw0U" target="_blank">George Ford</a> , one of the best countdown contestants. <a href="https://drive.google.com/file/d/0B1sb6hz7jmZ7TFBndi1hTktMa1k/view?usp=sharing" target="_blank"><img border="0" height="20" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI6OjkW6h0QaMBO1ETM7A8-z0E1lgAchFSQgGJl33GLoR3_juFZ-9dn7_Ge_K3nG_ArHaHaTTWmQW4S88o7QTqdQ3TMWEMna-K3TWUwSrU7qKb6mmyQR9h1zpT-audxI7wEmwOeJuU2-KY/s1600/Link+symbol.jpg" /></a></li>
</ul>
<div>
<br />
<ul>
</ul>
Most of the complexity of the program is to do with minimising brackets,<br />
e.g. <span style="background-color: white; font-family: "courier new" , "courier" , monospace; font-size: 14px;">((</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace; font-size: 14px;">(((</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace; font-size: 14px;">6)+(7))-(9))×(7))×(9))-(100)</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace; font-size: 14px;">=(6+7-9)×7×9-100</span><br />
and avoiding solutions that are essentially the same, e.g. <span style="background-color: white; font-family: "courier new" , "courier" , monospace; font-size: 14px;">152=(6+7-9)×7×9-100</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace; font-size: 14px;">=</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace; font-size: 14px;">7×</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace; font-size: 14px;">(7-9</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace; font-size: 14px;">+6</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace; font-size: 14px;">)×9-100.</span><br />
<span style="background-color: white; font-family: "courier new" , "courier" , monospace; font-size: 14px;"><br /></span>
<span style="background-color: white; font-family: inherit;">The program also excludes "frivolous" solutions that contain an expression that equates to zero, e.g.</span><span style="font-family: "courier new" , "courier" , monospace;"><span style="background-color: white;"> 500 = </span><span style="background-color: white;">(9-8-</span></span><span style="background-color: white; font-family: "courier new" , "courier" , monospace;">1)</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace;">×4</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace;">+50</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace;">×</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace;">100, </span><span style="background-color: white;"><span style="font-family: inherit;">so</span>lutions</span><span style="background-color: white;"> that involve multiplying or dividing by 1, e.g. </span><span style="font-family: "courier new" , "courier" , monospace;"><span style="background-color: white;">500 = </span><span style="background-color: white;">(9-8</span></span><span style="background-color: white; font-family: "courier new" , "courier" , monospace;">)</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace;">×</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace;">50</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace;">×</span><span style="background-color: white; font-family: "courier new" , "courier" , monospace;">100 </span><span style="background-color: white;"><span style="font-family: inherit;">or</span></span><span style="background-color: white; font-family: "courier new" , "courier" , monospace;"> </span><span style="font-family: "courier new" , "courier" , monospace;"><span style="background-color: white;">500 = </span><span style="background-color: white;">50</span><span style="background-color: white;">×</span><span style="background-color: white;">100</span>÷1 </span><span style="background-color: white;">and solutions that have other redundancies</span><span style="font-family: inherit;">, e.g. </span><span style="background-color: white; font-family: monospace;">500 = 9+10×50-1-8</span><span style="font-family: inherit;"><span style="background-color: white;">.</span><span style="background-color: white;"> </span></span><br />
<br />
<blockquote>
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 700px;"><span style="color: blue;"><span style="font-size: 12px; line-height: 14px;"># -*- coding: cp1252 -*-
from itertools import combinations
def wrap(t, condition=True):
return ''.join(["(",t,")"]) if condition else t
def expressions( A, processed=set() ):
""" initially, A is an array of numbers
In recursive calls, A is an array of tuples (n,t,o,x,y,h) where
n is a number,
t is a text expression of n,
o is the last operation applied to x,y to produce n = xoy
h is the history of the expression, containing all the numbers produced in the construction
of the expression
"""
if type(A[0])==int: # inital call, so convert to array of tuples
A = [ (A[i],str(A[i]),"",0,0, frozenset((A[i],)) ) for i in xrange(len(A))]
processed=set()
else: # recursive call, so return the expression formed in the parent
n,t,o,x,y,h = A[0]
if (n,t) not in processed:
yield A[0]
processed.add( (n,t) )
<a name='more'></a>
A.sort()
tA=tuple(A)
if tA in processed:
return
processed.add(tA)
if A[0][0]==0:
return
for p1, p2 in combinations(range(len(A)),2):
p1,p2 = sorted((p1,p2))
n1,t1,o1,x1,y1,h1 = A[p1]
n2,t2,o2,x2,y2,h2 = A[p2]
history=h1|h2
B= A[:]
B.pop(p2)
B.pop(p1)
# don't process x/(y/z) as (x*z)/y produces the same answer
# don't process x/(y*z) as x/y/z produces the same answer
if n2 <> 0 and n1%n2==0 and o2 not in ('*','/') and n1/n2 not in history:
C=[(n1/n2, wrap(t1,o1 not in ('',))+ u'÷' +wrap(t2,o2<>''),"/",n1,n2, frozenset(history|set((n1/n2,))) )]
for x in expressions(C+B, processed):
yield x
if n1 <> 0 and n2%n1==0 and o1 not in ('*','/') and n1<>1 and n2/n1 not in history:
C=[(n2/n1, wrap(t2,o2 not in ('',))+u'÷'+wrap(t1, o1<>''),"/",n2,n1, frozenset(history|set((n2/n1,))) )]
for x in expressions(C+B, processed):
yield x
# don't process x*(y/z), as (x*y)/z produces the same answer
# don't process (x/y)*z as (x*z)/y produces the same answer
if o2<>'/' and o1<>'/' and n2<>1 and n1<>1:
# don't process x*(y*z) if (x>y or x>z)
if not(o2=='*' and (n1>x2 or n1>y2)) and n1*n2 not in history:
C= [(n1*n2,wrap(t1,o1 not in ('','*'))+u'×'+wrap(t2,o2 not in ('','*')),"*",n1,n2, frozenset(history|set((n1*n2,))) )]
for x in expressions(C+B, processed):
yield x
# don't process x-(y-z), as x+y-z produces the same answer
# don't process x-(y+z), as x-y-z produces the same answer
# don't process (x-y)-z if y>z. x-z-y produces the same answer
if n1>=n2:
if o2 not in ('+','-'):
if not( o1=='-' and y1>n2) and n1-n2 not in history:
C=[(n1-n2,wrap(t1,False)+"-"+wrap(t2,o2 not in ('','*','/')),"-",n1,n2, frozenset(history|set((n1-n2,))) )]
for x in expressions(C+B, processed):
yield x
if n2>=n1:
if o1 not in ('+','-'):
if not( o2=='-' and y2>n1) and n2-n1 not in history:
C= [(n2-n1,wrap(t2,False)+"-"+wrap(t1,o1 not in ('','*','/')),"-",n2,n1, frozenset(history|set((n2-n1,))) )]
for x in expressions(C+B, processed):
yield x
# don't process x+(y-z), as (x+y)-z produces the same answer
# don't process (x-z)+y, as (x+y)-z produces the same answer
if o1<>'-' and o2<>'-':
# don't process x+(y+z) if (x>z or x>y)
if not( o2=='+' and (n1>x2 or n1>y2)) and n1+n2 not in history:
C=[(n1+n2,wrap(t1,False)+"+"+wrap(t2,False),"+",n1,n2, frozenset(history|set((n1+n2,))) )]
for x in expressions(C+B, processed):
yield x
#---------------------------------------------------------------------
# find all the solutions matching a target
def allsolutions(A,target):
print "\n", A, "target =",target
for (x,t,o,a,b,h) in expressions(A):
if x==target:
print x,"=",t
# find how many targets in the range 101..999 are covered
def numtargets(A):
results=set()
for (x,t,o,a,b,h) in expressions(A):
results.add(x)
return len(results & set(range(101,1000)))
# write expressions for all targets for a set of numbers A, until a gap above 1000 is found
def alltargets(A):
filename = "Countdown numbers game coverage for "+ ",".join(str(i) for i in sorted(A)) +".txt"
f=open(filename,'w')
lastx=-1
for (x,t) in sorted( (x,t) for (x,t,o,a,b,h) in expressions(A) ):
if x>lastx:
if x >1000 and x<>lastx+1:
break
f.write( (str(x) + "=" + t + "\n").encode('utf8') )
lastx=x
f.close()
if __name__=='__main__':
from random import randint as RI
print "\nThe James Martin 952 game, https://www.youtube.com/watch?v=6mCgiaAFCu8"
allsolutions([100,75,50,25,6,3], 952)
print "\nGeorge Ford, https://www.youtube.com/watch?v=DYW1c41Aw0U"
allsolutions([100,75,50,25,8,2], 318)
allsolutions([100,75,50,25,1,3], 974)
allsolutions([100,75,50,25,1,8], 278)
allsolutions([100,75,50,25,1,2], 940)
allsolutions([50,75,8,5,4,1], 937)
allsolutions([100,75,50,25,4,1], 189)
allsolutions([100,75,50,25,5,6], 814)
print "\nThe easiset game ever? https://www.youtube.com/watch?v=d3I2lafp9LY"
allsolutions([1,4,8,9,10,50], 500)
for i in xrange (5):
target=RI(101,999)
print "\nA game with 7,7,8,8,9,9, target",target
allsolutions([7,7,8,8,9,9], target)
print "\nThese only have a few solutions each"
allsolutions([50,25,1,7,10,10], 976)
allsolutions([100,75,1,1,3,5], 862)
allsolutions([50,75,2,5,5,6], 977)
allsolutions([100,50,10,10,7,1], 284)
allsolutions([75,25,1,4,6,10], 632)
print "\nTest random combinations of 2 top + 4 bottom"
print "until a combination is found that covers all targets 101 to 999"
top2 = [ x for x in combinations([25,50,75,100],2)]
bottom4 = [ x for x in combinations(range(1,11)+range(1,11),4)]
while True:
A= list(top2[RI(0,len(top2)-1)] + bottom4[RI(0,len(bottom4)-1)])
n = numtargets(A)
print A,"covers", n ,"targets"
if n==899:
break
print "\nTest random combinations of 1 top + 5 bottom"
print "until a combination is found that covers all targets 101 to 999"
bottom5 = [ x for x in combinations(range(1,11)+range(1,11),5)]
while True:
A=[RI(1,4)*25]+ list(bottom5[RI(0,len(bottom5)-1)])
n = numtargets(A)
print A,"covers", n ,"targets"
if n==899:
break
# these cover all targets 101..999
alltargets([75,5,6,7,8,9])
alltargets([25, 100, 4, 7, 10, 7])
# these are useful for school game of noughts and crosses
alltargets([2,3,4,5])
alltargets([3,4,5,6])
</span></span>
</pre>
<div>
<br /></div>
</blockquote>
</div>
Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-8118414786535377952014-02-17T17:45:00.000+00:002014-09-14T10:23:20.218+01:00Contest CenterDue to a prolonged spell of wet weather in the UK, and the demise of New Scientist Enigma, I have recently turned my attention to the <a href="http://www.contestcen.com/sitemap.htm" target="_blank">Contest Center</a>, which has a lot of interesting maths puzzles.<br />
<br />
I concentrated on problems that did not yet have any solvers, and managed to solve a few of them. (hints under plain cover to genuine puzzle enthusiasts only)<br />
<br />
<span style="background-color: white;"><span style="color: black; font-family: times; font-size: large;"><a href="http://www.contestcen.com/geom.htm" target="_blank">Point on Circumcircle</a> </span><span style="color: maroon; font-family: times;">(contributed by </span><b style="color: maroon; font-family: times;">Fotos Fotiadis</b><span style="color: maroon; font-family: times;">) </span><br style="color: maroon; font-family: times;" /><span style="color: maroon; font-family: times;"> ABC is a triangle whose smallest angle is A. K is a point on the arc BC of the circumcircle. The perpendicular bisectors of AB and AC intersect the line AK at L and M, respectively. The lines BL and CM intersect at T. Prove that BT+CT=AK. </span></span><br />
<span style="background-color: white; color: maroon; font-family: times;"><br /></span>
<span style="background-color: white;"><span style="color: black; font-family: times; font-size: large;"><a href="http://www.contestcen.com/math.htm" target="_blank">Greatest Divisor</a> </span><span style="color: maroon; font-family: times;">(contributed by </span><b style="color: maroon; font-family: times;">Paul Cleary</b><span style="color: maroon; font-family: times;">) </span><br style="color: maroon; font-family: times;" /><span style="color: maroon; font-family: times;">When </span><b style="color: maroon; font-family: times;">n=8</b><span style="color: maroon; font-family: times;">, the expression </span><b style="color: maroon; font-family: times;">ab(a<sup>n</sup>-b<sup>n</sup>)</b><span style="color: maroon; font-family: times;"> is divisible by 30 for all positive integers </span><b style="color: maroon; font-family: times;">a</b><span style="color: maroon; font-family: times;"> and </span><b style="color: maroon; font-family: times;">b</b><span style="color: maroon; font-family: times;">, and 30 is the greatest such divisor. Find a positive integer </span><b style="color: maroon; font-family: times;">n</b><span style="color: maroon; font-family: times;"> such that the greatest common divisor of </span><b style="color: maroon; font-family: times;">ab(a<sup>n</sup>-b<sup>n</sup>)</b><span style="color: maroon; font-family: times;"> for all positive integers </span><b style="color: maroon; font-family: times;">a</b><span style="color: maroon; font-family: times;"> and </span><b style="color: maroon; font-family: times;">b</b><span style="color: maroon; font-family: times;"> is </span><b style="color: maroon; font-family: times;">n</b><span style="color: maroon; font-family: times;">. </span></span><br />
<span style="background-color: white; color: maroon; font-family: times;"><br /></span>
<span style="background-color: white;"><span style="color: black; font-family: times; font-size: large;"><a href="http://www.contestcen.com/expert.htm" target="_blank">26 Numbers</a> </span><span style="color: maroon; font-family: times;">(Contributed by </span><b style="color: maroon; font-family: times;">Paul Cleary</b><span style="color: maroon; font-family: times;">) </span><br style="color: maroon; font-family: times;" /><span style="color: maroon; font-family: times;">There are infinitely many sets of 26 real numbers where their sum is 200 and the sum of their squares is </span><b style="color: maroon; font-family: times;">S</b><span style="color: maroon; font-family: times;">. The difference between the smallest and largest of the numbers in these sets is 60/13. What is the value of </span><b style="color: maroon; font-family: times;">S</b><span style="color: maroon; font-family: times;">? </span></span><br />
<span style="background-color: white; color: maroon; font-family: times;"><br /></span>
<span style="background-color: white;"><span style="color: black; font-family: times; font-size: large;"><a href="http://www.contestcen.com/expert.htm" target="_blank">Sums of Polynomials</a> </span><span style="color: maroon; font-family: times;"></span><br style="color: maroon; font-family: times;" /><span style="color: maroon; font-family: times;">Let </span><i style="color: maroon; font-family: times;">p<sub>i</sub>(x) = x<sup>2</sup>+m<sub>i</sub>x+n<sub>i</sub></i><span style="color: maroon; font-family: times;"> for </span><i style="color: maroon; font-family: times;">i=1,2,3,4</i><span style="color: maroon; font-family: times;"> be four given polynomials with </span><i style="color: maroon; font-family: times;">m<sub>i</sub></i><span style="color: maroon; font-family: times;"> and </span><i style="color: maroon; font-family: times;">n<sub>i</sub></i><span style="color: maroon; font-family: times;"> integers, and </span><i style="color: maroon; font-family: times;">m<sub>1</sub></i><span style="color: maroon; font-family: times;"> through </span><i style="color: maroon; font-family: times;">m<sub>4</sub></i><span style="color: maroon; font-family: times;"> not all odd. Show that there is an integer </span><i style="color: maroon; font-family: times;">N</i><span style="color: maroon; font-family: times;"> such that any integer </span><i style="color: maroon; font-family: times;">n > N</i><span style="color: maroon; font-family: times;"> can be expressed as the sum </span><nobr style="color: maroon; font-family: times;"><i>p<sub>1</sub>(a<sub>1</sub>)+p<sub>2</sub>(a<sub>2</sub>)+p<sub>3</sub>(a<sub>3</sub>)+p<sub>4</sub>(a<sub>4</sub>)</i></nobr><span style="color: maroon; font-family: times;"> for some integers </span><i style="color: maroon; font-family: times;">a<sub>1</sub></i><span style="color: maroon; font-family: times;"> through </span><i style="color: maroon; font-family: times;">a<sub>4</sub></i><span style="color: maroon; font-family: times;">. </span></span><br />
<span style="background-color: white; color: maroon; font-family: times;"><br /></span>
<span style="background-color: white;"><span style="color: black; font-family: times; font-size: large;"><a href="http://www.contestcen.com/powers.htm" target="_blank">Rational Powers</a> </span><span style="color: black; font-family: times;">(contributing the criterion </span></span><span style="background-color: white; color: maroon; font-family: times;">gcd(a,b,c)=1)</span><span style="background-color: white;"><br style="color: maroon; font-family: times;" /><span style="color: maroon; font-family: times;"> Let x be a rational number x=p/q with q>1 and gcd(p,q)=1. Let a, b and c be positive integers, with a</span><sup style="color: maroon; font-family: times;">x</sup><span style="color: maroon; font-family: times;">+b</span><sup style="color: maroon; font-family: times;">x</sup><span style="color: maroon; font-family: times;">=c</span><sup style="color: maroon; font-family: times;">x</sup><span style="color: maroon; font-family: times;"> and gcd(a,b,c)=1. Prove that a, b and c must be q-th powers, or find a counterexample. </span></span><br />
<span style="background-color: white; color: maroon; font-family: times;"><br /></span>
<br />
<span style="background-color: white;"><span style="color: black; font-family: times; font-size: large;"><a href="http://www.contestcen.com/powers.htm" target="_blank">Repeated Digits </a> </span><span style="color: black; font-family: times;">(not a first to solve, but most solutions found to date)</span></span><br />
<span style="background-color: white; color: maroon; font-family: times;">The square of 88 is 7744, where each digit of the square is repeated. Find additional squares (not ending with 0) where every digit is part of a repeated sequence, such as 11000555544. We will list the number of squares found by each solver. The notation +F indicates that the solver also found an infinite family of solutions. </span><br />
<span style="background-color: white; color: maroon; font-family: times;"><br /></span>
<span style="background-color: white; color: maroon; font-family: times;">Update June 2014:</span><br />
<a href="http://www.contestcen.com/geom.htm" style="font-family: times;" target="_blank"><span style="font-size: large;">Square Heronian</span></a><span style="color: maroon; font-family: times;"> (contributed by</span><b style="color: maroon; font-family: times;"> Lee Morgenstern</b><span style="color: maroon; font-family: times;">) </span><br />
<span style="color: maroon; font-family: times;">A Heronian triangle has integer sides and integer area. Find a Heronian triangles where all 3 sides are squares. [Only one solution is known. Extra credit for anyone who finds a second solution.] </span><span style="background-color: white; color: maroon; font-family: times;"></span><br />
<span style="color: maroon; font-family: times;"><br /></span>
<span style="color: maroon; font-family: times;">Update September 2014:</span><br />
<span style="color: maroon; font-family: times; font-size: large;">** <a href="http://www.contestcen.com/powers.htm" target="_blank">Square Rearranger</a> </span><br />
<span style="color: maroon; font-family: times;">Find the smallest three distinct whole numbers A, B and C such that you can rearrange the digits of A and B to get C</span><sup style="color: maroon; font-family: times;">2</sup><span style="color: maroon; font-family: times;">, the digits of A and C to get B</span><sup style="color: maroon; font-family: times;">2</sup><span style="color: maroon; font-family: times;">, and the digits of B and C to get A</span><sup style="color: maroon; font-family: times;">2</sup><span style="color: maroon; font-family: times;">. [Leading zeroes are not allowed.] </span><span style="color: maroon; font-family: times;"></span><br />
<div>
<br /></div>
Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com7tag:blogger.com,1999:blog-6654130526829307380.post-12638470267888516312014-01-21T10:44:00.003+00:002014-01-21T11:37:23.554+00:00New Scientist Enigma 1354: Sound idea Here is a solution to Enigma 1354 which appeared recently in <a href="http://enigmaticcode.wordpress.com/2014/01/20/enigma-1354-sound-idea/">Enigmatic
Code</a><br />
<br />
The problem is this:<br />
<blockquote>
<i>Joe’s daughter has been asking him for weeks to make a wind
chime. So this week Joe cut a length of stainless steel tubing into 10
lengths from 1 cm to 10 cm in steps of 1 cm. He also cut out a disc from
a sheet of stainless steel and drilled 10 evenly spaced holes round the
perimeter and one in the centre.</i><br />
<br />
<i>Joe hung one tube from each hole and hung the disc up by a thread
from its centre. That was a big mistake as the disc tilted right over.</i><br />
<br />
<i>So Joe rearranged the tubes until the disc balanced perfectly. In
making a note of the lengths of the tubes in order round the disc the
result was an 11-digit number.</i><br />
<br />
<i>What is the smallest of all the 11-digit numbers Joe could have written down?</i></blockquote>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVGlADu8TnU3F9fv86D-Gvjk-amUtameWHENTbqz4sH9tYWV9uQQuPLKdfXuNpjQtnPwTqdOHH1UvOLcg88MxwZg3Yk2UQQbDpD8t8NS_q-bGqGz-r68B_YnGrVLko6VFLXKadGOkxQhit/s1600/Enigma+1354.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVGlADu8TnU3F9fv86D-Gvjk-amUtameWHENTbqz4sH9tYWV9uQQuPLKdfXuNpjQtnPwTqdOHH1UvOLcg88MxwZg3Yk2UQQbDpD8t8NS_q-bGqGz-r68B_YnGrVLko6VFLXKadGOkxQhit/s1600/Enigma+1354.PNG" height="311" width="320" /></a></div>
<br />
In order for the wind chime to balance, moments about the axis <b><i>af</i></b>
must balance<br />
<blockquote>
$ (b+e-g-j)sin(\frac{π}{5}) +
(c+d-h-i)sin(\frac{2π}{5}) = 0 $ ..................... (1)</blockquote>
Noting that $sin( \frac{2π}{5}) = 2 sin(\frac{π}{5})
cos(\frac{π}{5})$ , dividing (1) through by $sin(\frac{π}{5})$<br />
<blockquote>
$ (b+e-g-j) +2 (c+d-h-i)cos(\frac{π}{5}) = 0 $
..................... (2)</blockquote>
Substituting $ cos(\frac{π}{5}) = \frac{(1+\sqrt{5})}{4} $ into (2)<br />
<blockquote>
$ b+e-g-j +\frac{c+d-h-i}{2} +\frac{(c+d-h-i)\sqrt{5}}{2} = 0$</blockquote>
As a,b,...,i,j are all integers,$ c+d-h-i = 0$ and $b+e-g-j +\frac{c+d-h-i}{2} =0$<br />
<br />
So $c+d=h+i$ and $b+e=g+j$<br />
<br />
So knowing five adjacent values, say, a,b,c,d,e, allows the other
five to be deduced:<br />
<blockquote>
$f = 55 - a - (b+c+d+e) - (g+h+i+j) = 55-a-2(b+c+d+e)$</blockquote>
And so on round the circle.<br />
<br />
So, some code:<br />
<blockquote>
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 90%;"><code><span style="color: blue;">
from itertools import permutations as perm
a=10
onetoten=frozenset(range(1,11))
for b,c,d,e in perm(range(1,10),4):
f=55-a-2*(b+c+d+e)
g=55-b-2*(c+d+e+f)
h=55-c-2*(d+e+f+g)
i=55-d-2*(e+f+g+h)
j=55-e-2*(f+g+h+i)
s=(a,b,c,d,e,f,g,h,i,j)
if set(s)==onetoten:
# sanity check
if all( sum(s[i%10] for i in xrange(m,m+4))
==sum(s[i%10] for i in xrange(m+5,m+9))
for m in xrange(10)):
print "solution", a,b,c,d,e,f,g,h,i,j
break</span>
</code></pre>
</blockquote>
Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-656644696530622652013-12-14T11:17:00.000+00:002013-12-14T16:17:39.939+00:00New Scientist Enigma 152: The highways of Genoland revisitedFollowing my post on <a href="http://arthurvause.blogspot.co.uk/2013/12/new-scientist-enigma-152-highways-of.html" target="_blank">The highways of Genoland</a>, Jim Randell <a href="http://enigmaticcode.wordpress.com/2013/12/09/enigma-152-the-highways-of-genoland/#comments" target="_blank">pointed out</a> that the original puzzle had missed a round trip, and that there are actually four round trips. The missing round trip uses highways 1,2,3,4,D (not necessarily in that order).<br />
<br />
I wondered what a solution would look like if the fourth round trip had been included in the original puzzle:<br />
<br />
As before, no pair of cities is connected by both a national and provincial highway. There are two possible configurations of connections that have eight connectors connecting five nodes:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoKW3GAG8bsAqTsXa1qwvpygONok_5Wtw0jKP_AlJAC9Jc8zdrfYPuYy87N0pRMEBuJ5NOzjp_Tqgp6SMPZfo1krzvymK_Ouuvi94HO0pYVFCYQXKAi-gG1YKzEUOt5_zpIko2n2iHg8s6/s1600/P1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoKW3GAG8bsAqTsXa1qwvpygONok_5Wtw0jKP_AlJAC9Jc8zdrfYPuYy87N0pRMEBuJ5NOzjp_Tqgp6SMPZfo1krzvymK_Ouuvi94HO0pYVFCYQXKAi-gG1YKzEUOt5_zpIko2n2iHg8s6/s1600/P1.PNG" width="320" /></a></div>
Configuration A does not provide four round trips, so the five cities are connected in configuration B. We can immediately deduce which city is Geno:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPRigt-oNAAR9TxLR9ALN6Ne7o4-jLNJMas4UNbX47YJBytxEs1EGT7XqwgKYQ3Xr8e1ZduXf5NpIsvSbtwE59kNfMhQ4u5JBI-0PFyW18WH5FkHgvbYYMydBmgaTi0a9T2UHsy3VkQXjg/s1600/p2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPRigt-oNAAR9TxLR9ALN6Ne7o4-jLNJMas4UNbX47YJBytxEs1EGT7XqwgKYQ3Xr8e1ZduXf5NpIsvSbtwE59kNfMhQ4u5JBI-0PFyW18WH5FkHgvbYYMydBmgaTi0a9T2UHsy3VkQXjg/s1600/p2.PNG" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The four round trips 1,3,4,B,C; 1,2,A,C,D; 2,3,A,B,C; 1,2,3,4,D are in some order: </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdVceBXD8XtXG5Wa0hXJDJmUoW-0OlUh0uu2NhVai-jhHmdpAadWxnjDTy7THsK_bYEc_EZon2mK8S98JnwECHCJ1F5kmQqgmJ0Ilh3EFEBEtFeF5TphwAwbB2lSKfel08bPTh77RWSIy2/s1600/p10.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="64" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdVceBXD8XtXG5Wa0hXJDJmUoW-0OlUh0uu2NhVai-jhHmdpAadWxnjDTy7THsK_bYEc_EZon2mK8S98JnwECHCJ1F5kmQqgmJ0Ilh3EFEBEtFeF5TphwAwbB2lSKfel08bPTh77RWSIy2/s1600/p10.PNG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Highways 1,2,3,C appear in three round trips (green). 4,A,B,D appear in two round trips (orange)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLmjrwAqRtGhtxOb91KHxFVbvz8SMD_lRgxG4HhGelT5ioEG-_4LVoY1tA0hpd9ddcNKYh1lwY6S0ZlJk-Z05ypImdqjc3lo849MyENwGxhc5pwa0SDC4XIygurSa321jL6D0JxLmwwCfS/s1600/p11.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLmjrwAqRtGhtxOb91KHxFVbvz8SMD_lRgxG4HhGelT5ioEG-_4LVoY1tA0hpd9ddcNKYh1lwY6S0ZlJk-Z05ypImdqjc3lo849MyENwGxhc5pwa0SDC4XIygurSa321jL6D0JxLmwwCfS/s1600/p11.PNG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<b>Geno is reached by the highways that appear in two round trips, namely 4,A,B,D</b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<br />Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-88620163903103815792013-12-13T14:16:00.002+00:002013-12-13T15:33:04.279+00:00New Scientist Enigma 152: The highways of GenolandThis was a particularly tricky puzzle to solve with a computer algorithm, as demonstrated by <a href="http://enigmaticcode.wordpress.com/2013/12/09/enigma-152-the-highways-of-genoland/" target="_blank">Jim Randell's solution</a>, so here is a manual solution.<br />
<br />
The problem statement is:<br />
<i><br /></i>
<i>The five cities of Genoland are interconnected by four national highways A, B, C and D. They are also independently linked by four provincial highways 1, 2, 3 and 4. Each highway connects two cities and Geno is the only city which can be directly reached from every other city. A round trip of the five cities involves the five highways 1, 3, 4, B and C or 1, 2, A, C and D or 2, 3, A, B and C (not necessarily in the order given).</i><br />
<i><br /></i>
<i>Which of the highways reach Geno?</i><br />
<i><br /></i>
No pair of cities is connected by both a national and provincial highway (this can be deduced from the round trips). There are two possible configurations that have eight highways connecting five cities:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPcmstGNPonVTeWslodCxh43aiPSDTaAe2JaY7Jq0OWl9CN17NyFJcfUUfO15gTLQ4kyc6ONw4DVPS5CARxiFL2HS32vXKUsbM-BWrlC32gCjd86VIg9Yf8OFxO2ZbFs5b0UslUspyNrZh/s1600/P1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPcmstGNPonVTeWslodCxh43aiPSDTaAe2JaY7Jq0OWl9CN17NyFJcfUUfO15gTLQ4kyc6ONw4DVPS5CARxiFL2HS32vXKUsbM-BWrlC32gCjd86VIg9Yf8OFxO2ZbFs5b0UslUspyNrZh/s320/P1.PNG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Configuration A does not provide three round trips, so the five cities are connected in configuration B. <span style="text-align: center;">We can immediately deduce which city is Geno:</span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPuMyAvTGgzmlsmOlzz0PO72tHluSV-NTPDJcidPl-Va8dm43A25a9hcyihpfIyrxaYO_28MZdMDw1WkKISBSii_ULS_JTyWf1CqzQZM3PdAfVRJErhugAMKj57mNtPxOiofOVtdGxq4E8/s1600/p2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="131" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPuMyAvTGgzmlsmOlzz0PO72tHluSV-NTPDJcidPl-Va8dm43A25a9hcyihpfIyrxaYO_28MZdMDw1WkKISBSii_ULS_JTyWf1CqzQZM3PdAfVRJErhugAMKj57mNtPxOiofOVtdGxq4E8/s200/p2.PNG" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The three round trips are: </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihIEaELNrtCvZ44Gl-I7FKBKbV75V1owISCJLKuING_69SQ5g9JICl8-ik8Kiz2mkgXT3xUqhjC4VKnA8hyphenhyphenMIiOkvXl4SFiw-ZFtG-GjDN2wULE-rGGxb2TZavoYR7lkflkUPFipWNOcVA/s1600/p3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="84" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihIEaELNrtCvZ44Gl-I7FKBKbV75V1owISCJLKuING_69SQ5g9JICl8-ik8Kiz2mkgXT3xUqhjC4VKnA8hyphenhyphenMIiOkvXl4SFiw-ZFtG-GjDN2wULE-rGGxb2TZavoYR7lkflkUPFipWNOcVA/s320/p3.PNG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Highway C appears in all three round trips, so we can deduce which highway is C. Highways D and 4 appear in only one round trip each, so we can also deduce 4 and D (national highways are blue, provincial are red)</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD_6GtP3P_ikR4Ufem_lCV2asnNLuQ-sKOEUgGKRkhFczbKgFPrpQc_7iidk2F8rJWuShUT2kR2GJBWFh2YYlZUV3BTrvqwtkdLC8ocm8jgWAXWRAzkcROgds5pL5q0feaMPfzSJEL-GJO/s1600/p5.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD_6GtP3P_ikR4Ufem_lCV2asnNLuQ-sKOEUgGKRkhFczbKgFPrpQc_7iidk2F8rJWuShUT2kR2GJBWFh2YYlZUV3BTrvqwtkdLC8ocm8jgWAXWRAzkcROgds5pL5q0feaMPfzSJEL-GJO/s1600/p5.PNG" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Highway 1 is in the same round trips as highways 4 and D, so we can deduce highway 1:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0WQfssGmwzbmxsRBFTd-eDtl1snNay92F3rdMmhrFpe8p_V5NMDizTVNiu9adM0n_TjguwH0-I3Yn18i8HXgEVpN0N6YcNWQpxug8hOgz5WwfF3HmmP_jKqBFGcqgK52vOHmYPO6_2MQu/s1600/p6.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0WQfssGmwzbmxsRBFTd-eDtl1snNay92F3rdMmhrFpe8p_V5NMDizTVNiu9adM0n_TjguwH0-I3Yn18i8HXgEVpN0N6YcNWQpxug8hOgz5WwfF3HmmP_jKqBFGcqgK52vOHmYPO6_2MQu/s1600/p6.PNG" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
As all cities are connected via provincial highways, the remaining highway from the top city must be a provincial. Similarly, as all cities are connected via national highways the remaining highway connecting the bottom right city must be a national:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKKHG1Vbsi8ugsUnpbuAM_clIqL1OGepfAaTpp_CWNFZ2qCXY63SuzSLv2MFwCC4nNAn5_Euo2k6g8bqNs6r6T2KBY2llA8vRVokSitUJeQ9XB7SIcuRNz5Lz41tCNGda8NEm57NGmDK5l/s1600/p7.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKKHG1Vbsi8ugsUnpbuAM_clIqL1OGepfAaTpp_CWNFZ2qCXY63SuzSLv2MFwCC4nNAn5_Euo2k6g8bqNs6r6T2KBY2llA8vRVokSitUJeQ9XB7SIcuRNz5Lz41tCNGda8NEm57NGmDK5l/s1600/p7.PNG" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
The round trip using highway 4 uses highways 1,3,4,B,C, so we can deduce which highways are B and 3 :</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9YI1bgB6jROR5tozCzSTUL7Ev7Pton2EKUsF2OSTfAvLZo8h9QH3LGAA0sV1swOChH7TP4kKsTZsAOS_E8vTXM3oqEJxwyEeGxEDqip5hSSUvueb6Hg6Term9RZrAIh_HdLk1bCmZex3C/s1600/p8.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="114" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9YI1bgB6jROR5tozCzSTUL7Ev7Pton2EKUsF2OSTfAvLZo8h9QH3LGAA0sV1swOChH7TP4kKsTZsAOS_E8vTXM3oqEJxwyEeGxEDqip5hSSUvueb6Hg6Term9RZrAIh_HdLk1bCmZex3C/s320/p8.PNG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Similarly, the round trip using highway D uses highways 1,2,A,C,D so we can deduce which highways are A and 2 :</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6ncJN8we3yd7nLz6BVw2-4KD-KmngKmC-O9dJhMw5-hyNfN2tNvbfQUxYu_uaYEsoFd-5gl5TxRbxMMKwt85vfDrJeozkvY_ysCoNhC7PEoPKMQmO-00hJiO7qP5v1kdvuukK5SUyoN68/s1600/p9.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="131" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6ncJN8we3yd7nLz6BVw2-4KD-KmngKmC-O9dJhMw5-hyNfN2tNvbfQUxYu_uaYEsoFd-5gl5TxRbxMMKwt85vfDrJeozkvY_ysCoNhC7PEoPKMQmO-00hJiO7qP5v1kdvuukK5SUyoN68/s320/p9.PNG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b>So Geno is reached by highways A,B,D,4</b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="text-align: center;"><br /></span></div>
<br />Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-3984032205624382032013-05-27T16:42:00.000+01:002013-05-27T16:45:28.192+01:00Hamiltonian Cycles on a Square Grid, part 2The algorithm in my <a href="http://arthurvause.blogspot.co.uk/2013/05/constructing-hamiltonian-cycles-on.html" target="_blank">first post</a> on this topic used some of the ideas in <a href="http://www.emis.ams.org/journals/SLC/wpapers/s34erlangen.pdf" style="background-color: white; color: #888888; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px; text-decoration: none;">R. Stoyan and V. Strehl: Enumeration of Hamiltonian Circuits in Rectangular Grids. Journal of Combinatorial Mathematics and Combin.Computing 21 (1996), 197-127</a>, but did not employ the construction technique suggested in their paper.<br />
<br />
Here is a modified algorithm, with vastly improved performance, using most of the construction method suggested by Stoyan and Strehl.<br />
<br />
The algorithm constructs all 1,072 Hamiltonian cycles on a 6 by 6 grid in about 100ms, and all <span style="font-family: inherit;"><span style="background-color: white;">4,638,576 </span></span>Hamiltonian cycles on an 8 by 8 grid in about 20 minutes.<span style="background-color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;"> </span><br />
<br />
Here, the algorithm runs out of steam, as a 10 by 10 grid h<span style="font-family: inherit;">as <span style="background-color: white;">467,260,456,608 cycles </span></span><span style="background-color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;">(Sloane </span><a href="http://oeis.org/A003763" style="background-color: white; color: #888888; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px; text-decoration: none;">A003763</a><span style="background-color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;">)</span><br />
<span style="background-color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;"><br /></span>
<br />
<a href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKsAAAC7CAIAAACVXPnVAAADBUlEQVR4nO3bQW7lMAxEQd3/0s4VzED8bYnV8HIgvBCV7GY9NnsrHWDhETB9BEwfAdNHwPQRMH0ETB8B00fA9BEwfQRMHwHTR8D0ETB9BEwfAdP3WsBajd/OH0hnrfMTAjZO55ECSsU60wKefV/rZXW+DDmuWCcBOgnQSYBOAnQSoJMAnQToJEAnAToJ0EmATgJ0EqCTAJ0E6CRAJwE6SyHHFeskQCcBOgnQSYBOAnQSoJMAnQToJOB3nR1f+p5lAR3/g/qUNzu+ls5WAXGzyU5/A75QHOh81tr9YMubBHR1EtB1WQIIICB+TwIICF6WAAIIiN+TAAKClyWAAALi9ySAgOBlCSCAgPg9CSAgeFkCCCAgfk8CCAhelgACCIjfkwACgpclgAAC4vckgIDgZQkggID4PQkgIHhZAgggIH7Pbwjo+CZ3tgrYuNbLju5sFTD6d+uUzmMEPGvtfrDlzX9dNnBPAggggAACCCCAgFpIspgAAgiIdxJAQLCYAAIIiHcSQECwmAACCIh3EkBAsJgAAgiIdxJAQLCYAAIIiHcSQECwmAACCIh3EkBAsJgAAgiIdxJAQLCYAAIIiHfWBZzypS/79p7pzmsFbNxxbxLwid+tt/dMdxb+9dp7gqY3P3PZUzoJIKDQTMCFnQQQUGgm4MJOAggoNBNwYScBBBSaCbiwkwACCs0EXNhJAAGFZgIu7CSAgEIzARd2EkBAoZmACzsJIKDQTMCFnQQQUGgm4MJOAggoNBNwYScBBBSaCbiwkwACCs0EXNhJAAHV4lO+9GXf3jPdea2AjTvuTQI+8bv19p7pzrqAjcXPWrsfbHmTgK5iAgggIN5JAAHBYgIIICDeSQABwWICCCAg3kkAAcFiAgggIN5JAAHBYgIIICDeSQABwWICCCAg3kkAAcFiAgggIN5JAAHBYgIIICDeSQABwWICCCAg3kkAAdXiyd/GfaaTgMK3cQSc+W3cZzq3/lR24AiYPgKmj4DpI2D6CJg+AqaPgOkjYPoImD4Cpo+A6fsDIWdrj6aDh5UAAAAASUVORK5CYII=" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKsAAAC7CAIAAACVXPnVAAADBUlEQVR4nO3bQW7lMAxEQd3/0s4VzED8bYnV8HIgvBCV7GY9NnsrHWDhETB9BEwfAdNHwPQRMH0ETB8B00fA9BEwfQRMHwHTR8D0ETB9BEwfAdP3WsBajd/OH0hnrfMTAjZO55ECSsU60wKefV/rZXW+DDmuWCcBOgnQSYBOAnQSoJMAnQToJEAnAToJ0EmATgJ0EqCTAJ0E6CRAJwE6SyHHFeskQCcBOgnQSYBOAnQSoJMAnQToJOB3nR1f+p5lAR3/g/qUNzu+ls5WAXGzyU5/A75QHOh81tr9YMubBHR1EtB1WQIIICB+TwIICF6WAAIIiN+TAAKClyWAAALi9ySAgOBlCSCAgPg9CSAgeFkCCCAgfk8CCAhelgACCIjfkwACgpclgAAC4vckgIDgZQkggID4PQkgIHhZAgggIH7Pbwjo+CZ3tgrYuNbLju5sFTD6d+uUzmMEPGvtfrDlzX9dNnBPAggggAACCCCAgFpIspgAAgiIdxJAQLCYAAIIiHcSQECwmAACCIh3EkBAsJgAAgiIdxJAQLCYAAIIiHcSQECwmAACCIh3EkBAsJgAAgiIdxJAQLCYAAIIiHfWBZzypS/79p7pzmsFbNxxbxLwid+tt/dMdxb+9dp7gqY3P3PZUzoJIKDQTMCFnQQQUGgm4MJOAggoNBNwYScBBBSaCbiwkwACCs0EXNhJAAGFZgIu7CSAgEIzARd2EkBAoZmACzsJIKDQTMCFnQQQUGgm4MJOAggoNBNwYScBBBSaCbiwkwACCs0EXNhJAAHV4lO+9GXf3jPdea2AjTvuTQI+8bv19p7pzrqAjcXPWrsfbHmTgK5iAgggIN5JAAHBYgIIICDeSQABwWICCCAg3kkAAcFiAgggIN5JAAHBYgIIICDeSQABwWICCCAg3kkAAcFiAgggIN5JAAHBYgIIICDeSQABwWICCCAg3kkAAdXiyd/GfaaTgMK3cQSc+W3cZzq3/lR24AiYPgKmj4DpI2D6CJg+AqaPgOkjYPoImD4Cpo+A6fsDIWdrj6aDh5UAAAAASUVORK5CYII=" width="181" /></a><br />
<span style="font-family: inherit;">To construct N by N Hamiltonian cycles, the algorithm builds up <span style="background-color: white; line-height: 18px;">"induced subgraphs" (see diagram at left) of an (N-1) by (N-1) square graph one cell at a time, starting with the top row and working across each row in turn.</span></span><br />
<span style="font-family: inherit;"><span style="background-color: white; line-height: 18px;"><br /></span></span>
<span style="font-family: inherit;"><span style="background-color: white; line-height: 18px;"><br /></span></span>
<span style="font-family: inherit;"><span style="background-color: white; line-height: 18px;"><br /></span></span>
<span style="font-family: inherit;"><span style="background-color: white; line-height: 18px;"><br /></span></span>
<span style="font-family: inherit;"><span style="background-color: white; line-height: 18px;"><br /></span></span>
<span style="font-family: inherit;"><span style="background-color: white; line-height: 18px;"><br /></span></span>
<span style="font-family: inherit;"><span style="background-color: white; line-height: 18px;"><br /></span></span>
<span style="font-family: inherit;"><span style="background-color: white; line-height: 18px;"><br /></span></span>
<span style="font-family: inherit;"><span style="background-color: white; line-height: 18px;"><br /></span></span><br />
<span style="font-family: inherit;"><span style="background-color: white; line-height: 18px;">The top row is constructed by observing that the corner cells have to be inside the Hamiltonian Cycle, and that no two outside cells can be adjacent.</span></span><br />
<span style="font-family: inherit;"><span style="background-color: white; line-height: 18px;"><br /></span></span>
<span style="font-family: inherit;"><span style="background-color: white; line-height: 18px;">From then on, cells are added by testing whether a cell can be inside or outside (or both or neither) according to the rule that no 2 by 2 block can be any of these patterns:</span></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0Ji7esFiKPkMvNXADmGARnBvOi_AdsAOCYRtSnRROEHacMa4lthO51EPL0BH4bEg8AvZagSXdmqlK-HR9xaTw5TpMrXeyw9mFk3-T4a0Gsg-67iXvesoL2Q8D6XUMvukMweu5J-R58QCc/s1600/Invalid+patterns.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="65" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0Ji7esFiKPkMvNXADmGARnBvOi_AdsAOCYRtSnRROEHacMa4lthO51EPL0BH4bEg8AvZagSXdmqlK-HR9xaTw5TpMrXeyw9mFk3-T4a0Gsg-67iXvesoL2Q8D6XUMvukMweu5J-R58QCc/s320/Invalid+patterns.PNG" width="320" /></a></div>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkr8GHXst-DzuGA-SleOHXbs3R6AHb_ggnxFfCeb1WYe3CkP_V-fNA6_dXEKThE77RfBNdhlDyqv04qfAiFFDXUxvMdOT8vqCEKR6XqLmvzVoAxRZNDvKse0NTo94WV390Eowiq3FnXv29/s1600/abcd.PNG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkr8GHXst-DzuGA-SleOHXbs3R6AHb_ggnxFfCeb1WYe3CkP_V-fNA6_dXEKThE77RfBNdhlDyqv04qfAiFFDXUxvMdOT8vqCEKR6XqLmvzVoAxRZNDvKse0NTo94WV390Eowiq3FnXv29/s1600/abcd.PNG" /></a><br />
<br />
A 2 by 2 block $a,b,c,d$ will match one of the four patterns iff $a=d$ and $b=c$<br />
<br />
<br />
<br />
<br />
Additional tests check that:<br />
<ul>
<li>no 2 adjacent cells on the perimeter can be outside</li>
<li>the total number of inside and outside cells does not exceed $\frac{N^2-2}{2}$ and $\frac{(N-2)^2}{2}$ respectively</li>
<li>After the completion of a row, all inside cells are connected to the row just completed.</li>
</ul>
<br />
<br />
<span style="background-color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;"><br /></span>
<br />
<h3>
<span style="background-color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;">Python implementation</span></h3>
<div>
<span style="background-color: white; font-family: inherit; line-height: 18px;">Here is the Python code for the algorithm. </span><br />
<span style="background-color: white; font-family: inherit; line-height: 18px;"><br /></span>
<b style="background-color: white; line-height: 18px;">Hamiltonians(N)</b><span style="background-color: white; line-height: 18px;"> yields all the Hamiltonian cycles for an N by N grid.</span><br />
<span style="font-family: inherit;"><b style="background-color: white; line-height: 18px;"></b></span><br />
<a name='more'></a><span style="font-family: inherit;"><b style="background-color: white; line-height: 18px;"><br /></b></span>
<span style="font-family: inherit;"><b style="background-color: white; line-height: 18px;">graph(m)</b><span style="background-color: white; line-height: 18px;"> constructs a rectangular m by m grid graph. Each node is represented by a number $0..m^2-1$</span></span><span style="background-color: white; font-family: inherit; line-height: 18px;">. A dictionary defines the nodes that each node is connected to.</span><br />
<span style="font-family: inherit;"><span style="background-color: white; line-height: 18px;"><br /></span></span><span style="font-family: inherit;"><span style="background-color: white;"><span style="line-height: 18px;"><b>valid(gr,M,grid)</b> determines whether a configuration of outside cells satisfies the conditions described above, by testing each 2 by 2 array of subcells, and by testing that the outside cells are all connected to an outside cell on the perimeter. </span></span></span><br />
<span style="font-family: inherit;"><br style="background-color: white; line-height: 18px;" /></span><span style="font-family: inherit;"><b style="background-color: white; line-height: 18px;">hamiltonian(outside,M)</b><span style="background-color: white; line-height: 18px;"> converts a valid configuration of outside cells on an M by M grid to the equivalent Hamiltonian cycle on an M+1 by M+1 grid.</span></span><br />
<span style="font-family: inherit;"><span aria-readonly="true" class="MathJax" role="textbox" style="background-color: white; border: 0px; direction: ltr; display: inline; float: none; margin: 0px; padding: 0px; white-space: nowrap; word-wrap: normal;"><nobr style="-webkit-transition: none; border: 0px; margin: 0px; max-height: none; max-width: none; padding: 0px; transition: none; vertical-align: 0px;"><span class="math" style="-webkit-transition: none; border: 0px; display: inline-block; margin: 0px; padding: 0px; position: static; transition: none; vertical-align: 0px; width: 4.992em;"><span style="-webkit-transition: none; border: 0px; display: inline-block; height: 0px; margin: 0px; padding: 0px; position: relative; transition: none; vertical-align: 0px; width: 4.068em;"><span style="-webkit-transition: none; border: 0px; clip: rect(1.112em 1000.003em 2.344em -0.49em); left: 0.003em; margin: 0px; padding: 0px; position: absolute; top: -2.153em; transition: none; vertical-align: 0px;"><span class="mrow" style="-webkit-transition: none; border: 0px; display: inline; margin: 0px; padding: 0px; position: static; transition: none; vertical-align: 0px;"><span class="msubsup" style="-webkit-transition: none; border: 0px; display: inline; margin: 0px; padding: 0px; position: static; transition: none; vertical-align: 0px;"><span style="-webkit-transition: none; border: 0px; display: inline-block; height: 0px; margin: 0px; padding: 0px; position: relative; transition: none; vertical-align: 0px; width: 1.297em;"><span style="-webkit-transition: none; border: 0px; left: 0.865em; margin: 0px; padding: 0px; position: absolute; top: -2.522em; transition: none; vertical-align: 0px;"><span style="-webkit-transition: none; border: 0px; display: inline-block; height: 2.159em; margin: 0px; padding: 0px; position: static; transition: none; vertical-align: 0px; width: 0px;"><br /></span></span></span></span></span></span></span></span></nobr></span></span><span style="font-family: inherit;"><span aria-readonly="true" class="MathJax" role="textbox" style="background-color: white; border: 0px; direction: ltr; display: inline; float: none; margin: 0px; padding: 0px; white-space: nowrap; word-wrap: normal;"><nobr style="-webkit-transition: none; border: 0px; margin: 0px; max-height: none; max-width: none; padding: 0px; transition: none; vertical-align: 0px;"><span class="math" style="-webkit-transition: none; border: 0px; display: inline-block; margin: 0px; padding: 0px; position: static; transition: none; vertical-align: 0px; width: 4.992em;"><span style="-webkit-transition: none; border: 0px; display: inline-block; height: 0px; margin: 0px; padding: 0px; position: relative; transition: none; vertical-align: 0px; width: 4.068em;"><span style="-webkit-transition: none; border: 0px; clip: rect(1.112em 1000.003em 2.344em -0.49em); left: 0.003em; margin: 0px; padding: 0px; position: absolute; top: -2.153em; transition: none; vertical-align: 0px;"><span style="-webkit-transition: none; border: 0px; display: inline-block; height: 2.159em; margin: 0px; padding: 0px; position: static; transition: none; vertical-align: 0px; width: 0px;"></span></span></span><span style="-webkit-transition: none; border-left-style: solid; border-width: 0px 0px 0px 0.004em; display: inline-block; height: 1.216em; margin: 0px; overflow: hidden; padding: 0px; position: static; transition: none; vertical-align: -0.072em; width: 0px;"></span></span></nobr></span></span>
<b style="font-family: inherit; line-height: 18px;">find_inside_connected(graph, maxnode, start, pathset,grid)</b><span style="font-family: inherit; line-height: 18px;"> finds all inside cells connected to the start node.</span></div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><b>findHamiltonians(gr, grid,M, x, numoutside ) </b>recursively searches for induced subgraphs</span><br />
<br />
<pre style="background-color: #eeeeee; border-bottom-color: rgb(153, 153, 153); border-bottom-style: dashed; border-bottom-width: 1px; border-image-outset: 0px; border-image-repeat: stretch; border-image-slice: 100%; border-image-source: none; border-image-width: 1; border-top-color: rgb(153, 153, 153); border-top-style: dashed; border-top-width: 1px; overflow: auto; padding-bottom: 5px; padding-top: 5px; width: 700px;"><span style="font-size: 11px; line-height: 13px;">from itertools import combinations as comb
def graph(m): # define a rectangular grid graph m by m
g = { n:set([n+1,n-m,n+m]) & set(xrange(m*m)) for n in xrange(0,m*m,m)}
g.update( { n:set([n-1,n+1,n-m,n+m]) & set(xrange(m*m))
for n in xrange(m*m) if 0 < n%m < m-1 })
g.update({ n:set([n-1,n-m,n+m]) & set(xrange(m*m))
for n in xrange(m-1,m*m,m)})
return g
def printgrid(outside,M):
s="\n"
for i in xrange(M):
for j in xrange(M):
s+= " " if M*i+j in outside else "* "
s+="\n"
print s
def find_inside_connected(graph, maxnode, start, pathset,grid):
pathset.add(start)
for node in graph[start]:
if node < maxnode and grid[node] and node not in pathset:
find_inside_connected(graph, maxnode, node, pathset, grid)
def find_outside_connected(graph, start, pathset,grid):
pathset.add(start)
for node in graph[start]:
if not(grid[node]) and node not in pathset:
find_outside_connected(graph, node, pathset,grid)
def valid(gr,M,grid): # check that there are (M-1)^2 / 2 outside cells connected to perimeter
global perimeter
outside_connected=set()
for s in perimeter:
if not(grid[s]):
find_outside_connected(gr, s, outside_connected, grid)
return len(outside_connected)==((M-1)*(M-1))/2
def hamiltonian(outside,M):
inside = set(range(M*M))-set(outside)
# convert to an M+1 by M+1 array to trace the Hamiltonian
converted = set([x+x/M for x in inside])
N=M+1
ham=[0,1]
pos=1
move=1
while pos != 0:
if move==1: # going right,
if pos-N in converted: move=-N
elif pos in converted: move=+1
else: move=+N
elif move==N: # going down,
if pos in converted: move=1
elif pos-1 in converted: move=+N
else: move=-1
elif move== -N: # going up,
if pos-N-1 in converted: move=-1
elif pos-N in converted: move=-N
else: move=1
elif move== -1: # going left,
if pos-1 in converted: move=N
elif pos-N-1 in converted: move=-1
else: move=-N
else:
raise Exception("no more cases")
pos+=move
ham.append(pos)
if len(ham) != N*N+1 or len(set(ham)) != N*N:
print ham
raise Exception("Invalid Hamiltonian")
return ham
# powerset of an iterable, up to L elements (adapted from itertools recipes)
from itertools import chain, combinations, product
def powerset(iterable, L=None):
if L == None: L = len(iterable)
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(L+1))
def findHamiltonians(gr, grid,M, x, numoutside ):
global MAXOUTSIDE, MAXINSIDE, BOTTOMLEFT, BOTTOMRIGHT
if x-numoutside > MAXINSIDE:
return
if numoutside > MAXOUTSIDE:
return
if x==M*M: # all cells populated, check for a valid configuration
if valid(gr,M,grid):
outside = set([i for i in xrange(M*M) if not grid[i]])
yield hamiltonian(outside,M)
return
if x == BOTTOMLEFT: # bottom corners have to be inside
options=[True]
elif x==BOTTOMRIGHT: # bottom corners have to be inside
if grid[x-M-1] and grid[x-1]==grid[x-M]:
return
else:
options=[True]
elif x > BOTTOMLEFT and not grid[x-1]: # no adjacent outside cells on bottom row
if grid[x-M-1] and not(grid[x-M]):
return
else:
options=[True]
elif x%M == 0: # start of a new row
# check that all inside cells are connected to last completed row
inside_connected = set(i for i in xrange(x-M,x) if grid[i])
for s in xrange(x-M,x):
if grid[s]:
find_inside_connected(gr, x, s, inside_connected, grid)
if inside_connected <> set(i for i in xrange(x) if grid[i]):
return
if not(grid[x-M]) : # no adjacent outside cells on left column
options=[True]
else:
options=[True,False]
#elif x%M == M-1 and not(grid[x-M]) and not(grid[x-1]) and grid[x-M-1] :
# return
else: # avoid an invalid 2 by 2 configuration
if grid[x-1]^grid[x-M]:
options=[True,False]
else:
options = [ not(grid[x-M-1]) ]
for op in options:
grid[x]=op
for f in findHamiltonians(gr,grid,M, x+1, numoutside + (0 if grid[x] else 1)):
yield f
perimeter=set()
def Hamiltonians(N):
global perimeter, MAXOUTSIDE, MAXINSIDE, BOTTOMLEFT, BOTTOMRIGHT
M=N-1
MAXOUTSIDE = (M-1)*(M-1)/2
MAXINSIDE = (M*M+2*M-1)/2
BOTTOMLEFT = M*(M-1)
BOTTOMRIGHT = M*M-1
gr=graph(M)
noncorners = set(range(M*M))-set((0,M-1,M*(M-1),M*M-1))
allnodes=set(range(M*M))
centre = set([x for x in xrange(M*M) if x/M not in (0,M-1) and x%M not in (0,M-1)])
perimeter = allnodes-centre
for p in powerset( range(1,M-1), (M-1)/2 ):
if all( p[i+1] !=p[i]+1 for i in xrange(len(p)-1)):
grid = [True]*(M*M)
for i in p:
grid[i]=False
for f in findHamiltonians(gr,grid,M,M, sum([1 for x in xrange(0,M) if not(grid[x])]) ):
yield f
if __name__=="__main__":
from time import clock
start= clock()
for N in (4,6):
start=clock()
solutions = [h for h in Hamiltonians(N)]
interval=clock()-start
print "N=",N,":", len(solutions),"solutions,",interval, "sec"
print "N=",N,":", len(set([tuple(x) for x in solutions])) , "distinct solutions"
start=clock()
counter=0
for h in Hamiltonians(8):
counter+=1
if counter%10000 == 0:
print counter,"Hamiltonians found,", clock()-start,"sec"
print counter," Hamiltonians for N=8,", clock()-start, "sec"</span><span style="font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px;">
</span></pre>
<div>
<br /></div>
<br />Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-43071890138762741042013-05-21T10:38:00.000+01:002013-05-27T15:41:56.984+01:00Constructing Hamiltonian Cycles on a Square Grid<h2>
Background</h2>
A solution to <a href="http://enigmaticcode.wordpress.com/2013/05/14/enigma-1431-patience/">New
Scientist Enigma puzzle 1431</a> led me to consider how to
generate all <a href="http://mathworld.wolfram.com/HamiltonianCycle.html">Hamiltonian
Cycles</a> for an N by N square grid.<br />
<br />
The obvious way to generate Hamiltonian cycles for any graph is to
find all <a href="http://mathworld.wolfram.com/HamiltonianPath.html">Hamiltonian
paths</a> that end at a node adjacent to the start node. However,
for a 6 by 6 grid, there are 458,696 Hamiltonian paths but only
1,072 Hamiltonian cycles. (Sloane <a href="http://oeis.org/A096969">A096969</a>
and <a href="http://oeis.org/A003763">A003763</a>)<br />
<table border="0" cellpadding="2" cellspacing="2" style="width: 100%px;">
<tbody>
<tr>
<td valign="top">The analysis in <a href="http://www.emis.ams.org/journals/SLC/wpapers/s34erlangen.pdf">
R. Stoyan and V. Strehl: Enumeration of Hamiltonian
Circuits in Rectangular Grids. Journal of Combinatorial
Mathematics and Combin.Computing 21 (1996), 197-127</a>,
identifies an alternative way of identifying Hamiltonian
cycles.<br />
<br />
For example, this figure shows a Hamiltonian Cycle for a 6
by 6 grid.</td>
<td valign="top"><img align="middle" alt="" height="114" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALwAAAC9CAIAAACGd4BZAAAEvElEQVR4nO3csY4kRwwE0fn/n6acBk4uuyOlrKsg2n5ggYHBWvsbx1nO7/9ewDlvjMZZj9E46zEaZz1G46zHaJz1GI2zHqNx1mM0znqMxlmP0TjrMRpnPUbjrMdonPUYjbMeLprfL/iB456f9zwjGnDc85ZosCXdszQacDQrTaPR3DPIMjPVj9RkTaPR3DPIMjPVj9RkTaPR3DPIMjPVj9RkTaPR3DPIMjPVj9RkTaPR3DPIMjPVj9RkTaPR3DPIMjPVj9RkTaPR3DPIMjPVj9RkTaPR3DPIMjPVj9RkTaPR3DPIMjPVj9RkTaPR3DPIMjPVj9RkTaPR3DPIMjPVj9RkTaPR3DPIMjPVj9RkTaPR3DPIMjPVj9RkTaPR3DPIMjPVj/zvzMSX2PMjgywz82ehxL/bOMVMfJE9P54aCWbmwF+FhOkvzVLqfWTcnPnRYMQ0miLTaN5KhxzYaIymwjSat9IhBzYao6kwjeatdMiBjcZoKkyjeSsdcmCjMZoK02jeSocc2GiMpsI0mrfSIQc2GqOpMI3mrXTIgY3GaCpMo3krHXJgozGaCtNo3kqHHNhojKbCNJq30iEHNhqjqTCN5q10yIGNxmgqTKN5Kx1yYKMxmgrTaN5KhxzYaIymwjSat1LywInv5j0/MsgyM38WAid6jKv3/HhqJJgZf2mO2vMjgywz498KpQdOmEbDiLUHTphGw4i1B06YRsOItQdOmEbDiLUHTphGw4i1B06YRsOItQdOmEbDiLUHTphGw4i1B06YRsOItQdOmEbDiLUHTphGw4i1B06YRsOItQdOmEbDiLUHTphGw4i1B06YRsOItQdOmEbDiLUHTphGw4i1B06YRsOItQdOmEbDiLUHTphGw4i1B06YRsOItQdOmEbDiLUHTphGw4i1B06YRsOItQdOmEbDiLUHTphGw4i1B06YRsOItQdOmIFoTvnAucy8NxpwjjO/nhoJZua8aLCHT/WvQsIkd/qxLwyZxcc4xTQazT2DLPNYRnOHaTSaewZZ5rGM5g7TaDT3DLLMYxnNHabRaO4ZZJnHMpo7TKPR3DPIMo9lNHeYRqO5Z5BlHsto7jCNRnPPIMs8ltHcYRqN5p5Blnkso7nDNBrNPYMs81hGc4dpNJp7BlnmsYzmDtNoNPcMssxjGc0dptFo7hlkmccymjtMo9HcM8gyj2U0d5hGo7lnkGVm/rXQKR84l5n3RgPOcebXUyPBzJwXDfbwqf5VSJiBaND50WDELD5wwjQaRqw9cMI0GkasPXDCNBpGrD1wwjQaRqw9cMI0GkasPXDCNBpGrD1wwjQaRqw9cMI0GkasPXDCNBpGrD1wwjQaRqw9cMI0GkasPXDCNBpGrD1wwjQaRqw9cMI0GkasPXDCNBpGrD1wwjQaRqw9cMI0GkasPXDCNBpGrD1wwjQaRqw9cMI0GkasPXDCNBpGrD1wwjQaRqw9cMI0GkasPXDCNBpGrD1wwjQaRqw9cMI0GkasPXDCNBpGrD1wwgxEc/MHTvGeRkN+4BjNNR84xXvyfzE4f/0YjbMeo3HWYzTOeozGWY/ROOsxGmc9RuOsx2ic9RiNsx6jcdZjNM56jMZZj9E46zEaZz3/AB0FfnuxMwpaAAAAAElFTkSuQmCC" width="114" /></td>
</tr>
</tbody>
</table>
<br />
<table border="0" cellpadding="2" cellspacing="2" style="width: 100%px;">
<tbody>
<tr>
<td valign="top">Stoyan and Strehl point out that each cell is
either inside or outside the Hamiltonian Cycle, as shown
here (yellow cells inside, white outside)<br />
<br />
Thus, Hamiltonian Cycles for an N by N graph can be
associated with an "induced subgraph" of an (N-1) by (N-1)
square graph. </td>
<td valign="top"><img align="middle" alt="" height="108" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKsAAAC7CAIAAACVXPnVAAADBUlEQVR4nO3bQW7lMAxEQd3/0s4VzED8bYnV8HIgvBCV7GY9NnsrHWDhETB9BEwfAdNHwPQRMH0ETB8B00fA9BEwfQRMHwHTR8D0ETB9BEwfAdP3WsBajd/OH0hnrfMTAjZO55ECSsU60wKefV/rZXW+DDmuWCcBOgnQSYBOAnQSoJMAnQToJEAnAToJ0EmATgJ0EqCTAJ0E6CRAJwE6SyHHFeskQCcBOgnQSYBOAnQSoJMAnQToJOB3nR1f+p5lAR3/g/qUNzu+ls5WAXGzyU5/A75QHOh81tr9YMubBHR1EtB1WQIIICB+TwIICF6WAAIIiN+TAAKClyWAAALi9ySAgOBlCSCAgPg9CSAgeFkCCCAgfk8CCAhelgACCIjfkwACgpclgAAC4vckgIDgZQkggID4PQkgIHhZAgggIH7Pbwjo+CZ3tgrYuNbLju5sFTD6d+uUzmMEPGvtfrDlzX9dNnBPAggggAACCCCAgFpIspgAAgiIdxJAQLCYAAIIiHcSQECwmAACCIh3EkBAsJgAAgiIdxJAQLCYAAIIiHcSQECwmAACCIh3EkBAsJgAAgiIdxJAQLCYAAIIiHfWBZzypS/79p7pzmsFbNxxbxLwid+tt/dMdxb+9dp7gqY3P3PZUzoJIKDQTMCFnQQQUGgm4MJOAggoNBNwYScBBBSaCbiwkwACCs0EXNhJAAGFZgIu7CSAgEIzARd2EkBAoZmACzsJIKDQTMCFnQQQUGgm4MJOAggoNBNwYScBBBSaCbiwkwACCs0EXNhJAAHV4lO+9GXf3jPdea2AjTvuTQI+8bv19p7pzrqAjcXPWrsfbHmTgK5iAgggIN5JAAHBYgIIICDeSQABwWICCCAg3kkAAcFiAgggIN5JAAHBYgIIICDeSQABwWICCCAg3kkAAcFiAgggIN5JAAHBYgIIICDeSQABwWICCCAg3kkAAdXiyd/GfaaTgMK3cQSc+W3cZzq3/lR24AiYPgKmj4DpI2D6CJg+AqaPgOkjYPoImD4Cpo+A6fsDIWdrj6aDh5UAAAAASUVORK5CYII=" width="100" /></td>
</tr>
</tbody>
</table>
<br />
<table border="0" cellpadding="2" cellspacing="2" style="width: 100%px;">
<tbody>
<tr>
<td valign="top">Stoyan and Strehl show that any induced
subgraph corresponds to a Hamiltonian Cycle if:<br />
<br />
A) It is a tree<br />
<br />
B) No 2 by 2 sub-grid of the extended grid matches one of
the four patterns: <img align="middle" alt="" height="53" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXYAAABfCAIAAABz6Ht4AAAENElEQVR4nO2VQW4cMRDE9v+fdm4+yUFcCNFdDRK+usChBO3nS0QE4zMtICKX8YkRERCfGBEB8YkRERCfGBEB8YkRERCfGBEB8YkRERCfGBEB8YkRERCfGBEB8YkRERCfGBEB8YkRERCfGBEB8YkRERCfGBEBCZ+YTzP/t6BZzGKWv31mXCf7x38ep/40/9kcHUez2HzveOhRfiM1f5qj42gWm+8dDz3Kb6TmT3N0HM1i873joUf5jdT8aY6Oo1lsvnc89Ci/kZo/zdFxNIvN946HHuU3UvOnOTqOZrH53vHQo/xGav40R8fRLDbfOx56lN9IzZ/m6DiaxeZ7x0OP8hup+dMcHUez2HzveOhRfiM1f5qj42gWm+8dDz3Kb6TmT3N0HM1i873joUf5jdT8aY6Oo1lsvnc89Ci/kZo/zdFxNIvN946HHuU3UvOnOTqOZrH53vHQo/xGav40R8fRLDbfOx56lN9IzZ/m6DiaxeZ7x0OP8hup+dMcHUez2HzveOhRfiM1f5qj42gWm+8dDz3Kb6TmT3N0HM1i873joUf5jdT8aY6Oo1lsvnc89Ci/kZo/zdFxNIvN946HHuU3UvOnOTqOZrH53vHQo/xGav40R8fRLDbfOx56lN9IzZ/m6DiaxeZ7x0OP8hup+dMcHUez2HzveOhRfiM1f5qj42gWm+8dDz3Kb6TmT3N0HM1i873joUf5jdT8aY6Oo1lsvnc89Ci/kZo/zdFxNIvN946HHuU3UvOnOTqOZrH53vHQ49NM9slmMYtZvvnFZ8Z1/OmYGO9tjpr3Zrk/Hnp4rkPjvc1R894s98dDD891aLy3OWrem+X+eOjhuQ6N9zZHzXuz3B8PPTzXofHe5qh5b5b746GH5zo03tscNe/Ncn889PBch8Z7m6PmvVnuj4cenuvQeG9z1Lw3y/3x0MNzHRrvbY6a92a5Px56eK5D473NUfPeLPfHQw/PdWi8tzlq3pvl/njo4bkOjfc2R817s9wfDz0816Hx3uaoeW+W++Ohh+c6NN7bHDXvzXJ/PPTwXIfGe5uj5r1Z7o+HHp7r0Hhvc9S8N8v98dDDcx0a722OmvdmuT8eeniuQ+O9zVHz3iz3x0MPz3VovLc5at6b5f546OG5Do33NkfNe7PcHw89PNeh8d7mqHlvlvvjoYfnOjTe2xw1781yfzz08FyHxnubo+a9We6Phx6e69B4b3PUvDfL/fHQw3MdGu9tjpr3Zrk/Hnp4rkPjvc1R894s98dDD891aLy3OWrem+X+eOjhuQ6N9zZHzXuz3B8PPTzXofHe5qh5b5b746GH5zo03tscNe/Ncn889Pg0k32yWcxilm9+8ZlcQRERnxgRAfGJEREQnxgRAfGJEREQnxgRAfGJEREQnxgRAfGJEREQnxgRAfGJEREQnxgRAfGJEREQnxgRAfkDAHqUrm1Zvg0AAAAASUVORK5CYII=" width="210" /></td>
<td valign="top"><img align="middle" alt="" height="131" src="data:image/png;base64,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" width="131" /></td>
</tr>
</tbody>
</table>
<br />
Additionally, there are always $\frac{N^2-2}{2}$ inside cells
and $\frac{(N-2)^2}{2}$ outside cells, and the four corner cells
have to be inside.<br />
<br />
These constrants can be used to find subgraphs that correspond to
Hamiltonian cycles more efficiently than the search of Hamiltonian
paths. For N=6, there are $\binom{(N-1)^2-4}{\frac{(N-2)^2}{2}} =
\binom{21}{8} = 203,490$ combinations of outside cells that need to
be tested.<br />
<br />
However, the algorithm does not scale well. For N=8, there are
$\binom{45}{18} = 1,715,884,494,940$ combinations of outside
cells.<br />
<br />
The performance could be improved by using the observation that
there cannot be 2 contiguous outside cells on the boundary. However
the algorithm as it stands runs in less than 1 second for N=6, and
the suggested improvement would not significantly reduce the number
of cases that would need to be tested for N=8.<br />
<br />
<h2>
Python Implementation</h2>
A Python implementation of an algorithm based on these
constraints is presented below. The search for the four patterns
of 2 by 2 sub-cells does not cover the extended grid, as it turns
out that this is not necessary, at least for the cases N=4 and N=6
(I haven't worked out whether this extends to higher values of N)<br />
<br />
<a name='more'></a><br /><br />
The Python program is composed of a number of functions:<br />
<br />
<blockquote>
<b>graph(m)</b> constructs a rectangular m by m grid graph.
Each node is represented by a number $0..m^2-1$. A dictionary
defines the nodes that each node is connected to.<br />
<b><br />
valid(gr,M,outside,oppmask,perimeter)</b> determines whether a
configuration of outside cells satisfies the conditions
described above, by testing each 2 by 2 array of subcells, and
by testing that the outside cells are all connected to an
outside cell on the perimeter. <b>oppmask</b> is the
pre-calculated set of 2 by 2 subcells<br />
<br />
<b>hamiltonian(outside,M)</b> converts a valid configuration of
outside cells on an M by M grid to the equivalent Hamiltonian
cycle on an M+1 by M+1 grid.<br />
<br />
<b>Hamiltonians(N)</b> yields all the Hamiltonian cycles for an
N by N grid.</blockquote>
<div align="left">
If the program is run stand-alone, it calculates the
Hamiltonian cycles for N=4 and N=6, and prints randomly selected
cycles and induced subgraphs. Here are some examples of induced
subgraphs for N=6 : </div>
<div align="center">
<img align="top" alt="" height="278" src="data:image/png;base64,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" width="277" /></div>
<blockquote>
</blockquote>
<blockquote>
<pre style="-moz-border-bottom-colors: none; -moz-border-left-colors: none; -moz-border-right-colors: none; -moz-border-top-colors: none; background-color: #eeeeee; border-bottom-color: rgb(153, 153, 153); border-bottom-style: dashed; border-bottom-width: 1px; border-image-outset: 0 0 0 0; border-image-repeat: stretch stretch; border-image-slice: 100% 100% 100% 100%; border-image-source: none; border-image-width: 1 1 1 1; border-left-color-ltr-source: physical; border-left-color-rtl-source: physical; border-left-color-value: rgb(153, 153, 153); border-left-style-ltr-source: physical; border-left-style-rtl-source: physical; border-left-style-value: dashed; border-left-width-ltr-source: physical; border-left-width-rtl-source: physical; border-left-width-value: 1px; border-right-color-ltr-source: physical; border-right-color-rtl-source: physical; border-right-color-value: rgb(153, 153, 153); border-right-style-ltr-source: physical; border-right-style-rtl-source: physical; border-right-style-value: dashed; border-right-width-ltr-source: physical; border-right-width-rtl-source: physical; border-right-width-value: 1px; border-top-color: rgb(153, 153, 153); border-top-style: dashed; border-top-width: 1px; color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left-ltr-source: physical; padding-left-rtl-source: physical; padding-left-value: 5px; padding-right-ltr-source: physical; padding-right-rtl-source: physical; padding-right-value: 5px; padding-top: 5px; width: 98%;"><code>from random import randint
from itertools import combinations as comb
def graph(m): # define a rectangular grid graph m by m
g = { n:set([n+1,n-m,n+m]) & set(xrange(m*m)) for n in xrange(0,m*m,m)}
g.update( { n:set([n-1,n+1,n-m,n+m]) & set(xrange(m*m))
for n in xrange(m*m) if 0 < n%m < m-1 })
g.update({ n:set([n-1,n-m,n+m]) & set(xrange(m*m))
for n in xrange(m-1,m*m,m)})
return g
def valid(gr,M,outside,oppmasks,perimeter):
for op in oppmasks:
s = op.mask & outside
if len(s) in (0,4) \
or s == op.oppsA \
or s == op.oppsB:
return False
def find_outside_connected(graph, start, pathset):
pathset.add(start)
for node in graph[start]:
if node in outside and node not in pathset:
find_outside_connected(graph, node, pathset)
outside_connected=set()
for s in perimeter & outside:
find_outside_connected(gr, s, outside_connected)
if len(outside_connected)<((M-1)*(M-1))/2:
return False
return True
def hamiltonian(outside,M):
inside = set(range(M*M))-set(outside)
# convert to an M+1 by M+1 array to trace the Hamiltonian
converted = set([x+x/M for x in inside])
N=M+1
ham=[0,1]
pos=1
move=1
while pos != 0:
if move==1: # going right,
if pos-N in converted: move=-N
elif pos in converted: move=+1
else: move=+N
elif move==N: # going down,
if pos in converted: move=1
elif pos-1 in converted: move=+N
else: move=-1
elif move== -N: # going up,
if pos-N-1 in converted: move=-1
elif pos-N in converted: move=-N
else: move=1
elif move== -1: # going left,
if pos-1 in converted: move=N
elif pos-N-1 in converted: move=-1
else: move=-N
else:
raise Exception("no more cases")
pos+=move
ham.append(pos)
if len(ham) != N*N+1 or len(set(ham)) != N*N:
print ham
raise Exception("Invalid Hamiltonian")
return ham
def Hamiltonians(N):
M=N-1
gr=graph(M)
noncorners = set(range(M*M))-set((0,M-1,M*(M-1),M*M-1))
allnodes=set(range(M*M))
centre = set([x for x in xrange(M*M) if x/M not in (0,M-1) and x%M not in (0,M-1)])
perimeter = allnodes-centre
class Twobytwo: # class to hold the masks for 2 by 2 tests
pass
oppmasks=[]
for i in xrange(M-1):
for j in xrange(M-1):
m=Twobytwo()
m.mask = set((M*i+j,M*i+j+1,M*(i+1)+j,M*(i+1)+j+1))
m.oppsA = set((M*i+j,M*(i+1)+j+1))
m.oppsB = set((M*i+j+1,M*(i+1)+j))
oppmasks.append(m)
for outside in comb(noncorners,((M-1)*(M-1))/2 ):
if valid(gr, M, set(outside),oppmasks, perimeter):
h = hamiltonian(outside,M)
if __name__=="__main__" and randint(0,99)%100==0:
s="\n"
for i in xrange(M):
for j in xrange(M):
s+= " " if M*i+j in outside else "* "
s+="\n"
print s
print h
yield h
if __name__=="__main__":
from time import clock
start= clock()
for N in (4,6):
solutions = [h for h in Hamiltonians(N)]
print "N=",N,":", len(solutions),"solutions"
print "N=",N,":", len(set([tuple(x) for x in solutions])) , "distinct solutions"
print clock()-start, "seconds"
</code></pre>
</blockquote>
<br />Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-63845481549896852452013-05-07T15:51:00.000+01:002013-05-09T14:31:36.455+01:00Dent, Aye Gill Pike<div>
I camped at High Laning campsite in Dent on a very pleasant sunny evening, and next day walked a circuit from Dent along the ridge of Aye Gill Pike.</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5aXyr5jnxpc3D4RmkKLa3wZbbgBToocs0HvPtV1h2Wl6Y5x-wpQolmKJGV3wkx9FXopENE70UkAtx3kPabrBFCwTlWrX9d1a-hU3XKsaWubyYtgXP9eDtotSt4q_nFxo2QGeljVNHX6ZZ/s200/IMG_4540.JPG" style="margin-left: auto; margin-right: auto;" width="200" /></td></tr>
<tr><td class="tr-caption" style="text-align: center;">View from High Laning campsite</td></tr>
</tbody></table>
<img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiABkkEb_KkuS76Hkhx2MdhIveJF0APrizxqRDihpF1pWmJfPIU62m6MOGDitQRodabvuwCu84SDvDxpjns4kWnt7Iu2arG9F9SFekn2o7Z2gvTVqs9JNcuSebbidLAJj0YO9P2MJQACCCd/s200/IMG_4539.JPG" style="text-align: center;" width="200" /><br />
<div class="separator" style="clear: both; text-align: center;">
<span style="text-align: left;"> </span></div>
Although the ridge isn't marked on OS maps as a footpath, it is on access land. There are footpath signs throughout its length and stiles over all walls and fences.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><span style="margin-left: auto; margin-right: auto;"><a href="http://www.bing.com/maps/?v=2&cp=54.294899~-2.443427&lvl=13&dir=0&sty=s&cid=2D836E7B06151FFA!288" target="_blank"><img border="0" height="340" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNl-b1pXXbtjeNaVR7-EJlKVxgzlbYeDah_ZO9wFYfyFi6wmoLXuf7QREtKpDHSseBnjxFM87aP06TjeGOakmbtr8P8ELpEp5WKyNxWa0E63jdwvXie3Ly_n276YQtb-UnQ1dAoKpnh_IT/s640/Dent,+Aye+Gill+Pike.PNG" width="640" /></a></span></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://www.bing.com/maps/?v=2&cp=54.294899~-2.443427&lvl=13&dir=0&sty=s&cid=2D836E7B06151FFA!288" target="_blank">Click for an interactive map</a><br />
<br />
<div style="text-align: left;">
<br />
<br /></div>
</td></tr>
</tbody></table>
<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKJZXUaN1vpXX8f65fQI43PZPe7s_tTObnAhe0RszETCU6rudAzAOz91lTXuFdApDD-In6VJfYgubjTe4kktKRPMYxuvNO5j62s0W2F5rcezeVAVMMmmM4LyKkIVXesDdJnKZxYsyrlSDO/s1600/IMG_4548.JPG" imageanchor="1" style="clear: left; font-size: 13px; margin-bottom: 1em; margin-left: auto; margin-right: auto; text-align: center;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKJZXUaN1vpXX8f65fQI43PZPe7s_tTObnAhe0RszETCU6rudAzAOz91lTXuFdApDD-In6VJfYgubjTe4kktKRPMYxuvNO5j62s0W2F5rcezeVAVMMmmM4LyKkIVXesDdJnKZxYsyrlSDO/s200/IMG_4548.JPG" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Gate on Dales Way</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiO7O7J9DxReN5t_BgwPdF65B3Jzn7jBILHO7guJEsJrJ6CUj7Gor9szq386Bbka7Nq_Q79BZjNpdPOUrOIvJXgzab40G3brl5yGtTjdGxfu_J3a9qiVZWZsdcIJ75EIaF1xw8FLPRmvWew/s1600/IMG_4554.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiO7O7J9DxReN5t_BgwPdF65B3Jzn7jBILHO7guJEsJrJ6CUj7Gor9szq386Bbka7Nq_Q79BZjNpdPOUrOIvJXgzab40G3brl5yGtTjdGxfu_J3a9qiVZWZsdcIJ75EIaF1xw8FLPRmvWew/s200/IMG_4554.JPG" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px; text-align: center;">Mire House</td></tr>
</tbody></table>
Stopping at the village shop in Dent to buy some pasties for lunch, I walked down to the river Dee, following the Dales Way heading West through numerous fields and gates to Ellers, where I took the footbridge across the river and followed the path up through Mire House, Craggs Farm and Hewthwaite, picking up the Dales Way again.<br />
<br />
<span style="font-size: 13px;"><br /></span>
<span style="font-size: 13px;"><br /></span>
<span style="font-size: 13px;"></span><br />
<span style="font-size: 13px;"></span>
Before reaching Millthrop, there are good views of Sedbergh, in front of the Howgills.<br />
<span style="font-size: 13px;"><br /></span>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5QisDHNI8rH8B-C2fc3P4J4-bN1wzttwW0-6-vkoLAStTxCKxtPxHNLJOHqN6Ibl3XRCDJCqFB8Fxf_Qi6o4TZEbKfzF6ZJ23ykrYaKimtt9NbsPA021hPFdbYaJzedlKWccszUfIFofu/s1600/STA_4558_stitch.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5QisDHNI8rH8B-C2fc3P4J4-bN1wzttwW0-6-vkoLAStTxCKxtPxHNLJOHqN6Ibl3XRCDJCqFB8Fxf_Qi6o4TZEbKfzF6ZJ23ykrYaKimtt9NbsPA021hPFdbYaJzedlKWccszUfIFofu/s640/STA_4558_stitch.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Sedbergh and the Howgills</td></tr>
</tbody></table>
<span style="font-size: 13px;"><br /></span>
Turning East just before Millthrop, I followed a footpath that became increasingly indistinct, taking a bearing East across Frostrow to pick up a bridleway on the far side. This section was quite boggy and hard going. A shorter alternative route (shown in green on the map), would avoid this "off path" section.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkioHUzCmtrWmfDFAxkX-7J4HW0VxkhEtF3FAsYEQgTiUw7XpbR2gCZabX40UiQNS9j4FKHBe6kD2Pz8bVbRa1x3oIbrOEAykJknUmcuIaTW3IEZiO7Avyd1aCtdTe5j_F-qMXDhpdXZ8q/s1600/IMG_4565.JPG" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkioHUzCmtrWmfDFAxkX-7J4HW0VxkhEtF3FAsYEQgTiUw7XpbR2gCZabX40UiQNS9j4FKHBe6kD2Pz8bVbRa1x3oIbrOEAykJknUmcuIaTW3IEZiO7Avyd1aCtdTe5j_F-qMXDhpdXZ8q/s200/IMG_4565.JPG" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px; text-align: center;">Aye Gill Pike</td></tr>
</tbody></table>
<br />
From the end of the bridleway, it is a simple matter of following the wall up to the summit of Aye Gill Pike.<br />
<br />
<br />
<div class="separator" style="clear: both; font-size: 13px; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixILVqHbLPPY3qwGhGm1BUk-j0AP2nR8EhqiKQPNxxSSuKIdyvX6ur51jwOFFfx43cOG0h6XuoysPG6YT9M4r1ZL3SS6_LGOA8eUjfGTCXOWMIHgj4vz_lh96gnu7wIVIN5A8405cwxhta/s1600/IMG_4569.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixILVqHbLPPY3qwGhGm1BUk-j0AP2nR8EhqiKQPNxxSSuKIdyvX6ur51jwOFFfx43cOG0h6XuoysPG6YT9M4r1ZL3SS6_LGOA8eUjfGTCXOWMIHgj4vz_lh96gnu7wIVIN5A8405cwxhta/s200/IMG_4569.JPG" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Cowgill Church</td></tr>
</tbody></table>
<br />
From the summit, I followed the wall East to Snaizwold Fell, then followed a ruined wall down to a track which runs past Cowgill Church, and to the Dales Way at Ewegales.<br />
<br />
<br />
<br />
<br />
<br />
<br />
I then followed the Dales Way all the way back to Dent.<br />
<br />
<div style="text-align: left;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEESVwA6j98ahPSWQOFWfOXMBpkc-LNkx6CMzcKnKJdP-A9S4A0Eh61_URx3RxY6Qrqg4-TnAeHH1BTv4-m3nTSOEWqtx0xKHicdCPPTNF1IbF_KivHHPsDA5yd6LhAYa_tasTNm_CTjUe/s1600/IMG_4579.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEESVwA6j98ahPSWQOFWfOXMBpkc-LNkx6CMzcKnKJdP-A9S4A0Eh61_URx3RxY6Qrqg4-TnAeHH1BTv4-m3nTSOEWqtx0xKHicdCPPTNF1IbF_KivHHPsDA5yd6LhAYa_tasTNm_CTjUe/s200/IMG_4579.JPG" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px; text-align: center;">That will teach them!</td></tr>
</tbody></table>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0gpIwuAZTDz2StQBezYseFC7PFvIMV451LBZd8i3FxbZ62FhUpIoUrIPv6DhoByv4H3G9BeKZsSuwx5SPsjMn2cwf8D2JA8ZZXDj4RtQme48PQEgvifnuFuQiVs2fd0OQ84RV25vtJxd8/s1600/IMG_4583.JPG" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0gpIwuAZTDz2StQBezYseFC7PFvIMV451LBZd8i3FxbZ62FhUpIoUrIPv6DhoByv4H3G9BeKZsSuwx5SPsjMn2cwf8D2JA8ZZXDj4RtQme48PQEgvifnuFuQiVs2fd0OQ84RV25vtJxd8/s200/IMG_4583.JPG" width="150" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px; text-align: center;">River Dee</td></tr>
</tbody></table>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDMXXlI1kHawSYrFppodhHBZ_1rw1F4AIsdPVnwFEzac5jTdvAu4ILIUMjJMiTvzVafFn17oDg1ThVPCCkWXVLqD01BBrfC5M8KpdRzHaipAW6wTRMKbbBqCTcBMpQ1gpiIial_x0DrjMc/s1600/IMG_4577.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="155" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDMXXlI1kHawSYrFppodhHBZ_1rw1F4AIsdPVnwFEzac5jTdvAu4ILIUMjJMiTvzVafFn17oDg1ThVPCCkWXVLqD01BBrfC5M8KpdRzHaipAW6wTRMKbbBqCTcBMpQ1gpiIial_x0DrjMc/s200/IMG_4577.JPG" width="200" /></a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWq7UAkUdHxFAQOCb_yEs_RGGTW1lITe_1qZ6ZhtglwtTPJB-pz-MMrPd3vz3N4FHcHJZHJcy8ZxoXFp8NvLwQSvU6Ey5iNRNOhce7G-EJprIrerQpc4PSOI7ZTikZUCv7vye4g_NX_77e/s1600/IMG_4587.JPG" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWq7UAkUdHxFAQOCb_yEs_RGGTW1lITe_1qZ6ZhtglwtTPJB-pz-MMrPd3vz3N4FHcHJZHJcy8ZxoXFp8NvLwQSvU6Ey5iNRNOhce7G-EJprIrerQpc4PSOI7ZTikZUCv7vye4g_NX_77e/s320/IMG_4587.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Enjoying a well-earned retirement from show business</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<br />
<span style="font-size: 13px;"><br /></span>Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-53928898769275096122013-04-30T15:46:00.000+01:002013-05-03T20:39:08.720+01:00Burtersett, Semer Water, AskriggA brief spell of decent weather, so I went up to the Dales to walk
from Burtersett across to Semer Water and Askrigg.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;">
<tbody>
<tr>
<td style="text-align: center;"><a href="http://www.bing.com/maps/?v=2&cp=54.299155%7E-2.107640&lvl=13&dir=0&sty=s&cid=2D836E7B06151FFA%21283&form=LMLTCC" target="_blank"><img alt="" border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzVs2CDXRK9ctqRErYS6Tyqkq74siX7BOo8kfGi7hfhSIZad7DXC3uxI6gk66XVGQjNUshGu0iA4BbxgFWXe_UfhnjKUsCuxzqo4Pifb-1OcvzNf-0foPao676-VdATZr0UawvgOwicKIs/s400/Burtersett,+Semer+Water,+Askrigg.PNG" style="margin-left: auto; margin-right: auto;" title="" width="400" /></a></td>
</tr>
<tr>
<td class="tr-caption" style="text-align: center;"><a href="http://www.bing.com/maps/?v=2&cp=54.299155%7E-2.107640&lvl=13&dir=0&sty=s&cid=2D836E7B06151FFA%21283&form=LMLTCC" target="_blank">Click the map image for an interactive map</a></td>
</tr>
</tbody>
</table>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXbEOEfWVCe2OQa8S2bymJ1XKKDD0g6aT6ENUDV_LGwhM7xKIkH97y-QFpt3FYk00RWNwdJmDA3VLjQ9yN_zRm8S6RUSNlNFqiLmAx9Mbz11MGPkYCfemw118zc9WjQgWdqHcfKwgy2Cvm/s1600/IMG_4422.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXbEOEfWVCe2OQa8S2bymJ1XKKDD0g6aT6ENUDV_LGwhM7xKIkH97y-QFpt3FYk00RWNwdJmDA3VLjQ9yN_zRm8S6RUSNlNFqiLmAx9Mbz11MGPkYCfemw118zc9WjQgWdqHcfKwgy2Cvm/s320/IMG_4422.JPG" width="320" /></a><br />
Parking at the top of Burtersett village, where there is ample
parking space, I set off following the bridleway to Wether Fell.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJwNQlPg8pCYOtwaQRQxU4tla3ssf4nZnjzHgzwkDfeQ_L1lnmYsiw9Yw-5fztKoGfyoH3qzA5JZyJaZDqm7XBl_bsENcZxFLnM7a4wEy86due3FCQ71daz-eOVWCWUTE6t2wH3xnke9Aw/s1600/IMG_4423.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJwNQlPg8pCYOtwaQRQxU4tla3ssf4nZnjzHgzwkDfeQ_L1lnmYsiw9Yw-5fztKoGfyoH3qzA5JZyJaZDqm7XBl_bsENcZxFLnM7a4wEy86due3FCQ71daz-eOVWCWUTE6t2wH3xnke9Aw/s320/IMG_4423.JPG" width="320" /></a><br />
<br />
<br />
<div>
<br /></div>
<div>
<br /></div>
<div>
Crossing the Roman Road, I followed the footpath initially
signposted to Marsett, taking a turning towards Countersett and
Semer Water after a few hundred yards.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdvAwkSxGyMSDlFp0P8HbzG0P2LjuhqIycbkpj9ns2Yq_m67eVNYET1AcvknocJbUlcCR5ztFItRNgwBnuirNKXv0BsHIAKmYGDxNOe-5opqEAKiWfVV6oEsz9vM-NL_4pRBCHpQMlVpQR/s1600/STA_4428_stitch.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdvAwkSxGyMSDlFp0P8HbzG0P2LjuhqIycbkpj9ns2Yq_m67eVNYET1AcvknocJbUlcCR5ztFItRNgwBnuirNKXv0BsHIAKmYGDxNOe-5opqEAKiWfVV6oEsz9vM-NL_4pRBCHpQMlVpQR/s640/STA_4428_stitch.jpg" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
A brief detour into Countersett Village, and then on to Semer Water
for lunch.<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;">
<tbody>
<tr>
<td style="text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsso7vAS9QUsfyLVBO4R7BADmouoFYm40g3MiAGJqOc6kmIFxKvDPKrDoTjF9xYyQnrkmqM55i7b0WC7IjtjXL4uCKakKT87eBhjV_AOqRo4QPrFxOn9i8GRq5Nj1Oifuaem-AT4fRSwq4/s320/IMG_4444.JPG" style="margin-left: auto; margin-right: auto;" width="320" /> </td>
</tr>
<tr>
<td class="tr-caption" style="text-align: center;">Semer Water
feeding into river Bain</td>
</tr>
</tbody>
</table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;">
<tbody>
<tr>
<td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjclXODD4Fnik3wotn1AzQloOqOyRJgm6gZeNL_syrgzCx5802U9yI-s6mEdniySPSa0TbPSDv4gWEaEbm6plPm1FYi7CGmQpTn9Zb2YWeY1HCwZXhMmnmYdLXzeqwWgnOD7hqJG7dXjRBw/s1600/IMG_4447.JPG" imageanchor="1" style="clear: left; display: inline !important; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjclXODD4Fnik3wotn1AzQloOqOyRJgm6gZeNL_syrgzCx5802U9yI-s6mEdniySPSa0TbPSDv4gWEaEbm6plPm1FYi7CGmQpTn9Zb2YWeY1HCwZXhMmnmYdLXzeqwWgnOD7hqJG7dXjRBw/s320/IMG_4447.JPG" width="320" /></a></td>
</tr>
<tr>
<td class="tr-caption" style="text-align: center;">Semer Water</td>
</tr>
</tbody>
</table>
<span style="text-align: center;"> </span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7lBhdmFxTnzg8XJhyphenhyphenj2dzROquMbh20tpUMTzhYzKH-xxv7HiVxxfMELsJxz-Ui8YsPLpFtYava2fhgVhIOsAX8DTZYs3xNi8TtUeR_9rOdsKEk9yABFwplPS01Q9R2rM4xrp03EgXPf0i/s1600/IMG_4454.JPG" imageanchor="1" style="clear: left; display: inline !important; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7lBhdmFxTnzg8XJhyphenhyphenj2dzROquMbh20tpUMTzhYzKH-xxv7HiVxxfMELsJxz-Ui8YsPLpFtYava2fhgVhIOsAX8DTZYs3xNi8TtUeR_9rOdsKEk9yABFwplPS01Q9R2rM4xrp03EgXPf0i/s320/IMG_4454.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px; text-align: center;">River Bain<br />
<div>
<br /></div>
</td></tr>
</tbody></table>
<span style="text-align: center;">After lunch, I followed the river
Bain to Bainbridge, and doubled back just before Bainbridge to climb up to Scar Top, to
avoid walking along the main road. </span><br />
<span style="text-align: center;"><br /></span>
<span style="text-align: center;">There is a dilemma of where to
drop down from Scar Top back to the Ure river - the shorter route
to Askrigg is across a set of stepping stones, but the
stones are likely to be underwater in moderately high water conditions. The
longer option is to drop down to Worton village (blue route on
map) where there is a bridge over the river Ure. From the bridge,
there is a flagstone path through the fields to Askrigg.</span><br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxs4kuBiCM6CIymTYnGckru7tlpFsfBOhnU_MP7NGicxTCbSJ_GJNLGPyqbyh4T_c13xwi9o3JQjRGhYTAPnEAVfQO3G_rWAYWYFyOGVBWobF6gTQYy6YLQhUMxrd0-dpJMnGU1BxRMuD7/s1600/IMG_4464.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;"><img border="0" height="147" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxs4kuBiCM6CIymTYnGckru7tlpFsfBOhnU_MP7NGicxTCbSJ_GJNLGPyqbyh4T_c13xwi9o3JQjRGhYTAPnEAVfQO3G_rWAYWYFyOGVBWobF6gTQYy6YLQhUMxrd0-dpJMnGU1BxRMuD7/s320/IMG_4464.JPG" width="320" /></a><br />
A brief stop at the Kings Arms in Askrigg (once used as the Drovers
in the TV series All Creatures Great and Small), and then following
Skelgill Lane and down to Shaw Cote to cross the Ure at a set of
stepping stones near Catriggs Farm, that are always above
water level.<br />
<br />
<br />
<br />
<br />
Then across the main road and up Mitre Bank Lane to Burtersett.
Altogether a very pleasant circuit.<br />
<br />Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-12847531387534625762013-02-25T09:49:00.001+00:002013-02-27T17:44:15.129+00:00Testing whether a number is a perfect square<h3>
Introduction</h3>
A simple way to test whether a whole number is a perfect square is
to take its square root, square the integer part and compare the
result to the original number. In Python this might be coded as
follows (the +0.5 is to avoid rounding errors) <br />
<blockquote>
<blockquote>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 50%;"><code><span style="color: blue;">from math import sqrt
def issquare(n):
return int(sqrt(n) + 0.5) ** 2 == n</span>
</code></pre>
</blockquote>
</blockquote>
<div>
However, a preliminary test can avoid the need to calculate
the square root for some numbers. Perfect squares always end in
0,1,4,5,6 or 9, so numbers ending in 2,3,7 or 8 could
immediately be eliminated by looking at the remainder after
dividing by 10.</div>
<div>
<br /></div>
<div>
Similarly, a perfect square divided by 16 always leaves a
remainder of 0,1,4 or 9. Numbers with remainders
2,3,5,6,7,8,10,11,12,13,14,15 (75% of numbers) can be eliminated. As 16 is a power of 2, $16=2^4$, the remainder can be obtained in two ways: by division or by finding the last 4 bits by masking. In Python these could be implemented as:
<br />
<br />
<center>
<table border="0" cellpadding="2" cellspacing="2" style="width: 100%px;">
<tbody>
<tr>
<td valign="top"><div style="text-align: center;">
<b>Obtaining remainder by division</b></div>
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 300px;"><code><span style="color: blue;">from math import sqrt
SR16= frozenset((0, 1, 4, 9))
def issquare(n):
</span><span style="color: #351c75;"><b>if n%16 in SR16</b> :</span><span style="color: blue;">
return int(sqrt(n) + 0.5) ** 2 == n
return False</span></code></pre>
</td>
<td valign="top"><div style="text-align: center;">
<b>Obtaining remainder by masking</b></div>
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 300px;"><code><span style="color: blue;">from math import sqrt
SR16= frozenset((0, 1, 4, 9))
def issquare(n):
</span><span style="color: #351c75;"><b>if n & 15 in SR16</b> :</span><span style="color: blue;">
return int(sqrt(n) + 0.5) ** 2 == n
return False</span></code></pre>
</td>
</tr>
</tbody>
</table>
</center>
<div>
<b><span style="background-color: white; font-family: inherit;"><br /></span></b>
<br />
<h3>
<span style="background-color: white; font-family: inherit;"></span>
<b><span style="background-color: white; font-family: inherit;">Which divisor produces the most efficient
pre-test? </span></b></h3>
<span style="background-color: white; font-family: inherit;">Defining $s(n)$ to be the number of</span><span style="font-family: inherit;"><span style="background-color: white;"> possible residues of square numbers modulo n</span><span style="background-color: white;"></span></span><span style="background-color: white; font-family: inherit;">, a
formula for $s(n)$ is derived by<span style="font-family: inherit;"> </span></span><span style="font-family: inherit;"><a href="http://mathdl.maa.org/images/cms_upload/Walter_D22068._Stangl.pdf" target="_blank">Stangl, W. D. "Counting Squares in ℤn,
Math. Mag. 69, 285-289, 1996</a>. The formula</span><span style="background-color: white;"> is summarised in <a href="http://mathworld.wolfram.com/SquareNumber.html" target="_blank">Wolfram Mathworld - Square Number</a>. </span><br />
<div>
<br />
Defining <span style="text-align: center;">$r(n) = $ </span><span style="font-size: large; text-align: center;">$\frac{s(n)}{n}$, </span><br />
<br />
<span style="font-size: small;"></span>we are interested in numbers with small values of
$r(n)$. In <span style="background-color: white;">the
examples above, s(10)=6,</span><span style="background-color: white;"><span style="background-color: white;"> r(10)=0.6, </span>
s(16)=4, r(16)=0.25.</span><br />
<span style="background-color: white;"><br />
</span>
<br />
<div>
</div>
Stangl shows that $s(n)$ is
multiplicative, i.e $s(ab)=s(a)s(b)$ if $a$ and $b$ are
co-prime, so $r(n)$ is also multiplicative, and is therefore
defined by its values for $p^n$ where $p$ is prime. The
following graph shows the value of $r(p^n)$ for primes up to
29<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjb4etJRrXHnW_A-avU163tnG9kEu32PKdg9fdHITNlSntQwC9kDJg2hFw2R9dcYue7MwDA5naCFSsYqmUmCr-kH9XrGqlvwEhyaM0Jy3HBNCjAHwIib6BTGVPGIIPYVlSsLT3KtvHGct8Z/s1600/r(p%5En).PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjb4etJRrXHnW_A-avU163tnG9kEu32PKdg9fdHITNlSntQwC9kDJg2hFw2R9dcYue7MwDA5naCFSsYqmUmCr-kH9XrGqlvwEhyaM0Jy3HBNCjAHwIib6BTGVPGIIPYVlSsLT3KtvHGct8Z/s400/r(p%5En).PNG" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<span style="background-color: white; font-family: inherit;">Values of $r(2^n)$ look much more promising than powers of other
primes, but Stangl's formula shows that </span><span style="background-color: white;">$r(2^n)$ </span><span style="background-color: white;">tends towards $\frac{1}{6}$
as n increases, </span>so there are diminishing returns
in choosing larger values of $2^n$ as a pre-test divisor.<br />
<br /></div>
</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<h3 align="left">
Can other composite divisors produce smaller
values of $r(n)$?</h3>
The above graph shows that for primes
greater than 2, there is no benefit in including a factor of
$p$ higher than $p^2$ in $n$ to reduce $r(n)$. A few powers
of 2 may have a benefit in reducing $r(n)$.<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div>
<span style="background-color: white;"></span>
<br />
<table border="1" cellpadding="2" cellspacing="2" style="width: 100%px;">
<tbody>
<tr>
<td valign="top"><br />
This graph shows $r(n)$ for all values of n below
10,000. We are interested in the values of n at the
lower edge of the graph, highlighted with a blue line.
These are values of $n$ for which <span style="background-color: white;"><br />
</span>
<br />
<blockquote>
$r(n) < r(m)$ for all $m < n$</blockquote>
<br />
<br />
<br /></td>
<td align="center" valign="top"><div class="separator" style="clear: both; text-align: center;">
<a href="http://www.blogger.com/blogger.g?blogID=6654130526829307380" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"></a></div>
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU7HuIoslbjWGEwIZvv8dAjXbBGY-yzbATRRSit7cH-RrH12M0tyd3QX0Sh9dQl3J5K8jhnZRNccFO3IiKyNOJyzEMbuomN71H3p2lmY05RPdMMgAH7-a3NuHbl55HCvXvTkhLZ1FHotK_/s1600/r(n)+below+10000.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="197" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU7HuIoslbjWGEwIZvv8dAjXbBGY-yzbATRRSit7cH-RrH12M0tyd3QX0Sh9dQl3J5K8jhnZRNccFO3IiKyNOJyzEMbuomN71H3p2lmY05RPdMMgAH7-a3NuHbl55HCvXvTkhLZ1FHotK_/s400/r(n)+below+10000.PNG" width="400" /></a> </td>
</tr>
<tr>
<td valign="top" width="40%"><span style="background-color: white;">Defining the set </span><br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;"> $Opt=\{n: r(n) < r(m)$ for all $m < n \}$</span><br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">this
graph shows $r(n)$ values of $n$ in $Opt$ up to
100,000<br />
<br />
Values of $r(n)$ </span><span style="background-color: white;">below the general
trend for $n$ in $Opt$ are highlighted. </span>Their
prime factorisation shows the trend of the numbers:<br />
<br />
16 = <span style="background-color: white;">2</span><sup>4</sup><br />
144 = <span style="background-color: white;">2</span><sup>4</sup>.3<sup>2</sup><br />
720 = <span style="background-color: white;">2</span><sup>4</sup>.3<sup>2</sup>.5<br />
5,040 = <span style="background-color: white;">2</span><sup>4</sup>.3<sup>2</sup>.5.7<br />
55,440 = <span style="background-color: white;">2</span><sup>4</sup>.3<sup>2</sup>.5.7.11</td>
<td valign="top"><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQItJCW4bZe5xqXg7CZY8krE0JUhLFhNxB_j7hA2FnJA4b7u6f0Hi-g5F3w00wlaYYXoIc20P0aT3eaxUTEbOhJTTYbftDW9IUSFEETtprRQLQpHz-Mz11uf3Qfqe6clv5bcxiCi8N7nDR/s1600/r(n)+for+optimal+n.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQItJCW4bZe5xqXg7CZY8krE0JUhLFhNxB_j7hA2FnJA4b7u6f0Hi-g5F3w00wlaYYXoIc20P0aT3eaxUTEbOhJTTYbftDW9IUSFEETtprRQLQpHz-Mz11uf3Qfqe6clv5bcxiCi8N7nDR/s400/r(n)+for+optimal+n.PNG" width="400" /></a></div>
</td>
</tr>
<tr>
<td valign="top" width="40%">Extending this trend, this
graph shows values of r(n) for the following values of
n:<br />
<br />
16 = <span style="background-color: white;">2</span><sup>4</sup><br />
144 = <span style="background-color: white;">2</span><sup>4</sup>.3<sup>2</sup><br />
720 = <span style="background-color: white;">2</span><sup>4</sup>.3<sup>2</sup>.5<br />
5,040 = <span style="background-color: white;">2</span><sup>4</sup>.3<sup>2</sup>.5.7<br />
55,440 = <span style="background-color: white;">2</span><sup>4</sup>.3<sup>2</sup>.5.7.11<br />
720,720 = <span style="background-color: white;">2</span><sup>4</sup>.3<sup>2</sup>.5.7.11.13<br />
12,252,240 = <span style="background-color: white;">2</span><sup>4</sup>.3<sup>2</sup>.5.7.11.13.17
<br />
232,792,560 = <span style="background-color: white;">2</span><sup>4</sup>.3<sup>2</sup>.5.7.11.13.17.19<br />
5,354,228,880 = <span style="background-color: white;">2</span><sup>4</sup>.3<sup>2</sup>.5.7.11.13.17.19.23<br />
<br /></td>
<td align="center" valign="top"><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguiimwoTOvvCvym2N7QqBQjxjIoo8IbZGcXU_hDLG5mCwIYb6Bii8QCL1JyP1q4NnhqtAxt4Sa749LVYBncXDo-yCcGZYHofcCAWXkwCMeJYiyQ5D3YlIpMTHlAEMhB33prZADm0GSFao1/s1600/r(n)+extended.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguiimwoTOvvCvym2N7QqBQjxjIoo8IbZGcXU_hDLG5mCwIYb6Bii8QCL1JyP1q4NnhqtAxt4Sa749LVYBncXDo-yCcGZYHofcCAWXkwCMeJYiyQ5D3YlIpMTHlAEMhB33prZADm0GSFao1/s400/r(n)+extended.PNG" width="400" /></a></div>
</td>
</tr>
</tbody>
</table>
<span style="background-color: white;"></span>$r(n)$ reaches a
tantalisingly small 0.16%, but for n=5,354,228,880 (larger than
2<sup>32</sup>), and for $s(n)=$8,709,120. </div>
<div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h3>
<b>Testing different divisors</b></h3>
The following graph tests the divisors listed above and
divisors of the form $2^n$, by calculating the time to test
all numbers in the range 1 to 10,000,000. For divisors of the form $2^n$ , two forms of Python function are tested, using division and masking to obtain the remainder.<br />
<br />
For comparison, the time taken by the simplest issquare
function is shown in yellow<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEind81fT6cvOc498VMfpBw8W6qRUhWzgSVax3-YKbq1K1lPiGAzPeMaYMRyV1xzSp7oJ5Iv-fldeesGcKx9hMJl6UdzNOvQMh9oM6lJAFqqEf5y9wwed_y9C7_jkn6a70CAL0F_XrOabDjW/s1600/performance+of+issquare.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="432" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEind81fT6cvOc498VMfpBw8W6qRUhWzgSVax3-YKbq1K1lPiGAzPeMaYMRyV1xzSp7oJ5Iv-fldeesGcKx9hMJl6UdzNOvQMh9oM6lJAFqqEf5y9wwed_y9C7_jkn6a70CAL0F_XrOabDjW/s640/performance+of+issquare.PNG" width="640" /></a><br />
<a href="http://www.blogger.com/blogger.g?blogID=6654130526829307380" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="http://www.blogger.com/blogger.g?blogID=6654130526829307380" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><br />
<div align="center">
<div style="text-align: left;">
The graph shows that the performance improves for divisors
of the form $2^m$ up to $2^7$, and then levels out. The
graph also shows that there is no significant advantage in
using masking to calculate a number modulo $2^m$ (blue
points) compared to straightforward division (green points).</div>
<div align="left">
<br />
The performance of the best composites (red points) is
noticably better than the performance of powers of 2
of similar magnitude. The best performance is for D= 55,440
= <span style="background-color: white;">2</span><sup>4</sup>.3<sup>2</sup>.5.7.11, after which the performance degrades.<br />
<br />
<h3>
Pre calculating the residues of squares modulo D<br />
</h3>
The overhead of pre-calculating the <span style="font-family: inherit;"><span style="background-color: white;">residues of square
numbers modulo D needs to considered when choosing the
pre-test divisor.<br />
<br />
Using the following algorithm, the table shows the time
taken to generate the set of residues of squares modulo
n. The table shows that the set of square residues mod
55,440 can be calculated in 2ms </span></span><br />
<br />
<div>
<div align="center">
<div align="left">
<table border="1" cellpadding="2" cellspacing="2" style="width: 100%px;"><tbody>
<tr><td valign="middle"><pre style="-moz-border-bottom-colors: none; -moz-border-left-colors: none; -moz-border-right-colors: none; -moz-border-top-colors: none; background-color: #eeeeee; border-bottom-color: rgb(153, 153, 153); border-bottom-style: dashed; border-bottom-width: 1px; border-image-outset: 0 0 0 0; border-image-repeat: stretch stretch; border-image-slice: 100% 100% 100% 100%; border-image-source: none; border-image-width: 1 1 1 1; border-top-color: rgb(153, 153, 153); border-top-style: dashed; border-top-width: 1px; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-top: 5px; width: 100%;"><span style="color: blue;">SR={0}
D=1
for b in [2**4,3**2,5,7,11]:
squares_mod_b = set([(x*x)%b for x in range(b)])
SR = set([ r + n*D for r in SR for n in range(b)
if (r+n*D)%b in squares_mod_b ])
D*=b<b>
</b></span></pre>
</td><td valign="top"><table border="1" cellpadding="1" cellspacing="1" style="border-collapse: collapse; height: 184px; width: 372px;">
<tbody>
<tr align="center" height="60" style="height: 45pt;"><td class="xl64" height="60" style="height: 45pt; width: 56pt;" width="75"><small><span style="font-family: Arial;">Factor introduced</span></small></td><td class="xl66" style="width: 80pt;" valign="middle" width="40"><small><span style="font-family: Arial;"><span style="mso-spacerun: yes;"> </span>D<span style="mso-spacerun: yes;"> </span></span></small></td><td class="xl64" style="width: 48pt;" width="64"><small><span style="font-family: Arial;">r(D)</span></small></td><td align="center" class="xl64" style="width: 70pt;" width="40"><small><span style="font-family: Arial;">s(D)</span></small></td><td align="center" class="xl64" style="width: 87pt;" width="116"><small><span style="font-family: Arial;">Time to generate residues of squares<br /> (ms)</span></small></td></tr>
<tr align="center" height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt;"><small><span style="font-family: Arial;">16</span></small></td><td class="xl68" valign="middle" width="40"><small><span style="font-family: Arial;"><span style="mso-spacerun: yes;"> </span>16</span></small></td><td class="xl69"><small><span style="font-family: Arial;">25.00%</span></small></td><td align="center" class="xl68" width="40"><small><span style="font-family: Arial;"><span style="mso-spacerun: yes;"> </span>4</span></small></td><td align="center" class="xl71"><small><span style="font-family: Arial;"><span style="mso-spacerun: yes;"> </span>0.01</span></small></td></tr>
<tr align="center" height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt;"><small><span style="font-family: Arial;">9</span></small></td><td class="xl68" valign="middle" width="40"><small><span style="font-family: Arial;">144</span></small></td><td class="xl69"><small><span style="font-family: Arial;">11.11%</span></small></td><td align="center" class="xl68" width="40"><small><span style="font-family: Arial;"><span style="mso-spacerun: yes;"> </span>16</span></small></td><td align="center" class="xl71"><small><span style="font-family: Arial;"><span style="mso-spacerun: yes;"> </span>0.12</span></small></td></tr>
<tr align="center" height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt;"><small><span style="font-family: Arial;">5</span></small></td><td class="xl68" valign="middle" width="40"><small><span style="font-family: Arial;">720</span></small></td><td class="xl69"><small><span style="font-family: Arial;">6.67%</span></small></td><td align="center" class="xl68" width="40"><small><span style="font-family: Arial;"><span style="mso-spacerun: yes;"> </span>48</span></small></td><td align="center" class="xl71"><small><span style="font-family: Arial;"><span style="mso-spacerun: yes;"> </span>0.23</span></small></td></tr>
<tr align="center" height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt;"><small><span style="font-family: Arial;">7</span></small></td><td class="xl68" valign="middle" width="40"><small><span style="font-family: Arial;"><span style="mso-spacerun: yes;"> </span>5,040</span></small></td><td class="xl69"><small><span style="font-family: Arial;">3.81%</span></small></td><td align="center" class="xl68" width="40"><small><span style="font-family: Arial;"><span style="mso-spacerun: yes;"> </span>192</span></small></td><td align="center" class="xl71"><small><span style="font-family: Arial;"><span style="mso-spacerun: yes;"> </span>0.53</span></small></td></tr>
<tr height="20" style="height: 15pt;"><td align="center" class="xl67" height="20" style="height: 15pt;"><small><span style="font-family: Arial;">11</span></small></td><td align="center" class="xl68" valign="middle" width="40"><small><span style="font-family: Arial;"><span style="mso-spacerun: yes;"> </span>55,440</span></small></td><td align="center" class="xl69"><small><span style="font-family: Arial;">2.08%</span></small></td><td align="center" class="xl68" width="40"><small><span style="font-family: Arial;"><span style="mso-spacerun: yes;"> </span>1,152</span></small></td><td align="center" class="xl71"><small><span style="font-family: Arial;"><span style="mso-spacerun: yes;"> </span>2.01</span></small></td></tr>
</tbody>
</table>
</td>
</tr>
</tbody></table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<span style="font-family: inherit;"><span style="background-color: white;"><br />
We can now define algorithms with the best pre-test. Two
options are presented, one with a hard coded set of
square residues, and one with a calculated set.<br />
<br />
$s(720)=48$, which is a reasonable number of square residues to
hard-code into an algorithm. An implementation of
issquare using D=720 is:</span></span><br />
<blockquote>
<blockquote>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><span style="color: blue;">from math import sqrt
SR = frozenset([0,1,4,385,324,649,256,144,145,121,580,409,576,25,640,265,\
544,289,180,676,369,169,304,49,436,9,441,36,64,160,196,481,\
585,484,81,340,625,601,225,100,16,529,361,496,241,400,244,505])
def issquare(n):
if n%720 in SR :
return int(sqrt(n) + 0.5) ** 2 == n
return False</span></code></pre>
</blockquote>
</blockquote>
<br />
An implementation using D=55,440, with the square residues
being constructed dynamically:<br />
<blockquote>
<blockquote>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><code></code><span style="color: blue;">from math import sqrt
SR={0}
D=1
for b in [2**4,3**2,5,7,11]:
squares_mod_b = set([(x*x)%b for x in range(b)])
SR = set([ r + n*D for r in SR for n in range(b)
if (r+n*D)%b in squares_mod_b ])
D*=b
def issquare(n):
if n%D in SR:
return int(sqrt(n) + 0.5) ** 2 == n
return False</span></code></pre>
</blockquote>
</blockquote>
For a further increase in speed of approximately 33%, at the expense of readability, function calls could be replaced with in-line code, for example:<br />
<br />
<center>
<table border="0" cellpadding="2" cellspacing="2" style="width: 100%px;">
<tbody>
<tr>
<td valign="top"><div style="text-align: center;">
<b>Function calls</b></div>
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 200px;"><span style="color: blue;">count=0
for n in xrange(10000000):</span>
<span style="color: blue;"> if </span><span style="color: red;">issquare(n)</span><span style="color: blue;">:</span>
<span style="color: blue;"> count+=1</span></pre>
</td>
<td valign="top"><div style="text-align: center;">
<b>In-line code</b></div>
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 400px;"><span style="color: blue;">count=0
for n in xrange(10000000):</span>
<span style="color: blue;"> if </span><span style="color: red;">n%D in SR and int(sqrt(n) + 0.5) ** 2 == n</span><span style="color: blue;">:</span>
<span style="color: blue;"> count+=1</span>
</pre>
</td>
</tr>
</tbody>
</table>
</center>
<div>
</div>
<br />
<br />Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-84301705901776723012013-02-15T17:13:00.001+00:002013-02-18T10:32:39.254+00:00Enigma 1736, or solving $x^3=x$ mod $10^N$The problem posed by <a href="http://www.newscientist.com/article/mg21729041.800-enigma-number-1736.html">New
Scientist Enigma 1736</a> was to find the largest 4 digit number
with all digits different whose cube has the same last 4 digits as
the original number.<br />
<br />
Generalising the problem to finding an N digit number whose cube has
the same last N digits as the original number, i.e. solutions of
$x^3=x$ mod $10^N$, (without the constraint of all digits being
different) we can rewrite the equation as<br />
<br />
<div align="center">
$x^3-x = (x-1)x(x+1)=0$ mod $10^N$<br />
<br />
<div align="left">
For $N$ $\geq$ $3$ there are always fifteen solutions, one for each of the cells in the table. Five (in grey) have
an immediate solution, the other ten can be found by solving three linear diophantine equations (red, green and blue).<br />
<br />
<table align="center" border="1" cellpadding="1" cellspacing="2" style="border-collapse: collapse; height: 302px; width: 750px;">
<tbody>
<tr height="20" style="height: 15.0pt;">
<td class="xl63" style="border-left: none; border-top: none;"></td>
<td valign="middle"><br /></td>
<td align="center" bgcolor="#cccccc" class="xl63" style="border-left: none; border-top: none;"><b>$5^N | (x-1)$</b></td>
<td align="center" bgcolor="#cccccc" class="xl63" style="border-left: none; border-top: none;"><b>$5^N |x $</b></td>
<td align="center" bgcolor="#cccccc" class="xl63" style="border-left: none; border-top: none;"><b>$5^N | (x+1)$ </b></td>
</tr>
<tr height="40" style="height: 30.0pt;">
<td bgcolor="#cccccc" class="xl64" style="border-left: none; border-top: none; width: 97pt;"> $2^N | (x-1) $</td>
<td align="center" bgcolor="#cccccc" valign="middle">$2|(x+1)$</td>
<td align="center" class="xl63" style="border-left: none; border-top: none;"> <span style="color: #666666;">$1$</span></td>
<td align="center" class="xl63" style="border-left: none; border-top: none;"> $(r$ mod $2^N)5^N$<br />
<span style="color: #3366ff;">$r5^N+s2^N=1$</span></td>
<td align="center" class="xl63" style="border-left: none; border-top: none;">$2(r$ mod $2^{N-1})5^N-1$<br />
<span style="color: #33cc00;">$r5^N+s2^{N-1}=1$</span></td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td bgcolor="#cccccc" class="xl64" style="border-left: none; border-top: none; width: 97pt;">$2^N| x $</td>
<td align="center" bgcolor="#cccccc" valign="middle"><br /></td>
<td align="center" class="xl63" style="border-left: none; border-top: none;"> $10^N-(r$ mod $2^N)5^N+1$<br />
<span style="color: #3333ff;">$r5^N+s2^N=1$</span></td>
<td align="center" class="xl63" style="border-left: none; border-top: none;"><span style="color: #666666;">$0$ </span></td>
<td align="center" class="xl63" style="border-left: none; border-top: none;"> $(r$ mod $2^N)5^N-1$<br />
<span style="color: #3333ff;">$r5^N+s2^N=1$</span></td>
</tr>
<tr height="40" style="height: 30.0pt;">
<td bgcolor="#cccccc" class="xl64" style="border-left: none; border-top: none; width: 97pt;">$2^N| (x+1)$</td>
<td align="center" bgcolor="#cccccc" valign="middle">$2 |
(x-1)$</td>
<td align="center" class="xl63" style="border-left: none; border-top: none;">$10^N-2(r$ mod $2^{N-1})5^N+1$<br />
<span style="color: #33cc00;">$r5^N+s2^{N-1}=1$</span> </td>
<td align="center" class="xl63" style="border-left: none; border-top: none;">$10^N-(r$ mod $2^N)5^N$<br />
<span style="color: #3366ff;">$r5^N+s2^N=1$</span></td>
<td align="center" class="xl63" style="border-left: none; border-top: none;"><span style="color: #666666;">$10^N-1$ </span></td>
</tr>
<tr>
<td bgcolor="#666666" height="5" valign="top"><br /></td>
<td align="center" bgcolor="#666666" valign="middle"><br /></td>
<td bgcolor="#666666" height="5" valign="top"><br /></td>
<td bgcolor="#666666" height="5" valign="top"><br /></td>
<td bgcolor="#666666" height="5" valign="top"><br /></td>
</tr>
<tr height="40" style="height: 30.0pt;">
<td bgcolor="#cccccc" class="xl64" style="border-left: none; border-top: none; width: 97pt;">$2^{N-1}| (x-1)$</td>
<td align="center" bgcolor="#cccccc" valign="middle">$ 2 |
(x+1)$</td>
<td align="center" class="xl63" style="border-left: none; border-top: none;"><span style="color: #666666;"> $5^N 2^{N-1}+1$</span></td>
<td align="center" class="xl63" style="border-left: none; border-top: none;">$(r$ mod $2^{N-1})5^N$ <span style="color: #33cc00;"><br />
$r5^N+s2^{N-1}=1$</span></td>
<td align="center" class="xl63" style="border-left: none; border-top: none;">$2(r$ mod $2^{N-2})5^N-1$<br />
<span style="color: red;">$r5^N+s2^{N-2}=1$</span></td>
</tr>
<tr height="40" style="height: 30.0pt;">
<td bgcolor="#cccccc" class="xl64" style="border-left: none; border-top: none; width: 97pt;">$2^{N-1}| (x+1)$</td>
<td align="center" bgcolor="#cccccc" valign="middle">$2 |
(x-1)$</td>
<td align="center" class="xl63" style="border-left: none; border-top: none;"> $10^N-2(r$ mod $2^{N-2})5^N+1$<br />
<span style="color: red;">$r5^N+s2^{N-2}=1$</span></td>
<td align="center" class="xl63" style="border-left: none; border-top: none;"><span style="color: #33cc00;"><span style="color: black;">$10^N-(r$ mod $2^{N-1})5^N$</span><br />
$r5^N+s2^{N-1}=1$ </span></td>
<td align="center" class="xl63" style="border-left: none; border-top: none;"><span style="color: #666666;"> $5^N 2^{N-1}-1$</span></td>
</tr>
</tbody>
</table>
<br />
<br /></div>
</div>
<div align="center">
Complementary pairs of solutions, $x$ and $10^N-x$ occur on
opposite sides, as illustrated by the example for N=4<br />
<br />
<br />
<div align="center">
<table border="0" cellpadding="0" cellspacing="0" class="MsoNormalTable" style="border-collapse: collapse; height: 219px; margin-left: 4.55pt; width: 407px;">
<tbody>
<tr style="height: 15.0pt; mso-yfti-firstrow: yes; mso-yfti-irow: 0;">
<td nowrap="nowrap" style="height: 15.0pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 53.0pt;" valign="middle" width="90"><br /></td>
<td nowrap="nowrap" style="height: 15.0pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 18.0pt;" valign="bottom" width="24"><br /></td>
<td style="background: #CCCCCC; border: solid black 1.0pt; height: 15.0pt; mso-border-alt: solid black .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 58.0pt;" valign="bottom" width="77"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b>625
| (<i>x</i>−1)<o:p></o:p></b></div>
</td>
<td style="background: #CCCCCC; border-left: none; border: solid black 1.0pt; height: 15.0pt; mso-border-bottom-alt: solid black .5pt; mso-border-right-alt: solid black .5pt; mso-border-top-alt: solid black .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 56.0pt;" valign="bottom" width="75"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b>625
| <i>x</i><o:p></o:p></b></div>
</td>
<td style="background: #CCCCCC; border-left: none; border: solid black 1.0pt; height: 15.0pt; mso-border-bottom-alt: solid black .5pt; mso-border-right-alt: solid black .5pt; mso-border-top-alt: solid black .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 65.0pt;" valign="bottom" width="87"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b>625
| (<i>x</i>+1) <o:p></o:p></b></div>
</td>
</tr>
<tr style="height: 15.0pt; mso-yfti-irow: 1;">
<td nowrap="nowrap" style="height: 15.0pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 53.0pt;" valign="middle" width="90"><br /></td>
<td nowrap="nowrap" style="height: 15.0pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 18.0pt;" valign="bottom" width="24"><br /></td>
<td nowrap="nowrap" style="height: 15.0pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 58.0pt;" valign="bottom" width="77"><br /></td>
<td nowrap="nowrap" style="height: 15.0pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 56.0pt;" valign="bottom" width="75"><br /></td>
<td nowrap="nowrap" style="height: 15.0pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 65.0pt;" valign="bottom" width="87"><br /></td>
</tr>
<tr style="height: 23.25pt; mso-yfti-irow: 2;">
<td style="background: #CCCCCC; border: solid black 1.0pt; height: 23.25pt; mso-border-alt: solid black .5pt; mso-border-bottom-alt: solid black 1.0pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 53.0pt;" valign="middle" width="90"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b> 16
| (<i>x</i>−1)<o:p></o:p></b></div>
</td>
<td nowrap="nowrap" style="height: 23.25pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 18.0pt;" valign="bottom" width="24"><br /></td>
<td nowrap="nowrap" style="background: yellow; border: solid windowtext 1.0pt; height: 23.25pt; mso-border-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 58.0pt;" width="77"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b>1<o:p></o:p></b></div>
</td>
<td nowrap="nowrap" style="background: #F2DDDC; border-left: none; border: solid windowtext 1.0pt; height: 23.25pt; mso-border-bottom-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 56.0pt;" width="75"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b>625<o:p></o:p></b></div>
</td>
<td nowrap="nowrap" style="background: red; border-left: none; border: solid windowtext 1.0pt; height: 23.25pt; mso-border-bottom-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 65.0pt;" width="87"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b>1249<o:p></o:p></b></div>
</td>
</tr>
<tr style="height: 23.25pt; mso-yfti-irow: 3;">
<td style="background: #CCCCCC; border-top: none; border: solid black 1.0pt; height: 23.25pt; mso-border-bottom-alt: solid black 1.0pt; mso-border-left-alt: solid black .5pt; mso-border-right-alt: solid black .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 53.0pt;" valign="middle" width="90"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b>16 | <i>x</i><o:p></o:p></b></div>
</td>
<td nowrap="nowrap" style="height: 23.25pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 18.0pt;" valign="bottom" width="24"><br /></td>
<td nowrap="nowrap" style="background: #DBEEF3; border-top: none; border: solid windowtext 1.0pt; height: 23.25pt; mso-border-bottom-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 58.0pt;" width="77"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b>9376<o:p></o:p></b></div>
</td>
<td nowrap="nowrap" style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; height: 23.25pt; mso-border-bottom-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 56.0pt;" width="75"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b>0<o:p></o:p></b></div>
</td>
<td nowrap="nowrap" style="background: #DBEEF3; border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; height: 23.25pt; mso-border-bottom-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 65.0pt;" width="87"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b>624<o:p></o:p></b></div>
</td>
</tr>
<tr style="height: 23.25pt; mso-yfti-irow: 4;">
<td style="background: #CCCCCC; border-top: none; border: solid black 1.0pt; height: 23.25pt; mso-border-bottom-alt: solid black .5pt; mso-border-left-alt: solid black .5pt; mso-border-right-alt: solid black .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 53.0pt;" valign="middle" width="90"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b>16 | (<i>x</i>+1)<o:p></o:p></b></div>
</td>
<td nowrap="nowrap" style="height: 23.25pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 18.0pt;" valign="bottom" width="24"><br /></td>
<td nowrap="nowrap" style="background: red; border-top: none; border: solid windowtext 1.0pt; height: 23.25pt; mso-border-bottom-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 58.0pt;" width="77"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b>8751<o:p></o:p></b></div>
</td>
<td nowrap="nowrap" style="background: #F2DDDC; border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; height: 23.25pt; mso-border-bottom-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 56.0pt;" width="75"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b>9375<o:p></o:p></b></div>
</td>
<td nowrap="nowrap" style="background: yellow; border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; height: 23.25pt; mso-border-bottom-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 65.0pt;" width="87"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b>9999<o:p></o:p></b></div>
</td>
</tr>
<tr style="height: 15.0pt; mso-yfti-irow: 5;">
<td nowrap="nowrap" style="height: 15.0pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 53.0pt;" valign="middle" width="90"><br /></td>
<td nowrap="nowrap" style="height: 15.0pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 18.0pt;" valign="bottom" width="24"><br /></td>
<td nowrap="nowrap" style="height: 15.0pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 58.0pt;" width="77"><br /></td>
<td nowrap="nowrap" style="height: 15.0pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 56.0pt;" width="75"><br /></td>
<td nowrap="nowrap" style="height: 15.0pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 65.0pt;" width="87"><br /></td>
</tr>
<tr style="height: 23.25pt; mso-yfti-irow: 6;">
<td style="background: #CCCCCC; border: solid black 1.0pt; height: 23.25pt; mso-border-alt: solid black .5pt; mso-border-bottom-alt: solid black 1.0pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 53.0pt;" valign="middle" width="90"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b>8 | (<i>x</i>−1)<o:p></o:p></b></div>
</td>
<td nowrap="nowrap" style="height: 23.25pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 18.0pt;" valign="bottom" width="24"><br /></td>
<td nowrap="nowrap" style="background: #FF33CC; border: solid windowtext 1.0pt; height: 23.25pt; mso-border-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 58.0pt;" width="77"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span style="color: #66ffff; mso-ascii-font-family: Calibri; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: EN-GB; mso-hansi-font-family: Calibri;">5001<o:p></o:p></span></b></div>
</td>
<td nowrap="nowrap" style="background: #FFC000; border-left: none; border: solid windowtext 1.0pt; height: 23.25pt; mso-border-bottom-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 56.0pt;" width="75"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span style="color: #17375d; mso-ascii-font-family: Calibri; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: EN-GB; mso-hansi-font-family: Calibri;">5625<o:p></o:p></span></b></div>
</td>
<td nowrap="nowrap" style="background: #92D050; border-left: none; border: solid windowtext 1.0pt; height: 23.25pt; mso-border-bottom-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 65.0pt;" width="87"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b>6249<o:p></o:p></b></div>
</td>
</tr>
<tr style="height: 23.25pt; mso-yfti-irow: 7; mso-yfti-lastrow: yes;">
<td style="background: #CCCCCC; border-top: none; border: solid black 1.0pt; height: 23.25pt; mso-border-bottom-alt: solid black .5pt; mso-border-left-alt: solid black .5pt; mso-border-right-alt: solid black .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 53.0pt;" valign="middle" width="90"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b>8 | (<i>x</i>+1)<o:p></o:p></b></div>
</td>
<td nowrap="nowrap" style="height: 23.25pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 18.0pt;" valign="bottom" width="24"><br /></td>
<td nowrap="nowrap" style="background: #92D050; border-top: none; border: solid windowtext 1.0pt; height: 23.25pt; mso-border-bottom-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 58.0pt;" width="77"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b>3751<o:p></o:p></b></div>
</td>
<td nowrap="nowrap" style="background: #FFC000; border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; height: 23.25pt; mso-border-bottom-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 56.0pt;" width="75"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span style="color: #17375d; mso-ascii-font-family: Calibri; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: EN-GB; mso-hansi-font-family: Calibri;">4375<o:p></o:p></span></b></div>
</td>
<td nowrap="nowrap" style="background: #FF33CC; border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; height: 23.25pt; mso-border-bottom-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 65.0pt;" width="87"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span style="color: #66ffff; mso-ascii-font-family: Calibri; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: EN-GB; mso-hansi-font-family: Calibri;">4999<o:p></o:p></span></b></div>
</td>
</tr>
</tbody>
</table>
</div>
<div align="center">
<br class="Apple-interchange-newline" /></div>
<br />
<div align="left">
</div>
</div>
<br />
<div align="left">
Here is a Python implementation to find
solutions:<br />
<br />
<a name='more'></a><br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 75%;"><code><span style="font-size: 12px; line-height: 14px;">def egcd(a,b):
if b == 0:
return [1,0,a]
else:
x,y,g = egcd(b, a%b)
return [y, x - (a//b)*y, g]
for N in range(3,101):
solutions = {0,1,10**N-1, (10**N)//2-1,(10**N)//2+1}
# Blue diophantine
r,s,g = egcd(5**N, 2**N)
x = (r%2**N )*5**N
solutions|= {x, 10**N-x, x-1, 10**N-x+1}
# Green diophantine
r,s,g = egcd(5**N, 2**(N-1))
x=(r%2**(N-1))*5**N
while x < 10**N:
solutions|= {x, 10**N-x}
x+= 5**N*2**(N-1)
x=2*(r%2**(N-1))*5**N - 1
while x < 10**N:
solutions|= {x, 10**N-x}
x+= 5**N*2**(N-1)
x=(s%5**N)*2**(N-1) - 1
while x < 10**N:
solutions|= {x, 10**N-x}
x+= 5**N*2**(N-1)
# Red diophantine
r,s,g = egcd(5**N, 2**(N-2))
x = 2*(r%2**(N-2) )*5**N - 1
while x < 10**N:
solutions|= {x, 10**N-x}
x+= 5**N*2**(N-1)
x = (s%5**N )*2**(N-1) - 1
while x < 10**N:
solutions|= {x, 10**N-x}
x+= 5**N*2**(N-1)
# sanity check
if len(solutions)<>15:
print "ERROR, wrong number of solutions",len(solutions)
for a in solutions:
if pow(a,3,10**N) <> a:
print "ERROR, Invalid value", a
print "N=",N,":", len(solutions),
print "solutions, highest non-trivial solution =", max( solutions-{10**N-1})</span><span style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace;"><span style="font-size: 12px; line-height: 14px;">
</span></span></code></pre>
<br /></div>
Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com1tag:blogger.com,1999:blog-6654130526829307380.post-42844854289046852252013-01-30T16:35:00.001+00:002013-01-30T19:15:57.112+00:00Another slip of the tongueA cracker from a <a href="http://www.bbc.co.uk/programmes/b01q8qq1" target="_blank">continuity announcer this afternoon</a>:<br />
<br />
"<i>At 2:15, Patrick Malahide stars as Albert Speer, or prisoner number five as he was known throughout his twenty years in Spandau Ballet</i>"<br />
<br />
I think Speer played the saxaphone.Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-84733763136960502172013-01-27T11:47:00.001+00:002013-01-29T14:24:07.976+00:00Enigma 49New Scientist magazine's <a href="http://enigmaticcode.wordpress.com/2013/01/24/enigma-49-a-square-problem/" target="_blank">Enigma #49</a> problem can be solved with a bit of number theory. Generalising the problem to finding a number whose square has the same last N digits as itself:<br />
<br />
<i>z<sup>2 </sup>= z</i> mod 10<sup>N</sup> → <i>z</i>(<i>z</i>-1) = 0 mod 10<sup>N</sup>. One factor of <i>z</i>(<i>z</i>-1) is odd, the other even. The even factor is a multiple of 2<sup>N</sup>. <br />
<br />
For a solution other than 0 or 1, the odd factor of <i>z</i>(<i>z</i>-1) must be a multiple of 5<sup>N </sup>(if the even factor is a multiple of 5 it is a multiple of 10, so the odd factor is congruent to 1 or 9 mod 10 and therefore not a multiple of 5, so the even factor is a multiple of 10<sup>N</sup>).<br />
<br />
So the solution is one of <br />
a) <i>z=2</i><sup><i>N</i></sup><i>x</i>, <i>z-1=5</i><sup><i>N</i></sup>y<br />
b) <i>z-1=<i>2</i><sup><i>N</i></sup><i>x</i></i><i>, z=<i>5</i><sup><i>N</i></sup>y</i>
<br />
<br />
Solutions to the Diophantine equation <i>2</i><i><sup>N</sup>x+ </i><i>5</i><i><sup>N</sup>y</i><i>=1 </i>produce the solutions<i> <br />
</i>a)<i> </i><i>z=</i><i><i>2</i><sup><i>N</i></sup>(x </i>mod <i><i>5</i><sup><i>N</i></sup>)<br />
</i><i></i>b)<i> <i>z=</i></i><i><i><i>5<sup><i>N</i></sup></i>(y</i></i> mod <i><i>2<sup><i>N</i></sup>)</i></i><br />
<br />
So, some Python code. Function egcd is a standard recursive implementation of the <a href="http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm" rel="nofollow">Extended Euclidean Algorithm</a> to find solutions to a linear Diophantine equation (and the gcd as a by-product). <br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"><span style="color: blue;">def egcd(a,b):</span></span><br />
<span style="color: blue; font-family: Courier New, Courier, monospace;"> if b == 0:</span><br />
<span style="color: blue; font-family: Courier New, Courier, monospace;"> return [1,0,a]</span><br />
<span style="color: blue; font-family: Courier New, Courier, monospace;"> else:</span><br />
<span style="color: blue; font-family: Courier New, Courier, monospace;"> x,y,g = egcd(b, a%b)</span><br />
<span style="color: blue; font-family: Courier New, Courier, monospace;"> return [y, x - (a//b)*y, g] </span><br />
<span style="color: blue;"><span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">for N in range(1,40):</span></span><br />
<span style="color: blue; font-family: Courier New, Courier, monospace;"> x,y,g = egcd(5**N, 2**N)</span><br />
<span style="color: blue; font-family: Courier New, Courier, monospace;"> print "N =",N, sorted([(x%2**N)*5**N, (y%5**N)*2**N])</span><br />
<br />Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com1tag:blogger.com,1999:blog-6654130526829307380.post-82821186029998909252013-01-04T14:44:00.000+00:002013-01-05T13:51:47.802+00:00A slip of the tongueThis had me laughing for several minutes.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieCg2oj4-f4qR9PUvL7uP4TkSEnStLzlGF1pR569pr4I60mdVKbqkRYrRN2H8N30SXTUNY6zdYEr38-mUPenjlwMWD2Gslcn0niAIhsLzCdJvMn1zjcBow9UdS_QavMlCTft0O_f9vU7lS/s1600/BLOWTORCH-DEAD-SPACE-3-HD-Wallpapers.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieCg2oj4-f4qR9PUvL7uP4TkSEnStLzlGF1pR569pr4I60mdVKbqkRYrRN2H8N30SXTUNY6zdYEr38-mUPenjlwMWD2Gslcn0niAIhsLzCdJvMn1zjcBow9UdS_QavMlCTft0O_f9vU7lS/s200/BLOWTORCH-DEAD-SPACE-3-HD-Wallpapers.jpg" width="150" /></a></div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYR4vG3nUJxaS_3AAu4slD-68RFVGFMMrnZel4KMqUYT3GzsdPqJzdJPEJF56faFD_GxwBz_eGsBKK45yQZG-JXkJxG4XbMTuELfAmjoMR3osDQ39Cxny546fDaCZWnPk1Cz1-QtVWAyHb/s1600/BOP-070731-027.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYR4vG3nUJxaS_3AAu4slD-68RFVGFMMrnZel4KMqUYT3GzsdPqJzdJPEJF56faFD_GxwBz_eGsBKK45yQZG-JXkJxG4XbMTuELfAmjoMR3osDQ39Cxny546fDaCZWnPk1Cz1-QtVWAyHb/s200/BOP-070731-027.jpg" width="100" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">"Squawk"</td></tr>
</tbody></table>
Matt Ridley talking on <a href="http://www.bbc.co.uk/programmes/b01phm1j" target="_blank">"The Value of Culture"</a> on Radio 4 this morning (about 6 mins 30 sec in from the start):<br />
<br />
"I live in a culture called science which is a tribe, but that tribe has no particular place in the world, but yet it is just as narrow as if it were a particular New Guinea group of people who killed birds of paradise with blowtorches"Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0tag:blogger.com,1999:blog-6654130526829307380.post-60338367727388017532012-12-17T16:41:00.000+00:002012-12-23T09:47:19.886+00:00New Scientist Enigma 1728This week's <a href="http://www.newscientist.com/article/mg21628951.800-enigma-number-1728.html" target="_blank">Enigma</a> puzzle was interesting enough to publish an analysis.<br />
<br />
This diagram shows the dynamics of the situation. $V_j$ is Jack's speed, $V_k$ is Ken's speed. $g$ is their initial goal line separation.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEqd54IsCtyV3SriD3v8MiMlGkuJBkvjrsReFfC_D_8fxlMQ9s2-rCdTJmrC5yBQMVOXhq-EhRgPuoGiXlaZtd3PzsUgXqM48gDJkCO1HzkCnBTMhN4MiysvRz3PyjDc8HQE0xnXxwKt9z/s1600/Enigma+1728+v2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="301" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEqd54IsCtyV3SriD3v8MiMlGkuJBkvjrsReFfC_D_8fxlMQ9s2-rCdTJmrC5yBQMVOXhq-EhRgPuoGiXlaZtd3PzsUgXqM48gDJkCO1HzkCnBTMhN4MiysvRz3PyjDc8HQE0xnXxwKt9z/s400/Enigma+1728+v2.jpg" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Defining $D$ as the distance between Joe and Ken, we will try to find the minimum of $D^2$ and hence the minimum of $D$</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
$D^2 = (g-V_j t cos\theta)^2 + t^2(V_k - V_j sin\theta)^2 $</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
$D^2 = g^2 - 2 g V_j t cos\theta +(V_j^2 + V_k^2)t^2 - 2 V_j V_k t^2 sin\theta$ ..............(1)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The minimum occurs when:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-size: large;"> $\frac{\partial{D^2}}{\partial \theta}$</span> $= 2gt V_j sin\theta - 2 V_j V_k t^2cos\theta =0$ .................(2)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-size: large;"> $\frac{ \partial{D^2}}{\partial{t}}$</span> $= -2g V_j cos\theta +2t(V_j^2 + V_k^2) - 4t V_j V_k sin\theta =0$ ...............(3)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
From (2), </div>
<div class="separator" style="clear: both; text-align: center;">
$t=$ <span style="font-size: large;">$\frac{g}{V_k}$</span> $tan\theta$ ..............................(4)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Substituting (4) into (3):</div>
<div class="separator" style="clear: both; text-align: center;">
$ -2g V_j cos\theta +2\frac{g}{V_k} (V_j^2 + V_k^2)\frac{sin\theta}{cos\theta} - 4g V_j\frac{sin^2\theta}{cos\theta} =0$ .....................(5)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Defining $s=sin\theta$ and multiplying (5) through by <span style="font-size: large;">$\frac{- cos\theta}{2gV_j}$</span> :</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
$ (1-s^2)-(\frac{V_j}{V_k}+\frac{V_k}{V_j})s+2s^2= (s-\frac{V_j}{V_k})(s-\frac{V_k}{V_j}) = 0$ </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
If $V_j < V_k$, this quadratic has one solution satisfying $s\lt1$, namely $s=\frac{V_j}{V_k}$</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
so </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
$sin\theta=$<span style="font-size: large;">$\frac{V_j}{V_k}$</span> <span style="text-align: left;">and </span>$t=$ <span style="font-size: large;">$\frac{g}{\sqrt{1-V_j^2/V_k^2}}$</span>. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Substituting these into (1) gives:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
$D^2 = $<span style="font-size: large;">$\frac{g^2}{V_k^2}$</span>$(V_k^2-V_j^2)$</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
so</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
$D = g\sqrt{1 - V_j^2/V_k^2}$ ............................... (6)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
Substituting the values $g=25ft, V_j=12mph, V_k=12.5mph$ into (6) gives the answer to the puzzle.<br />
<br />
The notable aspect of this analysis is that to minimise the distance between them when $V_j \lt V_k$, Joe runs at an angle $\theta$ where <span style="text-align: center;">$sin\theta=\frac{V_j}{V_k}$. </span>When $V_j \gt V_k$, Joe would run at an angle $\theta$ where <span style="text-align: center;">$sin\theta=\frac{V_k}{V_j}$ in order to intercept Ken.</span><br />
<span style="text-align: center;"><br /></span>
<br />
<br />Arthur Vausehttp://www.blogger.com/profile/13788126479372885933noreply@blogger.com0