-1
var userInput = prompt('enter number here');
var number = new Array(userInput.toString().split(''));
if (number ????){ //checks if the number is in a continuous stream
alert(correct);
}
else{
alert(invalid);
}

In Javascript, what can I do at "????" to check if it is in a continuous order/stream? Also how can I do this so that it only checks for this order/stream after a specific index in the array? Meaning the user enters say "12345678901234" which would pop up correct, but "12347678901234" would pop up invalid?(note there are two 7's) For the second part "3312345678901234" would pop up correct, how can this be implemented?

BigBob
  • 1,015
  • 1
  • 8
  • 9
  • Because the 7 breaks the order if this helps – BigBob May 02 '13 at 23:53
  • Lets assume numbers cannot be skipped, but when 0 is reached the order has to start over – BigBob May 03 '13 at 00:02
  • "3312345678901234" would be valid because as stated it will only check for the order/stream after a specific index in the array which in this case will be set to from index [2] onwards leaving index [0],[1] unchecked – BigBob May 03 '13 at 00:34

4 Answers4

0

You can make a function that checks any string for a stream of continuous/increasing alpha-numeric characters starting at a given index like this:

function checkContinuous(str, startIndex) {
    startindex = startIndex || 0;
    if (str.length <= startIndex) {
        return false;
    }
    var last = str.charCodeAt(startIndex);
    for (var i = startIndex + 1; i < str.length; i++) {
        ++last;
        if (str.charCodeAt(i) !== last) {
            return false;
        }
    }
    return true;
}

If it's numbers only and wrapping from 9 back to 0 is considered continuous, then it's a little more complicated like this:

function checkContinuous(str, startIndex) {
    // make sure startIndex is set to zero if not passed in
    startIndex = startIndex || 0;
    // skip chars before startIndex
    str = str.substr(startIndex);
    // string must be at least 2 chars long and must be all numbers
    if (str.length < 2 || !/^\d+$/.test(str)) {
        return false;
    }
    // get first char code in string
    var last = str.charCodeAt(0);
    // for the rest of the string, compare to last code
    for (var i = 1; i < str.length; i++) {
        // increment last charCode so we can compare to sequence
        if (last === 57) {
            // if 9, wrap back to 0
            last = 48;
        } else {
           // else just increment
            ++last;
        }
        // if we find one char out of sequence, then it's not continuous so return false
        if (str.charCodeAt(i) !== last) {
            return false;
        }
    }
    // everything was continuous
    return true;
}

Working demo: http://jsfiddle.net/jfriend00/rHH4B/

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • What would happen when it hits 0 and starts again? – BigBob May 02 '13 at 23:55
  • @BigBob - is wrapping to back zero considered continuous? Is this for numbers only? What about continous alpha sequences? This checks for any alphanumeric sequence being continuously increasing. – jfriend00 May 02 '13 at 23:58
  • Just for numbers yes, and I'm not too sure but when it hits 0 it has to know the order is repeating and thus still continuous – BigBob May 03 '13 at 00:01
  • @BigBob - OK, I added a second version that is just for numbers and wraps from 9 to 0 – jfriend00 May 03 '13 at 00:04
  • I'm sorry but I am having a little trouble understanding how your code works. It looks like it is working, however I'm not sure if I can understand it and be able to implement it into my code Edit: I noticed the array you used stored the numbers like (123456), how could this be done if stored like (1,2,3,4,5,6) – BigBob May 03 '13 at 00:21
  • @BigBob - your example said this was user input so I wrote the function to work on a string that the user typed. There is no need to break it into an array just to check for continuous characters in a string. What is it that you don't understand in the implementation? Ask a specific question and I can answer. `charCodeAt()` gets the character code for a specific character index in the string. – jfriend00 May 03 '13 at 00:35
  • Alright, thanks. This makes a lot more sense now. I'll try using what you have on my code and get back with how it worked out – BigBob May 03 '13 at 00:50
  • @BigBob - since you're fairly new here and you have lots of answers to choose from, are you aware that if you get an answer that solves your question, then you should select the best one and click the green checkmark next to the answer? That both rewards the person who provided the answer and also earns you some reputation points for following the desired procedure on StackOverflow. When you have some more reputation points yourself (and thus have earned more privileges), you can upvote (click the up arrow) all answers that were helpful. – jfriend00 May 03 '13 at 03:08
0

This will do the checking in real-time entry, but a similar principle could be used to check an entry on a button submit or similar. I was not 100% sure as to which way you wanted it, so I went for the live method.

HTML

<input id="stream" type="text" />

Javascript

window.addEventListener("load", function () {
    document.getElementById("stream").addEventListener("keyup", function (evt) {
        var target = evt.target;
        var value = target.value;
        var prev;
        var last;
        var expect;

        target.value = value.replace(/[^\d]/, "");
        if (value.length > 1) {
            prev = parseInt(value.slice(-2, -1), 10);
            last = parseInt(value.slice(-1), 10);
            expect = prev + 1;

            if (expect > 9) {
                expect = 0;
            }

            if (last !== expect) {
                target.value = value.slice(0, value.length - 1);
            }
        }
    }, false);
});

On jsfiddle

By changing the value here

if (value.length > 1) {

You can change where the checking starts.

Update: Ok, so it is function that you want, and you insist that it splits the string into an array. Then using the above as a reference, you could convert it to something like this.

Javascript

window.addEventListener("load", function () {
    var testStrings = [
        "0123456789012",
        "0123456789",
        "0123455555",
        "555012345678901234",
        "0123455555"];

    function test(string, offset) {
        if (typeof string !== "string" || /[^\d]/.test(string)) {
            return false;
        }

        var array = string.split("");
        var prev;
        var last;
        var expect;

        return !array.some(function (digit, index) {
            if (index >= offset) {
                prev = parseInt(array[index - 1], 10);
                last = parseInt(digit, 10);
                expect = prev + 1;

                if (expect > 9) {
                    expect = 0;
                }

                if (last !== expect) {
                    return true;
                }
            }

            return false;
        });
    }

    testStrings.forEach(function (string) {
        console.log(string, test(string, 1));
    });
});

On jsfiddle

As your question does not fully specify all possibilities, the above will return true for an empty string (""), of course you can simply add a check at the very beginning for that.

I also do not perform any checking for a valid number for your offset, but again this is something simple that you can add.

Of course these are just one (two) of many possible solutions, but hopefully it will set your mind in the right direction of thought.

Xotic750
  • 22,914
  • 8
  • 57
  • 79
  • That's a lot more than I asked for, however your if statements are pretty much what I was looking for, but could you show me how I could do your if statements by extracting the values out of an array which obtains it's values from my original post?(so the user inputs and then it gets checked) – BigBob May 03 '13 at 00:44
0

No need for arrays, just back though the string one character at a time.

When you hit a 0, substitute 10, and continue until the number is not one more than the previous one.

function continuousFromChar(str, start){
    start= start || 0;
    var i= 0, L= str.length, prev;
    while(L){
        c= +(str.charAt(-- L)) || 10; // use 10 for 0
        prev=+(str.charAt(L- 1));       
        if(c-prev  !== 1) break;
    }
    return  start>=L;
}

var s= "3312345678901234";

continuousFromChar(s,2)

/*  returned value: (Boolean)
true
*/
kennebec
  • 102,654
  • 32
  • 106
  • 127
0

There are some good answers here, but I would like to show a slight variation. I think it is important to showcase some different aspects of JavaScript and separating interests in code.

  1. Functions as first class objects are cool - the exact rules for "continuous" can be changed with only changing the predicate function. Perhaps we should allow skipping numbers? No problem. Perhaps we allow hex digits? No problem. Just change the appropriate follows function for the specific rules.

  2. This can be implemented generically because strings support indexing. This will work just as well over other array-like objects with an appropriate follows function. Note that there are no string-specific functions used in the continuous function.

Code also on jsfiddle:

// returns true only iff b "follows" a; this can be changed
function follows_1Through9WithWrappingTo0(b,a) {
    if (b === "1" && a === undefined) {
        // start of sequence
        return true;
    } else if (b === "0" && a === "9") {
        // wrap
        return true;
    } else {
        // or whatever
        return (+b) === (+a) + 1;
    }
}

function continuous(seq, accordingTo, from) {
   // strings can be treated like arrays; this code really doesn't care
   // and could work with arbitrary array-like objects
   var i = from || 0;
   if ((seq.length - i) < 1) {
       return true;
   }
   var a = undefined;
   var b = undefined;
   for (; i < seq.length; i++) {
      b = seq[i];
      if (!accordingTo(b, a)) {
         return false; // not continuous
      }
      a = b;
   }
   return true;
}

function assert(label, expr, value) {
    if (!(expr === value)) {
        alert("FAILED: " + label);
    }
}

var follows = follows_1Through9WithWrappingTo0;
assert("empty1", continuous("", follows), true);
assert("empty2", continuous("foobar", follows, 6), true);
assert("skip", continuous("331234", follows, 2), true);
assert("good 1", continuous("123456789", follows), true);
assert("good 2", continuous("12345678901234", follows), true);
assert("bad seq 1", continuous("12347678901234", follows), false);
assert("bad seq 2", continuous("10", follows), false);

// here a different predicate ensures all the elements are the same
var areAllSame = function (b, a) {
                     return a === undefined || a === b;
                 };
assert("same", continuous("aaaaa", areAllSame), true);

Note that the skipping could also be extracted out of the continuous function: in a language with better "functional" collection support, such as C#, this is exactly what I'd do first.

user2246674
  • 7,621
  • 25
  • 28