Karaethon Posted March 23, 2019 Share Posted March 23, 2019 (edited) ok... I'm still struggling with PHP syntax, my editor's linting keeps flagging a line as incorrect. it's supposed to read as " when d1 minus 1 is less than or equal to d2 with d2 being less than or equal to d1 plus 1" so in other words its supposed to be true if d2 is between d1 minus 1 and d1 plus 1, inclusive. I don't want d2 being the previous number, the same number or the next number relative to d1. The same goes for d3, d4, and d5 (4 and 5 are un coded because why code in errors). That being said... This isn't exactly my correct goal but I'm not sure how to code what I really want... Rules a 3 - 5 digit combo (0 - 99 per digit) where: 1. the numbers are not in order. (1,2,3,4 or 55,56,57,58,59 or 4,3,2,1 or 59,58,57,56,55) 2. no more than 2 numbers in the combo may be the same. (45,12,67,12,78 is ok 17,35,17,24,17 is not) 3. repeat numbers may not occur next to each other (45,12,67,12,78 = valid 45,67,12,12,78 = invalid) I can't seem to find a good way to test this without the commands I know from other languages like CountIf, Iffn and RandSamp. (those are Ti-Basic commands) I know "please do it for me" is frowned upon, and hate saying it (I'd rather learn to do it myself), but if anyone can explain how to do this I'd really appreciate it. Edited March 23, 2019 by Karaethon Quote Link to comment Share on other sites More sharing options...
Barand Posted March 23, 2019 Share Posted March 23, 2019 Are you looking for something like this? function generate($n) { $vault = [ mt_rand(1,99) ]; for ($i=1; $i<$n; $i++) { do { $d = mt_rand(1,99); } while (in_array($d, $vault) || ($d <= $vault[$i-1]-1 && $d >= $vault[$i-1]+1)); $vault[$i] = $d; } return join(', ', $vault); } // Test it for ($i=0; $i<20; $i++) { echo generate(5) . '<br>'; } Quote Link to comment Share on other sites More sharing options...
Karaethon Posted March 23, 2019 Author Share Posted March 23, 2019 (edited) Ok, that appears to do what I'm looking to do, or at least appoximates it enough as to make no difference. I had it run 300,000 times generating 50 digit groups and I found no sequences, also i didnt find any repeats within a sequence. I know the probability is rare but it is possible. My fluency in php is at the "babytalk" level probably so I can read the code you wrote but I don't "see" what it is doing. Could you explain it so I might learn and understand? Edited March 23, 2019 by Karaethon typo correction Quote Link to comment Share on other sites More sharing options...
Barand Posted March 23, 2019 Share Posted March 23, 2019 Commented version function generate($n) { $vault = [ mt_rand(1,99) ]; // put 1st random number into the array for ($i=1; $i<$n; $i++) { do { // keep adding numbers until there are $n of them $d = mt_rand(1,99); // get a new random number } while (in_array($d, $vault) || ($d <= $vault[$i-1]-1 && $d >= $vault[$i-1]+1)); // if it is in the array or within 1 of the previous number, choose another $vault[$i] = $d; // add the new number to the array } return join(', ', $vault); // return the array as a comma-sparated string. } Quote Link to comment Share on other sites More sharing options...
Karaethon Posted March 23, 2019 Author Share Posted March 23, 2019 (edited) Ok, i see now. I have been playing with it and i have questions... 15 minutes ago, Barand said: ($d <= $vault[$i-1]-1 && $d >= $vault[$i-1]+1) this reads (to me) as d is less than or equal to previous number minus 1 AND d is greater than or equal to previous number plus 1, which logically is impossible d cannot be both. BUT when I switch && to || the server hangs and/or if i switch >= to <= the server hangs. Am I misreading it? Also, is there a specific reason you used mt_rand? (performance, output quality, or programmer preference, etc) I created this: function countIf( $find, $arr){ $total = 0; foreach( $arr as $val){ if($val === $find){ $total++; } } return $total; } to meet the requirement of no more than 2 of any number as in_array allowed no repeating Edited March 23, 2019 by Karaethon Quote Link to comment Share on other sites More sharing options...
Barand Posted March 23, 2019 Share Posted March 23, 2019 Had the -1 and +1 the wrong way round. Should be ($vault[$i-1]-1 <= $d && $d <= $vault[$i-1]+1) Quote Link to comment Share on other sites More sharing options...
Karaethon Posted March 23, 2019 Author Share Posted March 23, 2019 (edited) Ok, with that change i now have: <?php function generate($n){ $vault = [ random_int(1,99) ]; for ($i=1; $i<$n; $i++) { do { $d = random_int(1,99); } while (countIf($d, $vault) > 2 || ($vault[$i-1]-1 <= $d && $d <= $vault[$i-1]+1)); $vault[$i] = $d; } return join(', ', $vault); } function countIf( $find, $arr){ $total = 0; foreach( $arr as $val){ if($val === $find){ $total++; } } return $total; } ?> <!doctype html> <html> <head> <title> </title> </head> <body> <?php // Test it for ($i=0; $i<$_GET['count']; $i++) { echo generate($_GET['num']) . '<br><br>'; } ?> </body> </html> and it seems to meet my needs, thank you very much for your time and effort. Edited March 23, 2019 by Karaethon Quote Link to comment Share on other sites More sharing options...
Barand Posted March 23, 2019 Share Posted March 23, 2019 4 minutes ago, Karaethon said: That is how your original post went except secont comparison is >=. ($d <= $vault[$i-1]-1 && $d >= $vault[$i-1]+1) // original ($vault[$i-1]-1 <= $d && $d <= $vault[$i-1]+1) // now mt_rand is a better randomising function than rand(). It doesn't hang for me when I use your countIf() function. Must be something else causing it. Quote Link to comment Share on other sites More sharing options...
Karaethon Posted March 23, 2019 Author Share Posted March 23, 2019 1 minute ago, Barand said: ($d <= $vault[$i-1]-1 && $d >= $vault[$i-1]+1) // original ($vault[$i-1]-1 <= $d && $d <= $vault[$i-1]+1) // now It doesn't hang for me when I use your countIf() function. Must be something else causing it. Yeah, it wasn't the countif, ($d <= $vault[$i-1]-1 && $d <= $vault[$i-1]+1) did it, the <= vs >= without swapping the $d to be next to the && Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.