Created
August 24, 2019 20:54
-
-
Save JohnyWS/747c4052bcb6f56bdfe5eb9a31c0fdf8 to your computer and use it in GitHub Desktop.
Playing around sequence generation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/******************************************************************************************** | |
* 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