php loop through array to find X consecutive numbers - php

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++;
}
}

Related

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.

Solving Algorithm (Josephus permutation) in PHP

Suppose 100 people line up in a circle. Counting from person 1 to person 14, remove person from the circle. Following the count order, counting again and remove the 14th person. Repeat. Who is the last person standing?
I've tried everything to solve this and it seems to not be working with dead loops.
<?php
//init array
$array = array();
for ($i = 0; $i < 100; $i++) { $array[] = $i; }
//start from 0
$pos = 0;
while (count_not_null($array) > 1) {
//reset count
$count = 0;
while (true) {
//ignore NULL for count, that position is already removed
if ($array[$pos] !== NULL) {
$count++;
if($count == 14) { break; }
}
$pos++;
//go back to beginning, we cant go over 0-99, for 100 elements
if ($pos > 99) { $pos = 0; }
}
echo "set index {$pos} to NULL!" ."<br>";
$array[$pos] = NULL;
if (count_not_null($array) === 1) { break; }
}
echo "<pre>";
print_r($array);
echo "</pre>";
//counting not null elements
function count_not_null($array) {
$count = 0;
for ($i = 0; $i < count($array); $i++) {
if ($array[$i] !== NULL) { $count++; }
}
return $count;
}
?>
For solving this with as little code as possible and quickest you could do like this:
function josephus($n,$k){
if($n ==1)
return 1;
else
return (josephus($n-1,$k)+$k-1) % $n+1;
}
echo josephus(100,14);
Here we are using an recursive statement instead, as what you are trying to solve can be defined by this mathematical statement f(n,k) = (f(n-1,k) + k) % n
For reading more about this mathematical formula you can see it here on the wiki page.
The problem is this while loop
while ($count < 14) {
if ($array[$pos] != NULL) {
$count++;
}
$pos++;
if ($pos > 99) { $pos = 0; }
}
Because you increment $pos even if count is 14 you will end with incorrect values and loop forever. Replace it with this:
while (true) {
if ($array[$pos] != NULL) {
$count++;
if($count == 14) {break;}
}
$pos++;
if ($pos > 99) { $pos = 0; }
}
Also comparing 0 to NULL won't give you the expected results as mentioned by #Barmar, so you can either change the NULL comparison, or start counting from 1
NOTE: This would be way faster if you didn't loop through array every time :D consider using a variable to count the remaining items
Anyone who stumbles across this again, here is a slightly quicker one:
function josephus($n){
$toBin = decbin($n); // to binary
$toBack = substr($toBin,1) . "1"; // remove first bit and add to end
return bindec($toBack); // back to value
}
Based on this solution.

PHP unique numbers not unique

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++;
}
...
}

Issue with custom script to sort Arrays ascending and descending order

I have an issue to deal with here (a logical error in my code 99%). I just can't seem to find the way to fix it, but I bet one of you will find the problem in no time!
I have to create a function which sorts array passed to it in asc or desc order, but can't use any array sorting functions !
I've been struggling with loops until now and I finally want to ask help from other devs ( you ).
Currently only code for ascending is worked on, descending will be no problem I assume once I do this one. It kinda of does sort values up to some point, but then stops ( it stops if the next smallest value is at the end of the passed array ). What could I do to prevent this and make it sort the whole array and it's elements?
Here is the code so far.
<?php
function order_array($array,$mode = 'ascending') {
$length = count($array);
if($mode == 'descending') {
return $array;
} else {
$sorted_array = array();
$used_indexes = array();
for($i = 0; $i < $length; $i++) {
$smallest = true;
echo $array[$i] . '<br/>';
for($y = 0; $y < $length; $y++) {
//echo $array[$i] . ' > ' . $array[$y] . '<br/>';
// if at ANY time during checking element vs other ones in his array, he is BIGGER than that element
// set smallest to false
if(!in_array($y,$used_indexes)) {
if($array[$i] > $array[$y]) {
$smallest = false;
break;
}
}
}
if($smallest) {
$sorted_array[] = $array[$i];
$used_indexes[] = $i;
}
}
return $sorted_array;
}
}
$array_to_sort = array(1, 3, 100, 99, 33, 20);
$sorted_array = order_array($array_to_sort);
print_r($sorted_array);
?>
I've solved the issue myself by doing it completely different. Now it sorts correctly all the elements of the passed in array. The logical issue I had was of using for() loop. The for() loop ran only a set ( length of passed array ) number of times, while we need it to loop more than that, because we will need to loop all the way untill we have a new sorted array in ascending order. Here is the code that will work
function order_array($array,$mode = 'ascending') {
if($mode == 'descending') {
// for() wont work here, since it will only loop an array length of times, when we would need it
// to loop more than that.
while(count($array)){
$value = MAX($array);
$key = array_search($value, $array);
if ($key !== false) {
unset($array[$key]);
}
$sorted[] = $value;
}
return $sorted;
} else {
// for() wont work here, since it will only loop an array length of times, when we would need it
// to loop more than that.
while(count($array)){
$value = MIN($array);
$key = array_search($value, $array);
if ($key !== false) {
unset($array[$key]);
}
$sorted[] = $value;
}
return $sorted;
}
}
function order_array($array,$mode = 'ascending') {
$length = count($array);
$sorted_array = array();
$used_indexes = array();
for($i = 0; $i < $length; $i++) {
$smallest = true;
echo $array[$i] . '<br/>';
for($y = 0; $y < $length; $y++) {
//echo $array[$i] . ' > ' . $array[$y] . '<br/>';
// if at ANY time during checking element vs other ones in his array, he is BIGGER than that element
// set smallest to false
if(!in_array($y,$used_indexes)) {
if($array[$i] > $array[$y]) {
$smallest = false;
break;
}
}
}
if($smallest) {
$sorted_array[] = $array[$i];
$used_indexes[] = $i;
}
if($mode == 'descending') {
return array_reverse($sorted_array);
}
return $sorted_array;
}
}

Display even & odd numbers

I am trying loop through an array of random numbers if the the number is dividable by two then it's even and I then want to assign this to an array $even[], and if odd then assign it to the odd array. I have managed to display the results without using an array but for the sake of this I want to put them into their own array. However I can't seem to get this result I'm after all I get is this error: message Array to string conversion.
<?php
$numbers = array();
for ($i=0; $i<=1000; $i++) {
$numbers[]=mt_rand(1,1000);
if ($i % 2 == 0){
$even[]=$i;
} else {
$odd[]=$i;
}
}
echo $even;
echo $odd;
?>
Try this to echo the results.
foreach ($even as $evens){
echo $evens . '<br/>';
}
define $odd and $even as a array
$even = array();
$odd = array();
check if($i%2 == 0)
{
$even[] = $i;
}
else
{
$odd = $i;
}
var_dump($even);
var_dump($odd);

Categories