Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,31 @@
using System;
using System.Numerics;
using System.Linq;
namespace Hamming {
class MainClass {
public static BigInteger Hamming(int n) {
BigInteger two = 2, three = 3, five = 5;
var h = new BigInteger[n];
h[0] = 1;
BigInteger x2 = 2, x3 = 3, x5 = 5;
int i = 0, j = 0, k = 0;
for (int index = 1; index < n; index++) {
h[index] = BigInteger.Min(x2, BigInteger.Min(x3, x5));
if (h[index] == x2) x2 = two * h[++i];
if (h[index] == x3) x3 = three * h[++j];
if (h[index] == x5) x5 = five * h[++k];
}
return h[n - 1];
}
public static void Main(string[] args) {
Console.WriteLine(string.Join(" ", Enumerable.Range(1, 20).ToList().Select(x => Hamming(x))));
Console.WriteLine(Hamming(1691));
Console.WriteLine(Hamming(1000000));
}
}
}

View file

@ -0,0 +1,37 @@
using System;
using System.Numerics;
using System.Linq;
namespace Hamming {
class MainClass {
public static BigInteger[] Hamming(int n, int[] a) {
var primes = a.Select(x => (BigInteger)x).ToArray();
var values = a.Select(x => (BigInteger)x).ToArray();
var indexes = new int[a.Length];
var results = new BigInteger[n];
results[0] = 1;
for (int iter = 1; iter < n; iter++) {
results[iter] = values[0];
for (int p = 1; p < primes.Length; p++)
if (results[iter] > values[p])
results[iter] = values[p];
for (int p = 0; p < primes.Length; p++)
if (results[iter] == values[p])
values[p] = primes[p] * results[++indexes[p]];
}
return results;
}
public static void Main(string[] args) {
foreach (int[] primes in new int[][] { new int[] {2,3,5}, new int[] {2,3,5,7} }) {
Console.WriteLine("{0}-Smooth:", primes.Last());
Console.WriteLine(string.Join(" ", Hamming(20, primes)));
Console.WriteLine(Hamming(1691, primes).Last());
Console.WriteLine(Hamming(1000000, primes).Last());
Console.WriteLine();
}
}
}
}

View file

@ -0,0 +1,73 @@
using System;
using System.Linq;
using System.Numerics;
namespace HammingFast {
class MainClass {
private static int[] _primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };
public static BigInteger Big(int[] exponents) {
BigInteger val = 1;
for (int i = 0; i < exponents.Length; i++)
for (int e = 0; e < exponents[i]; e++)
val = val * _primes[i];
return val;
}
public static int[] Hamming(int n, int nprimes) {
var hammings = new int[n, nprimes]; // array of hamming #s we generate
var hammlogs = new double[n]; // log values for above
var primelogs = new double[nprimes]; // pre-calculated prime log values
var indexes = new int[nprimes]; // intermediate hamming values as indexes into hammings
var listheads = new int[nprimes, nprimes]; // intermediate hamming list heads
var listlogs = new double[nprimes]; // log values of list heads
for (int p = 0; p < nprimes; p++) {
listheads[p, p] = 1; // init list heads to prime values
primelogs[p] = Math.Log(_primes[p]); // pre-calc prime log values
listlogs[p] = Math.Log(_primes[p]); // init list head log values
}
for (int iter = 1; iter < n; iter++) {
int min = 0; // find index of min item in list heads
for (int p = 1; p < nprimes; p++)
if (listlogs[p] < listlogs[min])
min = p;
hammlogs[iter] = listlogs[min]; // that's the next hamming number
for (int i = 0; i < nprimes; i++)
hammings[iter, i] = listheads[min, i];
for (int p = 0; p < nprimes; p++) { // update each list head if it matches new value
bool equal = true; // test each exponent to see if number matches
for (int i = 0; i < nprimes; i++) {
if (hammings[iter, i] != listheads[p, i]) {
equal = false;
break;
}
}
if (equal) { // if it matches...
int x = ++indexes[p]; // set index to next hamming number
for (int i = 0; i < nprimes; i++) // copy each hamming exponent
listheads[p, i] = hammings[x, i];
listheads[p, p] += 1; // increment exponent = mult by prime
listlogs[p] = hammlogs[x] + primelogs[p]; // add log(prime) to log(value) = mult by prime
}
}
}
var result = new int[nprimes];
for (int i = 0; i < nprimes; i++)
result[i] = hammings[n - 1, i];
return result;
}
public static void Main(string[] args) {
foreach (int np in new int[] { 3, 4, 5 }) {
Console.WriteLine("{0}-Smooth:", _primes[np - 1]);
Console.WriteLine(string.Join(" ", Enumerable.Range(1, 20).Select(x => Big(Hamming(x, np)))));
Console.WriteLine(Big(Hamming(1691, np)));
Console.WriteLine(Big(Hamming(1000000, np)));
Console.WriteLine();
}
}
}
}

