0

First of all, this is a school assignment, so I can't use the <math.h> library as a handicap. So as the title suggests, I tried to write a function that gets a sequence of positive numbers for its input, then returns the number of which the sequence would continue. For example, if the sequence is 3 1 1 1 1 3 3 3 1 1 1 3 3 3 1 1 1 1 then it would return a 3 because that's what the next number would be. The sequence of numbers always ends with -1, however, -1 is not part of the sequence, it merely marks its end.

Here's the function:

#include <stdio.h>
int predict(int seq[]) {
    int i, j;
    for (i = 0; seq[i] != -1; i++)
        ;
    int seqLength = i;
    int rep[i+1];
    for (j = 0; j < i + 1; j++)
        rep[j] = -1;
    i = 0;
    j = 1;
    while (seq[i] != -1) {
        if (rep[0] == seq[i]) {
            for (j = 1; seq[i + j] != -1; j++) {
                if (rep[j] == seq[i + j]) {
                    j++;
                } else {
                    rep[i] = seq[i];
                    j = 1;
                    break;
                }
            }
            i++;
        } else {
            rep[i] = seq[i];
            i++;
        }
    }
    for (i = 0; rep[i] != -1; i++)
        ;
    int repLength = i;
    return seq[seqLength % repLength];
}

int main() {
    int seq[20] = {1, 2, 1, 1, 2, 1, 2, 3, 1, 2, 1, 1, 2, 1, 2, -1}; /*or any other positive numbers as long as it ends with -1*/
    printf("%d\n",predict(seq));
    return 0;
}

The seq (short for sequence) is the sequence of numbers the function gets as the input. seqLength is the number of how many numbers the seq has. The rep (short for repeat) is the part of the sequence which repeats itself. repLength is the number of how many numbers the rep has.

The function works for all three test cases which I know, for example:

For 3 1 1 1 1 3 3 3 1 1 1 3 3 3 1 1 1 1 it returns 3.
For 1 2 3 1 2 3 4 1 2 3 1 2 3 4 1 2 3 it returns 1.
For 1 2 1 1 2 1 2 3 1 2 1 1 2 1 2 it returns 3.

However, when I upload it to the school system that tests and appraises my function, it tests for an additional two test cases, which are wrong. The problem is, that I don't know the input sequence for those additional two test cases and therefore I don't know what to change in order for my functions to work for all test cases. Can someone see an error in my work and have an idea of what to change in order for my function to work for any repeating number sequences, even for unknown ones?

Maszeg
  • 13
  • 2
  • Possibly the same as [this recent question](https://stackoverflow.com/questions/58658983/how-can-i-find-a-pattern-in-an-array-of-integers/58659326#58659326)? – Some programmer dude Nov 03 '19 at 18:14
  • do some more tests. suggestions without having read your code: `predict(1 1 -1)`, `predict(1 2 3 4 -1)`, `predict(-1) /* for sneaky teacher! */` – pmg Nov 03 '19 at 18:19
  • regarding: `for(i=0;seq[i]!=-1;i++);` a `-1` is not mentioned in your question. What does the `-1` represent? – user3629249 Nov 03 '19 at 18:46
  • please post a [mcve] so we can duplicate the problem and help you debug it. – user3629249 Nov 03 '19 at 18:48
  • 1
    OT: for ease of readability and understanding, Please consistently format the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces. – user3629249 Nov 03 '19 at 18:51
  • @Someprogrammerdude Yes, more than probably he's someone from my school who also working on this assignment, however, he asked for help on how to write the code on the first place while I already wrote my code, it's just not working perfectly. – Maszeg Nov 03 '19 at 19:25
  • @pmg Thanks for the suggestions, I tried them. The 1 2 3 4 case revealed a bug which I fixed. ("int rep[i+1]; for(j=0;j – Maszeg Nov 03 '19 at 19:25
  • @user3629249 it has indents after '{'-s in the next line and the '}' are indented the same amount as the function of which they belong so I really don't know whats your problem with that, however I added the minimal reproducible example. – Maszeg Nov 03 '19 at 19:48
  • now that you have a working version, here's my attempt: https://ideone.com/t9YXu0 – pmg Nov 03 '19 at 20:20

1 Answers1

0

There is a corner case for which your algorithm does not work: if the repeated sequence has length seqLength, you will not find -1 in the rep array because it was defined with a length of seqLength and the end of list marker was never copied there. Hence the last loop will run past the end of rep and cause undefined behavior.

I'm afraid there are other problems, let's try and simplify the code:

  • It would be safer to compare the index values to seqLength instead of testing for -1, which by the way you did not document as the end of list marker.

  • Furthermore, it seems superfluous to copy the sequence into a rep array as this array would always contain an initial portion of seq.

  • The problems seems to boil down to finding the length of the repeated pattern.

Here is a simplified version, with seqLength passed as an argument:

int predict(int seq[], int seqLength) {
    /* find the mininum value of repLength such that the sequence is
       a repeated pattern of length repLength */
    int i, repLength;
    for (repLength = 1; repLength < seqLength; replength++) {
        for (i = 0; i < seqLength; i++) {
            if (seq[i] != seq[i % repLength])
                break;
        }
        if (i == seqLength) {
            /* we found the pattern length */
            break;
        }
    }
    return seq[seqLength % repLength];
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • I appreciate your feedback. Fixed the part which caused undefined behavior if the repeated sequence has length seqLength by adding a +1 to the size of the block which also gets filled with -1. I'm not getting seqLength as an input and I cannot modify the code to do so. I have to calculate it merely from the block which I get as the only input. – Maszeg Nov 03 '19 at 19:57
  • Tried your version by rewriting it a bit (calculating seqLength inside the function instead of getting it as an input) and now it works like a charm. Thank you very much! – Maszeg Nov 03 '19 at 20:11