Forum Moderators: coopster

Message Too Old, No Replies

Long messy code to validate a string of numbers.

Need help!

         

internetheaven

3:46 pm on Oct 30, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Okay, I'm really struggling with this one. I need to check if a string is a "valid lottery sequence". I don't want it to alter the string to make it right, I want to know if an inputted string is already right (true/false). Rules:

1. there must be six numbers made up of two digits.
2. each number must be 49 or under.
3. each number must be unique.
4. the numbers must be in numerical order.

For example:

01, 02, 03, 04, 05, 06 = okay!
02, 01, 03, 04, 05, 06 = nope
01, 01, 03, 04, 05, 06 = nope
01, 02, 03, 04, 05, 51 = nope
01, 02, 03, 04 = nope
1, 2, 03, 04, 05, 06 = nope
01, 02, 03, 04, 05, 06, 07 = nope

But my PHP knowledge is pretty basic. Therefore I'd end up doing things like exploding the string and checking each number using:

preg_match /01|02|03| ... up to 48|49/

to check it is 49 or less. Which is quite a long way to do it for each number. Surely there is a quicker way to check each number is between 1-49?

Also, I know how to sort($numbers); into a sequence, but is there a way to check they are already sorted? Or would I have to sort($numbers); the string, then see if it matches the original using preg_match again?

Lastly, I'm reading up on array_unique() and array_count_values() to cover the requirement of six numbers and them being unique - but squeezing that into a couple of lines (and attempting to include a "two digit" checker) is proving difficult.

I'm hoping that some genius here will be laughing at my childish understanding of PHP whilst reading this, and will be able to spit out an easy, short way to do this in a matter of seconds!

Well? ..... ;)

penders

4:06 pm on Oct 30, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



...exploding the string


Exploding the string is a good start. What is the delimiter? ", " (comma + space)?

Although a bit of a "spanner in the works" is you suggest that "1, 2, 03, 04, 05, 06" should fail - so numbers must be padded to 2 chars, prefixed with "0"?

To be honest, because of the strict requirements, I wouldn't bother trying to call mutliple PHP functions to check ordering, uniqueness, etc. I would step through the exploded array and check each "number" one by one.

lucy24

6:09 pm on Oct 30, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



preg_match /01|02|03| ... up to 48|49/

I don't speak php but I do know Regular Expressions. The package is simply
/^[0-4][0-9]$/
(I prefer \d but use [0-9] if you like.) To get a little more granular,
/^(0[1-9]|[1-4][0-9])$/
will exclude 00. You need the ^anchors$ to ensure that the strings aren't longer than 2 characters.

If the list is comma-delimited, can't you already treat it as an array? Then it's array[count] compared with array[count-1] for "count" values 1 through 5.

penders

6:45 pm on Oct 30, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



If the list is comma-delimited, can't you already treat it as an array?


Well, you'd need to explicitly convert (ie. explode() [uk3.php.net]) it into an array first (0 indexed).
eg.
$myNumbers = explode(', ',$stringOfNumbers);


And then...
foreach ($myNumbers as $number) {
if (!preg_match('/^(0[1-9]|[1-4][0-9])$/',$number)) {
/* INVALID NUMBER */
}
}


I would certainly go with the regular expression (as lucy24 suggests), unless perhaps performance was critical?! PHP will implicitly convert numeric strings to numbers for comparison purposes, so you can do things like:

if ((strlen($number) == 2) && ($number > 0) && ($number < 50)) { ... }


When $number is a string. However, it will silently convert, what you would perhaps consider to be invalid values, to numbers. eg '5k' becomes (int)5. It really depends on what your source data might consist of.

penders

7:13 pm on Oct 30, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Actually, the above is pretty much it.

To check that you have 6 numbers, just count() [uk3.php.net] the array before attempting to loop:
if (count($myNumbers) != 6) {/* FAIL */}


To make sure the numbers are unique and already sorted correctly you just need to make sure that the current $number is greater than the previous (so you'll need to "remember" the previous number at the end of the loop).

lucy24

8:06 pm on Oct 30, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



so you'll need to "remember" the previous number at the end of the loop

Yes, that's why I was thinking of "count" vs. "count-1" (possibly by a different name if "count" is a reserved word in php). At each step you only need to check against the immediately preceding value, because the following value will do its own checking against the present value. Hence 1-5 in a total series of 0-5, where item 0 only has to be checked for format.

If #0 (the first term) is 45 or higher, or #5 (the sixth term) is 05* or lower, everything fails, but it probably isn't cost-effective even to do the test. Put in an escape so if the test fails at any point, you don't continue to the end.


* Is it 49 terms or 50? 00 or 01 through 49. Seems like starting at 01 would screw up a lot of probability formulas, but that's a different thread ;)

penders

8:21 pm on Oct 30, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Yes, that's why I was thinking of "count" vs. "count-1"


Yes, so you were. Just a point on implementation... you can certainly refer to the "count-1" element, however, whether it is easier to do that "in PHP" rather than actually saving the previous value is debatable (both methods require an additional variable and a similar check). Arrays in PHP aren't necessarily contiguous (although it is in this case), so referring to the "count-1" element isn't necessarily the "generic" solution.

Is it 49 terms or 50? 00 or 01 through 49.


If this is the UK lottery, then it's numbers from 1 to 49. (However, if this is "just" the UK lottery then numbers don't normally need to be two digits or sorted in order to be "valid".)