View file

@ -0,0 +1,123 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace HammingTest
{
class HammingNode
{
public double log;
public int[] exponents;
public HammingNode next;
public int series;
}
class HammingListEnumerator : IEnumerable<BigInteger>
{
private int[] primes;
private double[] primelogs;
private HammingNode next;
private HammingNode[] values;
private HammingNode[] indexes;
public HammingListEnumerator(IEnumerable<int> seeds)
{
// Ensure our seeds are properly ordered, and generate their log values
primes = seeds.OrderBy(x => x).ToArray();
primelogs = primes.Select(x => Math.Log10(x)).ToArray();
// Start at 1 (log(1)=0, exponents are all 0, series = none)
next = new HammingNode { log = 0, exponents = new int[primes.Length], series = primes.Length };
// Set all exponent sequences to the start, and calculate the first value for each exponent
indexes = new HammingNode[primes.Length];
values = new HammingNode[primes.Length];
for(int i = 0; i < primes.Length; ++i)
{
indexes[i] = next;
values[i] = AddExponent(next, i);
}
}
// Make a copy of a node, and increment the specified exponent value
private HammingNode AddExponent(HammingNode node, int i)
{
HammingNode ret = new HammingNode { log = node.log + primelogs[i], exponents = (int[])node.exponents.Clone(), series = i };
++ret.exponents[i];
return ret;
}
private void GetNext()
{
// Find which exponent value is the lowest
int min = 0;
for(int i = 1; i < values.Length; ++i)
if(values[i].log < values[min].log)
min = i;
// Add it to the end of the 'list', and move to it
next.next = values[min];
next = values[min];
// Find the next node in an allowed sequence (skip those that would be duplicates)
HammingNode val = indexes[min].next;
while(val.series < min)
val = val.next;
// Keep the current index, and calculate the next value in the series for that exponent
indexes[min] = val;
values[min] = AddExponent(val, min);
}
// Skip values without having to calculate the BigInteger value from the exponents
public HammingListEnumerator Skip(int count)
{
for(int i = count; i > 0; --i)
GetNext();
return this;
}
// Calculate the BigInteger value from the exponents
internal BigInteger ValueOf(HammingNode n)
{
BigInteger val = 1;
for(int i = 0; i < n.exponents.Length; ++i)
for(int e = 0; e < n.exponents[i]; e++)
val = val * primes[i];
return val;
}
public IEnumerator<BigInteger> GetEnumerator()
{
while(true)
{
yield return ValueOf(next);
GetNext();
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
class Program
{
static void Main(string[] args)
{
foreach(int[] primes in new int[][] {
new int[] { 2, 3, 5 },
new int[] { 2, 3, 5, 7 },
new int[] { 2, 3, 5, 7, 9}})
{
HammingListEnumerator hammings = new HammingListEnumerator(primes);
System.Diagnostics.Debug.WriteLine("{0}-Smooth:", primes.Last());
System.Diagnostics.Debug.WriteLine(String.Join(" ", hammings.Take(20).ToArray()));
System.Diagnostics.Debug.WriteLine(hammings.Skip(1691 - 20).First());
System.Diagnostics.Debug.WriteLine(hammings.Skip(1000000 - 1691).First());
System.Diagnostics.Debug.WriteLine("");
}
}
}
}

View file

@ -0,0 +1,81 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace Hamming {
class Hammings : IEnumerable<BigInteger> {
private class LazyList<T> {
public T v; public Lazy<LazyList<T>> cont;
public LazyList(T v, Lazy<LazyList<T>> cont) {
this.v = v; this.cont = cont;
}
}
private uint[] primes;
private Hammings() { } // must have an argument!!!
public Hammings(uint[] prms) { this.primes = prms; }
private LazyList<BigInteger> merge(LazyList<BigInteger> xs,
LazyList<BigInteger> ys) {
if (xs == null) return ys; else {
var x = xs.v; var y = ys.v;
if (BigInteger.Compare(x, y) < 0) {
var cont = new Lazy<LazyList<BigInteger>>(() =>
merge(xs.cont.Value, ys));
return new LazyList<BigInteger>(x, cont);
}
else {
var cont = new Lazy<LazyList<BigInteger>>(() =>
merge(xs, ys.cont.Value));
return new LazyList<BigInteger>(y, cont);
}
}
}
private LazyList<BigInteger> llmult(uint mltplr,
LazyList<BigInteger> ll) {
return new LazyList<BigInteger>(mltplr * ll.v,
new Lazy<LazyList<BigInteger>>(() =>
llmult(mltplr, ll.cont.Value)));
}
public IEnumerator<BigInteger> GetEnumerator() {
Func<LazyList<BigInteger>,uint,LazyList<BigInteger>> u =
(acc, p) => { LazyList<BigInteger> r = null;
var cont = new Lazy<LazyList<BigInteger>>(() => r);
r = new LazyList<BigInteger>(1, cont);
r = this.merge(acc, llmult(p, r));
return r; };
yield return 1;
for (var stt = primes.Aggregate(null, u); ; stt = stt.cont.Value)
yield return stt.v;
}
IEnumerator IEnumerable.GetEnumerator() {
return this.GetEnumerator();
}
}
class Program {
static void Main(string[] args) {
Console.WriteLine("Calculates the Hamming sequence of numbers.\r\n");
var primes = new uint[] { 5, 3, 2 };
Console.WriteLine(String.Join(" ", (new Hammings(primes)).Take(20).ToArray()));
Console.WriteLine((new Hammings(primes)).ElementAt(1691 - 1));
var n = 1000000;
var elpsd = -DateTime.Now.Ticks;
var num = (new Hammings(primes)).ElementAt(n - 1);
elpsd += DateTime.Now.Ticks;
Console.WriteLine(num);
Console.WriteLine("The {0}th hamming number took {1} milliseconds", n, elpsd / 10000);
Console.Write("\r\nPress any key to exit:");
Console.ReadKey(true);
Console.WriteLine();
}
}
}

View file

@ -0,0 +1,91 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
class HammingsLogArr : IEnumerable<Tuple<uint, uint, uint>> {
public static BigInteger trival(Tuple<uint, uint, uint> tpl) {
BigInteger rslt = 1;
for (var i = 0; i < tpl.Item1; ++i) rslt *= 2;
for (var i = 0; i < tpl.Item2; ++i) rslt *= 3;
for (var i = 0; i < tpl.Item3; ++i) rslt *= 5;
return rslt;
}
private const double lb3 = 1.5849625007211561814537389439478; // Math.Log(3) / Math.Log(2);
private const double lb5 = 2.3219280948873623478703194294894; // Math.Log(5) / Math.Log(2);
private struct logrep {
public double lg;
public uint x2, x3, x5;
public logrep(double lg, uint x, uint y, uint z) {
this.lg = lg; this.x2 = x; this.x3 = y; this.x5 = z;
}
public logrep mul2() {
return new logrep (this.lg + 1.0, this.x2 + 1, this.x3, this.x5);
}
public logrep mul3() {
return new logrep(this.lg + lb3, this.x2, this.x3 + 1, this.x5);
}
public logrep mul5() {
return new logrep(this.lg + lb5, this.x2, this.x3, this.x5 + 1);
}
}
public IEnumerator<Tuple<uint, uint, uint>> GetEnumerator() {
var one = new logrep();
var s2 = new List<logrep>(); var s3 = new List<logrep>();
s2.Add(one); s3.Add(one.mul3());
var s5 = one.mul5(); var mrg = one.mul3();
var s2hdi = 0; var s3hdi = 0;
while (true) {
if (s2hdi >= s2.Count) { s2.RemoveRange(0, s2hdi); s2hdi = 0; } // assume capacity stays the same...
var v = s2[s2hdi];
if ( v.lg < mrg.lg) { s2.Add(v.mul2()); s2hdi++; }
else {
if (s3hdi >= s3.Count) { s3.RemoveRange(0, s3hdi); s3hdi = 0; }
v = mrg; s2.Add(v.mul2()); s3.Add(v.mul3());
s3hdi++; var chkv = s3[s3hdi];
if (chkv.lg < s5.lg) { mrg = chkv; }
else { mrg = s5; s5 = s5.mul5(); s3hdi--; }
}
yield return Tuple.Create(v.x2, v.x3, v.x5);
}
}
IEnumerator IEnumerable.GetEnumerator() {
return this.GetEnumerator();
}
}
class Program {
static void Main(string[] args) {
Console.WriteLine(String.Join(" ", (new HammingsLogArr()).Take(20)
.Select(t => HammingsLogArr.trival(t))
.ToArray()));
Console.WriteLine(HammingsLogArr.trival((new HammingsLogArr()).ElementAt((int)1691 - 1)));
var n = 1000000UL;
var elpsd = -DateTime.Now.Ticks;
var rslt = (new HammingsLogArr()).ElementAt((int)n - 1);
elpsd += DateTime.Now.Ticks;
Console.WriteLine("2^{0} times 3^{1} times 5^{2}", rslt.Item1, rslt.Item2, rslt.Item3);
var lgrthm = Math.Log10(2.0) * ((double)rslt.Item1 +
((double)rslt.Item2 * Math.Log(3.0) + (double)rslt.Item3 * Math.Log(5.0)) / Math.Log(2.0));
var pwr = Math.Floor(lgrthm); var mntsa = Math.Pow(10.0, lgrthm - pwr);
Console.WriteLine("Approximately: {0}E+{1}", mntsa, pwr);
var s = HammingsLogArr.trival(rslt).ToString();
var lngth = s.Length;
Console.WriteLine("Decimal digits: {0}", lngth);
if (lngth <= 10000) {
var i = 0;
for (; i < lngth - 100; i += 100) Console.WriteLine(s.Substring(i, 100));
Console.WriteLine(s.Substring(i));
}
Console.WriteLine("The {0}th hamming number took {1} milliseconds", n, elpsd / 10000);
Console.Write("\r\nPress any key to exit:");
Console.ReadKey(true);
Console.WriteLine();
}
}

View file

@ -0,0 +1,90 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
static class NthHamming {
public static BigInteger trival(Tuple<uint, uint, uint> tpl) {
BigInteger rslt = 1;
for (var i = 0; i < tpl.Item1; ++i) rslt *= 2;
for (var i = 0; i < tpl.Item2; ++i) rslt *= 3;
for (var i = 0; i < tpl.Item3; ++i) rslt *= 5;
return rslt;
}
private struct logrep {
public uint x2, x3, x5;
public double lg;
public logrep(uint x, uint y, uint z, double lg) {
this.x2 = x; this.x3 = y; this.x5 = z; this.lg = lg;
}
}
private const double lb3 = 1.5849625007211561814537389439478; // Math.Log(3) / Math.Log(2);
private const double lb5 = 2.3219280948873623478703194294894; // Math.Log(5) / Math.Log(2);
private const double fctr = 6.0 * lb3 * lb5;
private const double crctn = 2.4534452978042592646620291867186; // Math.Log(Math.sqrt(30.0)) / Math.Log(2.0)
public static Tuple<uint, uint, uint> findNth(UInt64 n) {
if (n < 1) throw new Exception("NthHamming.findNth: argument must be > 0!");
if (n < 2) return Tuple.Create(0u, 0u, 0u); // trivial case for argument of one
var lgest = Math.Pow(fctr * (double)n, 1.0/3.0) - crctn; // from WP formula
var frctn = (n < 1000000000) ? 0.509 : 0.105;
var lghi = Math.Pow(fctr * ((double)n + frctn * lgest), 1.0/3.0) - crctn;
var lglo = 2.0 * lgest - lghi; // upper and lower bound of upper "band"
var count = 0UL; // need 64 bit precision in case...
var bnd = new List<logrep>();
for (uint k = 0, klmt = (uint)(lghi / lb5) + 1; k < klmt; ++k) {
var p = (double)k * lb5;
for (uint j = 0, jlmt = (uint)((lghi - p) / lb3) + 1; j < jlmt; ++j) {
var q = p + (double)j * lb3;
var ir = lghi - q;
var lg = q + Math.Floor(ir); // current log2 value (estimated)
count += (ulong)ir + 1;
if (lg >= lglo) bnd.Add(new logrep((UInt32)ir, j, k, lg));
}
}
if (n > count) throw new Exception("NthHamming.findNth: band high estimate is too low!");
var ndx = (int)(count - n);
if (ndx >= bnd.Count) throw new Exception("NthHamming.findNth: band low estimate is too high!");
bnd.Sort((a, b) => (b.lg < a.lg) ? -1 : 1); // sort in decending order
var rslt = bnd[ndx];
return Tuple.Create(rslt.x2, rslt.x3, rslt.x5);
}
}
class Program {
static void Main(string[] args) {
Console.WriteLine(String.Join(" ", Enumerable.Range(1,20).Select(i =>
NthHamming.trival(NthHamming.findNth((ulong)i))).ToArray()));
Console.WriteLine(NthHamming.trival((new HammingsLogArr()).ElementAt(1691 - 1)));
var n = 1000000000000UL;
var elpsd = -DateTime.Now.Ticks;
var rslt = NthHamming.findNth(n);
elpsd += DateTime.Now.Ticks;
Console.WriteLine("2^{0} times 3^{1} times 5^{2}", rslt.Item1, rslt.Item2, rslt.Item3);
var lgrthm = Math.Log10(2.0) * ((double)rslt.Item1 +
((double)rslt.Item2 * Math.Log(3.0) + (double)rslt.Item3 * Math.Log(5.0)) / Math.Log(2.0));
var pwr = Math.Floor(lgrthm); var mntsa = Math.Pow(10.0, lgrthm - pwr);
Console.WriteLine("Approximately: {0}E+{1}", mntsa, pwr);
var s = HammingsLogArr.trival(rslt).ToString();
var lngth = s.Length;
Console.WriteLine("Decimal digits: {0}", lngth);
if (lngth <= 10000) {
var i = 0;
for (; i < lngth - 100; i += 100) Console.WriteLine(s.Substring(i, 100));
Console.WriteLine(s.Substring(i));
}
Console.WriteLine("The {0}th hamming number took {1} milliseconds", n, elpsd / 10000);
Console.Write("\r\nPress any key to exit:");
Console.ReadKey(true);
Console.WriteLine();
}
}