Search code examples
frequencypseudocode

Get the most occuring number amongst several integers without using arrays


DISCLAIMER: Rather theoretical question here, not looking for a correct answere, just asking for some inspiration!

Consider this:

A function is called repetitively and returns integers based on seeds (the same seed returns the same integer). Your task is to find out which integer is returned most often. Easy enough, right?

But: You are not allowed to use arrays or fields to store return values of said function!

Example:

int mostFrequentNumber = 0;
int occurencesOfMostFrequentNumber = 0;
int iterations = 10000000;

for(int i = 0; i < iterations; i++)
{
    int result = getNumberFromSeed(i);
    int occurencesOfResult = magic();
    if(occurencesOfResult > occurencesOfMostFrequentNumber)
    {
        mostFrequentNumber = result;
        occurencesOfMostFrequentNumber = occurencesOfResult;
    }
}

If getNumberFromSeed() returns 2,1,5,18,5,6 and 5 then mostFrequentNumber should be 5 and occurencesOfMostFrequentNumber should be 3 because 5 is returned 3 times.

I know this could easily be solved using a two-dimentional list to store results and occurences. But imagine for a minute that you can not use any kind of arrays, lists, dictionaries etc. (Maybe because the system that is running the code has such a limited memory, that you cannot store enough integers at once or because your prehistoric programming language has no concept of collections).

How would you find mostFrequentNumber and occurencesOfMostFrequentNumber? What does magic() do?? (Of cause you do not have to stick to the example code. Any ideas are welcome!)

EDIT: I should add that the integers returned by getNumber() should be calculated using a seed, so the same seed returns the same integer (i.e. int result = getNumber(5); this would always assign the same value to result)


Solution

  • Alright, I found a decent solution myself:

    int mostFrequentNumber = 0;
    int occurencesOfMostFrequentNumber = 0;
    int iterations = 10000000;
    int maxNumber = -2147483647;
    int minNumber = 2147483647;
    
    //Step 1: Find the largest and smallest number that _can_ occur
    for(int i = 0; i < iterations; i++)
    {
        int result = getNumberFromSeed(i);
        if(result > maxNumber)
        {
            maxNumber = result;
        }
        if(result < minNumber)
        {
            minNumber = result;
        }
    }
    
    //Step 2: for each possible number between minNumber and maxNumber, count occurences
    for(int thisNumber = minNumber; thisNumber <= maxNumber; thisNumber++)
    {
        int occurenceOfThisNumber = 0;
        for(int i = 0; i < iterations; i++)
        {
            int result = getNumberFromSeed(i);
            if(result == thisNumber)
            {
                occurenceOfThisNumber++;
            }
        }
        if(occurenceOfThisNumber > occurencesOfMostFrequentNumber)
        {
            occurencesOfMostFrequentNumber = occurenceOfThisNumber;
            mostFrequentNumber = thisNumber;
        }   
    }
    

    I must admit, this may take a long time, depending on the smallest and largest possible. But it will work without using arrays.