using System; using System.IO; namespace primecalc { /// /// A hack program to generate HTML pages which correspond to the printed pages in the famous book /// Lehmer, D. N. List of Prime Numbers from 1 to 10,006,721. Washington, DC: Carnegie Institution, 1914. /// There are 133 pages of tables, each one with 5000 primes in 100 rows of 50 columns. /// public sealed class Program { private int pages; private int total; private int count; private int[] primes; private DateTime progressTime; private int columnsPerPage; private const int PrimesPerPage = 5000; private const int RowsPerPage = 100; private const string OutputFilePattern = @"..\..\output\page{0:000}.htm"; private StreamWriter writer; public static void Main(string[] args) { new Program().Run(args); } public Program() { } /// /// The primes 1, 2 and 3 are manually set in the prime array before a loop starts /// to test every number of the form 6n-1 and 6n+1. NOTE: Lehmer list 1 as a prime, /// which was a personal convention of his that was never widely accepted, so this /// program lists 1 to make the HTML pages correspond to the printed ones. /// /// The command line must specify an integer number of pages to /// generate as the first parameter. Lehmer's book has 133 pages. public void Run(string[] args) { pages = (args.Length > 1 ? int.Parse(args[0]) : 133); total = pages * PrimesPerPage; columnsPerPage = PrimesPerPage / RowsPerPage; primes = new int[total]; SavePrime(1); SavePrime(2); SavePrime(3); for (int i = 6; ; i += 6) { CheckNum(i - 1); CheckNum(i + 1); if (count == total) break; } WriteLinks(); } /// /// This childishly simple check for a prime number attempts to divide by /// all of the previous primes up to the square root. /// private void CheckNum(int n) { int stop = (int)Math.Sqrt(n); for (int i = 2; i < stop; i++) { if ((n % primes[i]) == 0) return; } SavePrime(n); } /// /// Save a prime in the array. When a multiple of the page count is hit we /// generate a HTML page with a 5000 cell table that has the same format as /// Lehmer's table page. /// private void SavePrime(int n) { if (count < total) { primes[count] = n; ++count; if ((count > 0) && ((count % PrimesPerPage) == 0)) { int pageNo = count / PrimesPerPage; DisplayProgress(pageNo, n); WritePageAsHtmlFile(pageNo); } } } private void DisplayProgress(int pageNo, int n) { double interval = 0.0; DateTime newtime = DateTime.Now; if (progressTime != DateTime.MinValue) { interval = newtime.Subtract(progressTime).TotalSeconds; } progressTime = newtime; int len = (int)(10 * interval); string bars = new string('*', len); Console.WriteLine(" {0,3} {1,8} {2,8} {3,8} {4:0.000} {5}", pageNo, count, total, n, interval, bars); } private void WritePageAsHtmlFile(int pageNo) { string fname = string.Format(OutputFilePattern, pageNo); writer = new StreamWriter(fname); int ix1 = count - PrimesPerPage; writer.WriteLine(""); writer.WriteLine(" "); writer.WriteLine(" Primes Page {0}", pageNo); writer.WriteLine(" "); writer.WriteLine(" "); writer.WriteLine(" "); writer.WriteLine("

BACK{0} — {1}

", primes[ix1], primes[ix1 + PrimesPerPage - 1]); writer.WriteLine(" "); // **** THE COLUMN COUNT ROW **** writer.Write(" "); writer.Write(""); for (int col = 0; col < columnsPerPage; col++) { writer.Write("", col+1); } writer.WriteLine(""); // **** THE 10,000 (TOP) PREFIX ROW **** writer.Write(" "); writer.Write(""); for (int col = 0; col < columnsPerPage; col++) { int t = primes[ix1 + col * RowsPerPage] / 10000; string s = (t == 0 ? " " : t.ToString()); writer.Write("", s); } writer.WriteLine(""); // **** A TABLE ROW **** for (int row=0; row"); writer.Write("", row + 1); for (int col = 0; col < columnsPerPage; col++) { int p = primes[ix1 + col*RowsPerPage + row]; if ((p >= 10000) && (row == 0)) { writer.Write("", p % 10000); } else { writer.Write("", p % 10000); } } writer.WriteLine(" "); } // **** THE 10,000 (BOTTOM) PREFIX ROW **** writer.Write(" "); writer.Write(""); for (int col = 0; col < columnsPerPage; col++) { int t = primes[ix1 + col * RowsPerPage + RowsPerPage-1] / 10000; string s = (t == 0 ? " " : t.ToString()); writer.Write("", s); } writer.WriteLine(""); writer.WriteLine("
 {0}
 {0}
{0}{0:0000}{0}
 {0}
"); writer.WriteLine("

{0}

", pageNo); writer.WriteLine(" "); writer.WriteLine(""); writer.Close(); } /// /// Just a string of links I needed to put in the parent web page. /// private void WriteLinks() { writer = new StreamWriter(@"links.txt"); for (int i = 0; i < pages; i++) { if (i > 0) writer.Write(" "); writer.Write("{0}", i + 1); if ((i > 0) && ((i % 5) == 0)) { writer.WriteLine(""); } } writer.Close(); } } }