To remove those troublesome and expensive zeroes (as a search that yields a 0, i.e. it doesn't exist in the sequence before that point, takes the longest to do for that term), I came up with this solution:
#define NUM_TERMS 100
// ...
char sequence[NUM_TERMS];
char counts[NUM_TERMS];
memset(sequence, 0, NUM_TERMS);
memset(counts, 0, NUM_TERMS);
for(char i = 1; i < NUM_TERMS; i++)
{
char index = i - 1;
if(counts[index] < 2)
{
char val = sequence[index];
for(char j = index - 1; j > -1; j--)
{
if(sequence[j] == val)
{
sequence[i] = index - j;
counts[sequence[i]]++;
break;
}
}
}
}
printf("\033[1;30m"); // Sets it to "black" (more like a dark grey)
printf("\033[0m"); // Resets the colour to what it was before
// [1;31m to [1;37m are the basic colours (red, green, yellow, blue, magenta, cyan, white)
// In that order
#define NUM_TERMS 100
// ...
char sequence [NUM_TERMS]; // Contains the Van Eck sequence
char counts [NUM_TERMS]; // Contains the frequency of each term
char indices [NUM_TERMS]; // Contains the last index of each term
char prevIndices[NUM_TERMS]; // Contains whatever indices did before it got updated
memset(sequence, 0, NUM_TERMS);
memset(counts, 0, NUM_TERMS);
memset(indices, 0, NUM_TERMS);
memset(prevIndices, 0, NUM_TERMS);
counts[0] = 1;
for(char i = 1; i < NUM_TERMS; i++)
{
char prevIndex = i - 1;
char prevValue = sequence[prevIndex];
if(counts[prevValue] > 1) // If the value we last wrote exists already
{
// Write a new value to the sequence that is the number of steps away
// from the previous occurrence of that number
char thisValue = prevIndex - prevIndices[prevValue];
sequence[i] = thisValue;
counts[thisValue]++; // Update new entry's count
prevIndices[thisValue] = indices[thisValue]; // Update the previous index
indices[thisValue] = i; // Update new entry's index
}
else // If the last value we wrote is a new term
{
// Update 0's count & index
// Equivalent of writing a 0
counts[0]++;
prevIndices[0] = indices[0];
indices[0] = i;
// Could do sequence[i] = 0; but it already is
}
}
#define NUM_TERMS 100
// ...
char sequence [NUM_TERMS]; // Contains the Van Eck sequence
char indices [NUM_TERMS]; // Contains the last index of each term
char prevIndices[NUM_TERMS]; // Contains whatever indices did before it got updated
memset(sequence, 0, NUM_TERMS);
memset(indices, 0, NUM_TERMS);
memset(prevIndices, 0, NUM_TERMS);
for(char i = 1; i < NUM_TERMS; i++)
{
char prevIndex = i - 1;
char prevValue = sequence[prevIndex];
if(prevIndices[prevValue]) // If the value we last wrote exists already
{
char thisValue = prevIndex - prevIndices[prevValue];
sequence[i] = thisValue;
prevIndices[thisValue] = indices[thisValue];
indices[thisValue] = i;
}
else // If the last value we wrote is a new term
{
prevIndices[0] = indices[0];
indices[0] = i;
}
}
for(char i = 1; i < NUM_TERMS; i++)
{
char prevIndex = i - 1;
char prevValue = sequence[prevIndex];
if(indices[prevValue]) // If the value we last wrote exists already
{
indices[prevValue] -= prevIndex;
char thisValue = prevIndex - indices[prevValue];
sequence[i] = thisValue;
indices[thisValue] += i;
}
else // If the last value we wrote is a new term
{
indices[0] += i;
}
}
#define NUM_TERMS 100
// ...
char sequence[NUM_TERMS];
unsigned char lastIndexOf[NUM_TERMS];
memset(lastIndexOf, 255, NUM_TERMS);
char prevVal = 0;
for (char i = 0; i < NUM_TERMS; i++)
{
unsigned char lio = lastIndexOf[prevVal];
lastIndexOf[prevVal] = i - 1;
prevVal = lio == 255 ? 0 : i - 1 - lio;
sequence[i] = prevVal;
}