Skip to content

Instantly share code, notes, and snippets.

@JohnyWS
Created August 24, 2019 20:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JohnyWS/747c4052bcb6f56bdfe5eb9a31c0fdf8 to your computer and use it in GitHub Desktop.
Save JohnyWS/747c4052bcb6f56bdfe5eb9a31c0fdf8 to your computer and use it in GitHub Desktop.
Playing around sequence generation
/********************************************************************************************
* Inspired by Amazing Graphs III - Numberphile: https://www.youtube.com/watch?v=j0o-pMIR8uk *
* Quick attempt at Rémy Sigrist's sequence: https://oeis.org/A279125 *
* Runs fine in Visual Studio Code and prints with the help of SharpPad *
* Ended up writing to file instead though, and attempted to use an online plotter *
* Just paste the dump into here: http://gnuplot.respawned.com/ *
* and change the plot commands to this: plot "data.txt" *
* and see the mountains taking form... :) *
********************************************************************************************/
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using SharpPad;
namespace sharppad
{
class Program
{
private static readonly List<BinaryIndexTracker> BinaryIndexTrackers = new List<BinaryIndexTracker>();
static async Task Main(string[] args)
{
int count = 20000; // Increase with care! x5 of this took me 4 minutes up from 8 seconds!
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
var sb = new StringBuilder().AppendLine().AppendLine("# Fooling around with SharpPad and https://oeis.org/A279125").AppendLine("# N f(N)");
var enumerator = EnumerateSequence().GetEnumerator();
var tempFileName = System.IO.Path.GetTempFileName();
for(int i = 1;i<=count;i++)
{
enumerator.MoveNext();
var line = String.Format("{0,-10}{1}", i, enumerator.Current);
sb.AppendLine(line);
}
stopwatch.Stop();
string executionDescription = $"# Found {count} in {stopwatch.ElapsedMilliseconds} ms";
string fullContentWithHeader = executionDescription + sb.ToString();
System.IO.File.WriteAllText(tempFileName, fullContentWithHeader);
await tempFileName.Dump();
Console.WriteLine($"Temp filename: {tempFileName}");
}
private static IEnumerable<int> EnumerateSequence()
{
for (int i = 1;;i++) // Endless loop
{
int binaryEnumerator = 1;
int binaryIndex = 0;
var matchingTrackers = new List<BinaryIndexTracker>();
do
{
if((binaryEnumerator & i) > 0)
{
if(binaryIndex >= BinaryIndexTrackers.Count)
{
// first time reaching this ...
BinaryIndexTrackers.Add(new BinaryIndexTracker(binaryIndex));
}
matchingTrackers.Add(BinaryIndexTrackers[binaryIndex]);
}
binaryEnumerator = binaryEnumerator << 1;
binaryIndex++;
} while (binaryEnumerator <= i);
int nextValue = matchingTrackers.Select(mt => mt.SmallestAvailableValue).Max();
while(!matchingTrackers.All(mt => mt.TestAvailable(nextValue)))
{
nextValue++;
}
matchingTrackers.ForEach(ml => ml.SetAsUsed(nextValue));
yield return nextValue;
}
}
private class BinaryIndexTracker
{
private int _smallestAvailableValue = 0;
private Dictionary<int, object> _biggerUsedValues = new Dictionary<int, object>();
public int BinaryIndex { get; }
public int SmallestAvailableValue => _smallestAvailableValue;
public BinaryIndexTracker(int binaryIndex)
{
BinaryIndex = binaryIndex;
}
public bool TestAvailable(int value)
{
return value >= SmallestAvailableValue && !_biggerUsedValues.ContainsKey(value);
}
public void SetAsUsed(int value)
{
if(!TestAvailable(value)) throw new InvalidOperationException($"The value {value} is not available at binary index {BinaryIndex}!");
_biggerUsedValues.Remove(value);
if(value == _smallestAvailableValue)
{
int nextValue = value + 1;
while(_biggerUsedValues.ContainsKey(nextValue))
{
_biggerUsedValues.Remove(nextValue);
nextValue++;
}
_smallestAvailableValue = nextValue;
}
else
{
_biggerUsedValues.Add(value, null);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment