2

I am solving this problem, a part of the problem that is giving me troubles is formulated as follows:

a. Start from index i=0;

b. Jump to index i=A[i];

c. If the current index i is outside the valid bound of [0..N-1], print “Out” and stop;

d. Else if the current index i is index N-1, print “Done” and stop;

e1. Otherwise, repeat step b;

e2. If doing this leads to an infinite loop, print “Cyclic” and stop;

(all output are without the quotes)

arr is an array of non-negative integers:

let index = 0;
const seen = new Set([0]);
while (true) {
  index = arr[index];
  if (index > arr.length - 1) {
    console.log("Out");
    break;
  }
  if (index === arr.length - 1) {
    console.log("Done");
    break;
  }
  if (seen.has(index)) {
    console.log("Cyclic");
    break;
  }
  seen.add(index);
}

I am getting WA (Wrong Answer) on some hidden test cases, but I can't for the life of me come up with a failing test case.

  • 1 2 3 4 5 0 -> Done
  • 1 2 3 4 6 0 -> Out
  • 1 0 0 -> Cyclic

Edit:

My C++ solution has exactly the same failed test cases, must really be something with my logic...

Bart Louwers
  • 873
  • 9
  • 28

1 Answers1

1

I believe the issue is that the coded algorithm is not adhering to the requirement. Specifically e1 indicates to repeat step b which fetches the next value, and **if doing this** leads to an infinite loop then print "Cycle". The problem is that the code is actually doing it, rather than checking first...

So, as the current code is written, a test case of...

12344

...will return "Done" rather than "Cyclic"...

EDIT In the parlance code, this is what I'm suggesting (untested)...

let index = 0;
const seen = new Set([0]);
while (true) {
  index = arr[index];
  if (index > arr.length - 1) {
    console.log("Out");
    break;
  }
  if (index === arr.length - 1) {
    console.log("Done");
    break;
  }
  if (seen.has(index) || seen.has(arr[index])) {
    console.log("Cyclic");
    break;
  }
  seen.add(index);
}

EDIT #2 Upon getting a chance to test my previously untested code just above, I discovered that it did not capture the nuance of my point. So, in an effort to further clarify, below is the Current and Proposed algorithms, with sample cases to show the similarities and the difference.

The last case, where the cyclic entry is the final entry, is where step e2 reports "Cyclic" before step c is able to report "Done"...

Comments in the proposed() function show the steps of the algorithm...

function current( arr ) {
  let index = 0;
  const seen = new Set([0]);
  while (true) {
    index = arr[index];
    if (index > arr.length - 1) {
      console.log("Out");
      break;
    }
    if (index === arr.length - 1) {
      console.log("Done");
      break;
    }
    if (seen.has(index)) {
      console.log("Cyclic");
      break;
    }
    seen.add(index);
  }
}

function proposed( arr ) {
  // a. Start from index i=0;
  let index = 0;

  // b. Jump to index i=A[i];
  const seen = new Set( [ index ] );
  index = arr[ index ];

  while( true ) {
    // c. If the current index i is outside the valid bound of [0..N-1], print “Out” and stop;
    if ( index > arr.length - 1 ) {
      console.log( "Out" );
      break;
    }
    
    // d. Else if the current index i is index N-1, print “Done” and stop;
    if ( index === arr.length - 1 ) {
      console.log( "Done" );
      break;
    }
    
    // e1. Otherwise, repeat step b;
    seen.add( index );
    index = arr[ index ];
    
    // e2. If doing this leads to an infinite loop, print “Cyclic” and stop;
    if ( seen.has( arr[index] ) ) {
      console.log("Cyclic");
      break;
    }
  }
}

arr = [1,0,2];
console.log( arr );
current( arr );
proposed( arr );

arr = [1,2,3,4,5];
console.log( arr );
current( arr );
proposed( arr );

arr = [1,2,3,6,5];
console.log( arr );
current( arr );
proposed( arr );

arr=[1,2,3,4,0];
console.log( arr );
current( arr );
proposed( arr );
Trentium
  • 3,419
  • 2
  • 12
  • 19
  • 1
    it should print "Done" per the requirement. *"**Otherwise**, repeat step b; **If doing this** leads to an infinite loop, print “Cyclic” and stop;"* – apple apple Feb 06 '22 at 15:59
  • @appleapple steps `c`, `d`, & `e` are written as an `if`, `else if`, `else` construct, so am interpreting `e1` and `e2` as forming the `else` portion of the logic, and not a continuation back to step `b` and a recheck of "Out" or "Done, before then checking for "Cyclic"... – Trentium Feb 06 '22 at 16:11
  • 1
    not sure I understand, so as you said, D ("Done") would execute before E ("Cycle"), so what's wrong with print "Done"? – apple apple Feb 06 '22 at 16:14
  • 1
    It is my understanding, that as soon as we set `index` to `arr.length - 1`, we need to print `Done` and exit. The value of `arr[arr.length - 1]` is never evaluated. – Bart Louwers Feb 06 '22 at 16:17
  • @BartLouwers but not if `e1` and `e2` are a combined step of `e`, in which case the logic to check for "Done" hasn't been reached yet... – Trentium Feb 06 '22 at 16:21
  • @BartLouwers the code sample i added has a follow up tweak, as the `seen.add(index)` was in the wrong spot in my untested code... – Trentium Feb 06 '22 at 16:43
  • 1
    @Trentium Yeah I spooted that. But the answer still fails. I think I'm going to try rewriting it in a different language... – Bart Louwers Feb 06 '22 at 16:45
  • 1
    @BartLouwers The language isn't the problem. – siride Feb 07 '22 at 00:22
  • @BartLouwers if you're willing to humor me a bit more, am interested in the results of the `proposed()` algorithm in Edit #2, which more accurately captures the nuance I was driving at... – Trentium Feb 08 '22 at 01:27
  • @Trentium Fails with one *more* test case ':). I actually found a working [solution](https://github.com/JonSteinn/Kattis-Solutions/blob/master/src/Basic%20Programming%201/Python%203/main.py) on GitHub, but to me it looks the same... – Bart Louwers Feb 08 '22 at 08:00
  • @BartLouwers except it appears that the order of the checks in the working example is different... Ie, the working example is Out-Cyclic-Done, while the spec states Out-Done-Cyclic. Welcome to programming 101, where the first lesson is dealing with requirements that need to be qualified and clarified! ; -) – Trentium Feb 08 '22 at 12:48