PHP unique numbers not unique - php

I have two different functions, one that generates 5 random cards from value 0-51 (unique), and one function that contain an array containing those 5 cards, and an array that contains some of the numbers from array #1 that would be stored.
The function two function two is to replace new values to array #1 if the value is not in array #2.
It seems to be something wrong here. after generating numbers for a bit i got:
array(27,18,37,27,45)
returned from the newCards function.
Question: How can i fix newCards function 100% to do what it is supposed to do? (aka use first array, check if number is in 2nd array, if not, make unique here too) since here it went something wrong since it returned two of the same numbers.
code:
function UniqueCards() {
$result = array();
while(count($result) != 5) {
$rand = rand(0,51); // reads as 0 = 1, and 51 = 52. aka starts at zero.
if(!in_array($rand,$result)){
$result[] = $rand;
}
}
return $result;
}
function newCards($input,$exclude) {
$i = 0;
$output = array();
while($i < count($input)) {
$rand = rand(0,51);
if(in_array($input[$i], $exclude)) {
$output[$i] = $input[$i];
$i++;
}
else if(!in_array($rand, $input)){
$output[$i] = $rand;
$i++;
}
}
return $output;
}

If you add checking if $rand is already in $output will it fix the problem?
function newCards($input,$exclude) {
...
else if(!in_array($rand, $input) && !in_array($rand, $output)) {
$output[$i] = $rand;
$i++;
}
...
}

Related

PHP -- How to multiple random numbers?

Very new to coding here. Trying to get five random numbers in a range from -10 to 10 generated at once. I have another .php file in which I use the roll_num function, but I'm trying to avoid writing the function 5 different times.
Here is what I currently have:
function roll_num()
{
for ($result = 0; $result <= 5; $result++)
{
$result = [];
$result = rand(-10, 10);
return $result;
}
}
Looking for the simplest way to write this. Help would be useful as I don't know what I'm doing, and this is for an introductory class lol. The way I'm trying is similar to the class example, so I'd like to keep it about the same so that I can follow alongside the course without getting too lost. (Besides what I need to change, of course!) Thanks in advance!
The problem with your code is the return inside of the for loop. As soon you hit the return command the function will exit returning the current value of the result, with only one element. Your return should be out of the for loop.
Try something like this:
<?php
function roll_num()
{
$result = []; // result should start empty
while (count($result) < 5)
{
// every step of the loop should add random value to the array
$result[] = rand(-10, 10);
}
// after all random values were pushed, you return once
return $result;
}
var_export(roll_num());
// http://sandbox.onlinephpfunctions.com/code/cd35d6d65f763963216423f341a4299ce1cee8fe
In your code, you are saving the random number in a variable result and immediately returning it. You should keep an array outside the loop and add numbers to it iteratively. Also the iterator should be a seperate integer not your array itself which should end at index 4.
<?php
function roll_num()
{
$result = [];
for ($i = 0; $i < 5; $i++)
{
$result[] = rand(-10, 10);
}
return $result;
}
print_r(roll_num());
function roll_num()
{
$min = -10;
$max = 10;
$num = 5;
$count = 0;
$return = [];
while ($count < $num) {
$return[] = mt_rand($min, $max);
$return = array_flip(array_flip($return));
$count = count($return);
}
shuffle($return);
return $return;
}
print_r(roll_num());

random_int instead of array_rand in a loop with no doubles

I'm trying to create a generator for a lotto that I play very often.
The lotto is a 5 number draw, ranging from number 1-50 and the same number cannot appear again.
My current approach to do this is using array_rand() but after some reading I noticed that I should not use array_rand() for this purpose, instead I should be using random_int().
My current approach below:
$numbers = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50);
for ($i = 0; $i <= 4; $i++) {
$number = array_rand($numbers);
unset($numbers[$number]);
if ($number == 0) {
$number = array_rand($numbers);
unset($numbers[$number]);
}
$out1[] = array("<div class=\"number\">$number</div>");
}
As you can see above, this works and it generates 5 numbers without duplicating because I unset the number after it's been drawn.
My question is:
How can I do the same as above but using random_int()instead?
To clarify: Use random_int() to generate a random number but ensure that it doesnt generate the same number again in that run.
$numbers = array(); // Create an empty array
while (count($numbers) < 5) { // While less than 5 items in the array repeat the following
$random = random_int(1,50); // Generate a random number
if (!in_array($random, $numbers)) { // Check if the random number is already in the array, and if it is not then:
$numbers[] = $random; // add the random number to the array
}
}
foreach ($numbers as $n) { // Loop over your array and output with your added HTML
echo "<div class=\"number\">$n</div>";
}
Here's the way:
$out = [];
$used = [];
for ($i = 0; $i <= 4; $i++) {
do {
$randInt = random_int(1, 50);
} while (in_array($randInt, $used));
$used[] = $randInt;
$out[] = "<div class=\"number\">$randInt</div>";
}

Three the same characters in a row in string PHP

