HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Detecting cycles

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
detectingcyclesstackoverflow

Problem

This is a challenge question from codeeval.com:


Given a
sequence, write a program to detect cycles within it. Input sample:


Your program should accept as its first argument a path to a filename
containing a sequence of numbers (space delimited). The file can have
multiple such lines. E.g


2 0 6 3 1 6 3 1 6 3 1


3 4 8 0 11 9 7 2 5 6 10 1 49 49 49 49


1 2 3 1 2 3 1 2 3


Output sample:


Print to stdout the first cycle you find in each sequence. Ensure that
there are no trailing empty spaces on each line you print.
E.g:


6 3 1


49


1 2 3


The cycle detection problem is explained more widely on wiki
Constrains: The elements of the sequence are integers in range [0, 99]
The length of the sequence is in range [0, 50]

Please let me know any improvements on this implementation.

```
#include
#include
#include
#include
#include
#include

template
class cyclicKeeper
{
public:
void push( T val)
{
cycles.push_back(val);
cycleSet.emplace(val);
}
void clear()
{
for ( auto & x : cycles)
{
--counter[x];
}
cycles.clear();
cycleSet.clear();
}
void incrementCounter(T val)
{
++counter[val];
}
T counterValue(T val)
{
return counter[val];
}
void print()
{
std::vector order( cycleSet.size());
for( auto & x : cycleSet)
{
auto pos= std::find(std::begin(cycles), std::end(cycles),x);
order[pos- std::begin(cycles)]=x;
}
for( auto &x : order)
{
std::cout counter;
std::vector cycles;
std::set cycleSet;
};

void processInputRecord(std::vector& vec)
{
cyclicKeeper ck;
for( auto & x : vec )
{
ck.incrementCounter(x);
}

int prev =

Solution

Too complex

With the problem constrained to:

The elements of the sequence are integers in range [0, 99]

The length of the sequence is in range [0, 50]

the program should be very simple. Instead, you use an unordered_map, a vector, and a set, which is overkill. The problem could be solved with only a vector of size 50.

(Note: answer modified to find the cycle as clarified by the comments)

The vector of size 50 holds the input sequence. Starting at the end of the sequence, you only need to search backwards until you find a match for the last number of the sequence. This is because any cycle must end the sequence.
Simplified example

Here is the simplified code:

#define MAX_INPUT_LENGTH        50

void readInputFile( std::string fileName )
{
    std::ifstream infile( fileName );
    std::vector inputValues(MAX_INPUT_LENGTH);
    std::string record;

    while( std::getline( infile, record ) )
    {
        std::istringstream iss(record);
        int i     = 0;
        int value = 0;

        while( iss >> value )
            inputValues[i++] = value;

        int lastValue = inputValues[i-1];
        for (int j = i-2; j >= 0; j--) {
            if (inputValues[j] == lastValue) {
                // Found a cycle.
                for (j = j+1; j < i; j++)
                    std::cout << inputValues[j] << " ";
                std::cout << "\n";
                break;
            }
        }
    }
    infile.close();
}

Code Snippets

#define MAX_INPUT_LENGTH        50

void readInputFile( std::string fileName )
{
    std::ifstream infile( fileName );
    std::vector<int> inputValues(MAX_INPUT_LENGTH);
    std::string record;

    while( std::getline( infile, record ) )
    {
        std::istringstream iss(record);
        int i     = 0;
        int value = 0;

        while( iss >> value )
            inputValues[i++] = value;

        int lastValue = inputValues[i-1];
        for (int j = i-2; j >= 0; j--) {
            if (inputValues[j] == lastValue) {
                // Found a cycle.
                for (j = j+1; j < i; j++)
                    std::cout << inputValues[j] << " ";
                std::cout << "\n";
                break;
            }
        }
    }
    infile.close();
}

Context

StackExchange Code Review Q#97395, answer score: 4

Revisions (0)

No revisions yet.