I have no idea how to create function which counts how many times 3 the same letters in a row reapets in one string?
For example: avcdddjrg return 1, aaargthbbb return 2
I can detect if there are 3 the same characters in a row, but can't figure it out how to count it
$input = 'hellooommm';
if (preg_match('/(.)\1{2}/', $input)) {
return 1;
}else {
return 0;
}
Thank you
Use preg_match_all(), like this:
$input = 'hellooommm';
$n = preg_match_all('/(.)\1{2}/', $input);
if ($n !== false) {
echo "$n matches found", PHP_EOL;
} else {
echo "an error occurred when calling preg_match_all()", PHP_EOL;
}
#hek2mgl's answer above is simple and eloquently solves the problem using regex. But I get the feeling you may benefit from hashing this out logically a bit more. Another approach you could use is iterating over the characters and counting the repetitions like this:
function countGroupsOfThree($str) {
$length = strlen($str);
$count = 1;
$groups = 0;
for ($i = 0; $i < $length; $i++){
// is this character the same as the last one?
if ($i && $str[$i] === $str[$i-1]) {
// if so, increment the counter
$count++;
// is this the third repeated character in a row?
if ($count == 3) {
// if so, increment $groups
$groups++;
}
} else {
// if not, reset the counter
$count = 1;
}
}
return $groups;
}
$str = 'aaavgfwbbb3ds';
echo countGroupsOfThree($str);
OUTPUT: 2
In the grand scheme of things, this function is probably not very useful but hopefully it illustrates some key concepts that will help you figure things like this out in the future.

php loop through array to find X consecutive numbers

I have some code that finds 3 consecutive numbers from an array and outputs them.
What I would like it to do now is be able to tell it how many numbers to find. I did think about putting a for loop inside the outside for loop but i don't see it working properly.
How can i get this iteration to run X times until X is met?
if(isset($arr[$i+1]))
if($arr[$i]+1==$arr[$i+1])
echo 'I found it:',$arr[$i],'|',$arr[$i+1],'|',$arr[$i+2],'|',$arr[$i+3],'<br>';
exit;
This is what i have so far
for($i=0; $i < sizeof($arr); $i++) {
if(isset($arr[$i+1]))
if($arr[$i]+1==$arr[$i+1])
{
if(isset($arr[$i+2]))
if($arr[$i]+2==$arr[$i+2])
{
if(isset($arr[$i+3]))
if($arr[$i]+3==$arr[$i+3])
{
echo 'I found it:',$arr[$i],'|',$arr[$i+1],'|',$arr[$i+2],'|',$arr[$i+3],'<br>';
exit;
}//if3
}//if 2
}//if 1
}
Instead of looking forward repeatedly, you could just loop through the array, comparing the current value to the previous value to see if the values are consecutive, while keeping track of the current consecutive count. Consecutive numbers should be appended to an array, and non-consecutive numbers should reinitialize the array. When you reach the desired count of consecutive numbers, you can return the result.
function find_consecutive($array, $count) {
$consecutive = array();
$previous = null;
foreach ($array as $value) {
if ($previous !== null && $value == $previous + 1) {
$consecutive[] = $value;
if ($found == $count) {
return "I found it: " . implode("|", $consecutive) . "<br>";
}
} else {
$consecutive = array($value);
$found = 1;
}
$previous = $value;
$found++;
}
}

PHP List All Combination of Elements of Array

I have an array:
$arr=array("A","B","C");
I want to make its all of combination as:
array("A")
array("B")
array("C")
array("A","B")
array("A","C")
array("B","C")
array("A","B","C")
i want to make an process all of this combinations but i don't want generate all combinations, store them in an array and apply function to them. Because this requires a lot of memory with large combinations. I have 40 items for this process (I have long time but i don't have enough memory).
I want to have a function like this:
function ProcessArrayCombinations($array){
foreach($array as $v){
//generate and process next combination of array
print_r($nextcombination);
}
}
Thank you.
This code recognizes the combinations as binary numbers, using the fact that there is a formula which states that the sum of all combinations possible from n elements is 2^n. Knowing its binary logarithm is integer, we can define a model where each possible binary number constructed from n digits is a set of combinations. Code is untested, if there are typos, please, let me know in comments.
function ProcessArrayCombinations($array) {
$status = array();
foreach ($array as $element) {
$status[] = false;
}
$elementCount = count($status);
$trues = 0;
while ($trues < $elementCount) {
$index = 0;
$stop = false;
while ((!$stop) && ($index < count($status)) && ($status[$index])) {
$status[$index] = false;
$trues--;
$index++;
}
$status[$index] = true;
$trues++;
//Found a new combination
//We should print elements from $array located at indexes fulfilling
//the criteria that the element having the same index in $status is true:
//for ($i = 0; $i < count($status); $i++) {
// if ($status[$i}) {
// print
// } else {
// don't print
// }
//}
}
}
I edited and used your function as below. Thank you again Lajos.
function ProcessArrayCombinations($array) {
$status = array();
foreach ($array as $element) {
$status[] = false;
}
$elementCount = count($status);
$trues = 0;
while ($trues < $elementCount) {
$index = 0;
$stop = false;
while ((!$stop) && ($index < count($status)) && ($status[$index])) {
$status[$index] = false;
$trues--;
$index++;
}
$status[$index] = true;
$trues++;
//Found a new combination
//We should print elements from $array located at indexes fulfilling
//the criteria that the element having the same index in $status is true:
for ($i = 0; $i < count($status); $i++) {
if ($status[$i]) {
echo $array[$i];
}
}
echo '<br/>';
}
}

Categories