I have a simple array $iteration=[0,1,2,3,4] and I am trying to build a function to increment it to a max value of $max=12 for example and I can't reuse the same number for 2 keys. But so far I have very little success. Here is what I have now.
//$iteration is my array and $max is the maximum value a key can have.
IncrementIteration($iteration,$max){
$count=count($iteration);
while($count > 0){
if( ($iteration[($count-1)] < $max) ){
$iteration[($count-1)]++;
break;
}
$count--;
}
return $iteration;
}
But this never resets the keys that follows the incremented key and does not take into account if the number has already been used.
Here is what I am looking for as example of results:
print_r(IncrementIteration([0,1,2],12))
Output : Array ( [0] => 0 [1] => 1 [2] => 3 )
print_r(IncrementIteration([0,1,12],12))
Output : Array ( [0] => 1 [1] => 2 [2] => 3 )
print_r(IncrementIteration([0,11,12],12))
Output : Array ( [0] => 1 [1] => 2 [2] => 3 )
This would be the highest possible incrementation.
print_r(IncrementIteration([10,11,12],12))
Output : Array ( [0] => 10 [1] => 11 [2] => 12 )
Thanks for any help on this code.
I am adding the other functions to add more clarity about the purpose of this function.
function ReverseSUM($value,$array){
global $debug;
$count=count($array);
$count=3;
$values=array();
while($count > 0){
//Init of While Iteration
$iteration=GenerateIteration($count);
//We iterate
while(SumIteration($iteration,$array) != $value){
if($iteration === IncrementIteration($iteration,(count($array)-1))){
break;
} else {
$iteration=IncrementIteration($iteration,(count($array)-1));
}
//End of While Iteration
}
//End of While Iteration
if(SumIteration($iteration,$array) == $value){
array_push($values,$iteration);
}
unset($iteration);
if($debug){echo "</div>";};
$count--;
}
return $values;
}
function GenerateIteration($number){
$iteration=array();
$count = 0;
while($count < $number){
array_push($iteration,$count);
$count++;
}
return $iteration;
}
function IncrementIteration($iteration,$max){
$count=count($iteration);
while($count > 0){
if( ($iteration[($count-1)] < $max) ){
$iteration[($count-1)]++;
break;
}
$count--;
}
return $iteration;
}
function SumIteration($iteration,$array){
$result=array();
foreach($iteration as $key){
array_push($result,$array[$key]);
}
return array_sum($result);
}
May be some thing like this can help,
function unique_keys_array($array) {
$temp_array = array();
$i = 0;
$key_array = array();
foreach($array as $key) {
if (!in_array($key, $key_array)) {
$key_array[$i] = $key;
$temp_array[$i] = $key;
}
$i++;
}
return $temp_array;
}
print_r(unique_keys_array([1,2,2,3,4,5,6,7,8,8,9,9]));
returns Array
(
[0] => 1
[1] => 2
[3] => 3
[4] => 4
[5] => 5
[6] => 6
[7] => 7
[8] => 8
[10] => 9
)
Here is my final code for my Reverse Sum
function ReverseSUM($value,$array){
ini_set('max_execution_time', 10);
if (!function_exists('GenerateIteration')) {
function GenerateIteration($number){
global $debug;
$iteration=array();
$count = 0;
while($count < $number){
$count++;
array_push($iteration,$count);
}
return $iteration;
}
}
if (!function_exists('IncrementIteration')) {
function IncrementIteration($iteration,$max){
global $debug;
$count=count($iteration);
while($count > 0){
if( $iteration[($count-1)] < $max ){
$iteration[($count-1)]++;
if($count != count($iteration)){
$count2=$count;
while($count2 <= count($iteration)){
if($count2 != count($iteration)){
// if( ($iteration[$count2] < $max) ){
$iteration[$count2]=($iteration[($count2-1)]+1);
// }
}
$count2++;
}
}
break;
}
$max--;
$count--;
}
return $iteration;
}
}
if (!function_exists('SumIteration')) {
function SumIteration($iteration,$array){
global $debug;
$result=array();
foreach($iteration as $key){
array_push($result,$array[$key]);
}
return array_sum($result);
}
}
$count=count($array);
$count=3;
$values=array();
while($count > 0){
//Init of While Iteration
$iteration=GenerateIteration($count);
//We iterate
while(SumIteration($iteration,$array) != $value){
if($iteration === IncrementIteration($iteration,(count($array)-1))){
break;
} else {
$iteration=IncrementIteration($iteration,(count($array)-1));
}
//End of While Iteration
}
//End of While Iteration
if(SumIteration($iteration,$array) == $value){
array_push($values,$iteration);
}
unset($iteration);
$count--;
}
return $values;
}
And here is how I display the results:
<?php foreach($recap as $line => $value){ ?>
<?php if($line<2){?>
<table border="1">
<tr>
<th colspan="2" style="text-align:left;">Line <?=$line?> - <?=$value?></th>
</tr>
<tr>
<th>Iteration</th>
<th>Values</th>
</tr>
<?php foreach(ReverseSUM($value,$invoice) as $iteration => $values){?>
<tr>
<td><?=$iteration?></td>
<td>
<?php foreach($values as $array){?>
<?=($array +1)?><br />
<?php } ?>
</td>
</tr>
<?php } ?>
</table>
<?php } ?>
<?php } ?>
The $recap array simply contains the total values we are searching for. And the $invoice array contains all the invoice lines totals.
Code available on GitHub : https://github.com/LouisOuellet/ReverseSUM
Sheers
Related
I'm trying to solve a backward prime question.
Following is the question:
Find all Backwards Read Primes between two positive given numbers (both inclusive), the second one being greater than the first one. The resulting array or the resulting string will be ordered following the natural order of the prime numbers.
Example
backwardsPrime(2, 100) => [13, 17, 31, 37, 71, 73, 79, 97]
backwardsPrime(9900, 10000) => [9923, 9931, 9941, 9967]
I tried doing something like this:
public function backwardPrime()
{
$start = 7000;
$stop = 7100;
$ans = [];
while($start <= $stop)
{
if($start > 10)
{
if($start !== $this->reverse($start))
{
if($this->isPrime($start) && $this->isPrime($this->reverse($start)))
{
array_push($ans, $start);
}
}
}
$start++;
}
return $ans;
}
public function reverse($num)
{
$reverse = 0;
while($num > 0)
{
$reverse = $reverse * 10;
$reverse = $reverse + $num%10;
$num = (int)($num/10);
}
return $reverse;
}
public function isPrime($num)
{
if($num == 1 || $num == 2 || $num == 3)
return true;
elseif ($num%2 == 0 || $num%3 == 0)
return false;
else
{
$i=5;
while($i<=$num/2)
{
if($num%$i===0)
{
return false;
}
$i++;
}
}
return true;
}
I'm able to get the appropriate answer but while doing the same in single function I'm not able to get it:
public function backwardPrimes()
{
$start = 7000;
$stop = 7100;
$ans = [];
while($start <= $stop)
{
$isStartPrime = true;
$isReversePrime = true;
if($start > 10)
{
$reverse = 0;
$num = $start;
while($num > 0)
{
$reverse = $reverse * 10;
$reverse = $reverse + $num%10;
$num = (int)($num/10);
}
if($start !== $reverse)
{
if($start%2 != 0 && $start%3 != 0)
{
$i =5;
while($i<=$start/2)
{
if($start%$i === 0)
{
$isStartPrime = false;
break;
}
$i++;
}
}
if($reverse%2 != 0 && $reverse%3 != 0)
{
$i =5;
while($i<=$reverse/2)
{
if($reverse%$i === 0)
{
$isReversePrime = false;
break;
}
$i++;
}
}
if($isStartPrime && $isReversePrime)
{
array_push($ans, $start);
}
}
}
$start++;
}
return $ans;
}
I don't know where I'm having mistake, guide me.
Thanks.
An emirp ("prime" spelled backwards) is a prime whose (base 10) reversal is also prime, but which is not a palindromic prime. in other words
Backwards Read Primes are primes that when read backwards in base 10 (from right to left) are a different prime. (This rules out primes which are palindromes.)
try this short solution in which I use two helper function reverse and isPrime :
isPrime: Thanks to #Jeff Clayton for his method to test prime numbers, for more information click the link below https://stackoverflow.com/a/24769490/4369087
reverse: that use the php function [strrev()][1], this method take a string a reverse it, we'll use this trick to reverse a number by converting it to a string reverse it and converting back to an integer.
backwardsPrime: this last function's job is itterating over a range of numbers from $min value to $max value and test if the number if a prime number and it's reverse is a prime number as well and it's not a palindrome number if all of those conditions are true then we addit to the result array.
implementation
function isPrime($number)
{
return !preg_match('/^1?$|^(11+?)\1+$/x', str_repeat('1', $number));
}
function reverse($n)
{
return (int) strrev((string) $n);
}
function backwardsPrime($min, $max)
{
$result = [];
foreach(range($min, $max) as $number) {
$reverse = reverse($number);
if($reverse !== $number && isPrime($number) && isPrime($reverse)) {
$result[] = $number;
}
}
return $result;
}
echo "<pre>";
print_r(backwardsPrime(2, 100));
print_r(backwardsPrime(9900, 10000));
output :
Array
(
[0] => 13
[1] => 17
[2] => 31
[3] => 37
[4] => 71
[5] => 73
[6] => 79
[7] => 97
)
Array
(
[0] => 9923
[1] => 9931
[2] => 9941
[3] => 9967
)
you can even optimize the backwardsPrime function like this :
function backwardsPrime($min, $max)
{
$result = [];
foreach(range($min, $max) as $number) {
$reverse = reverse($number);
if($reverse !== $number && !in_array($number, $result) && isPrime($number) && isPrime($reverse)) {
$result[] = $number;
}
}
return $result;
}
If I wanted to create a foreach loop that would add every second player to team A or team B
foreach ( $selectedplayers as $selectedplayer ) {
TeamA[] = $selectedplayer;
$selectedplayer++;
TeamB[] = $selectedplayer;
}
I know I can do it with a for loop but was interested to see if it could be done this way.
No. $selectedplayer is the actual value of each element. Either use your own counter:
$i = 0;
foreach ( $selectedplayers as $selectedplayer ) {
if($i % 2 === 0)) {
$TeamA[] = $selectedplayer;
} else {
$TeamB[] = $selectedplayer;
}
$i++;
}
Or use the $key of the array if the keys are sequential (or at least odd, even pattern):
foreach ( $selectedplayers as $key => $selectedplayer ) {
if($key % 2 === 0)) {
$TeamA[] = $selectedplayer;
} else {
$TeamB[] = $selectedplayer;
}
}
I have a list containing a bunch of values from 1-400. I am trying to divide the data into ranges like [1-50], [51-100], .. , [351-400] and get the count for the values that falls within the range given . I basically have the code working. So, my question would be is there a better way to do this or what would be a good practise for this?
$temp = array(); //temp array to store the values from mysql
$final_array = array //final array to store the counts from the range initialized to 0
(
"0" => 0,
"1-50" => 0,
"51-100" => 0,
"101-150" => 0,
"151-200" => 0,
"201-250" => 0,
"251-300" => 0,
"301-350" => 0,
"351-400" => 0
);
$sql = "SELECT count(*) AS total FROM user GROUP BY user_id";
$statement = $DB_->link->prepare ( $sql );
$statement->execute ();
if ($result = $statement->get_result ())
{
while ( $row = $result ->fetch_assoc() )
{
$temp [] = $row;
}
}
else
{
die(mysql_error());
}
foreach ($temp as $child)
{
if( $child['total'] >= 351 && $child['total'] <= 400)
{
$final['351-400']++;
}
elseif( $child['total'] >= 301 && $child['total'] <= 350)
{
$final['301-350']++;
}
...
elseif( $child['total'] >= 1 && $child['total'] <= 50)
{
$final['1-50']++;
}
}
Desired results
Array
(
[0] => 0
[1-50] => 1
[51-100] => 0
[101-150] => 0
[151-200] => 1
[201-250] => 0
[251-300] => 4
[301-350] => 5
[351-400] => 18
)
I would iterate over the keys of final_array, exploding them using - as the delimiter. While this method is slower than what you have, as it's iterating over final_array for each row returned from the database, it is much more maintainable, as it seamlessly handles keys for exact matches (only 1 number), and arbitrary ranges. Adding more buckets simply requires editing the final_array array, rather than changing a bunch of lines of code.
foreach ($temp as $child) {
foreach($final_array as $key => $value) {
if (strpos($key, '-') === false) {
if ($child['total'] == intval($key)) {
$final_array[$key]++;
}
} else {
list($min, $max) = explode('-', $key);
if ($child['total'] >= intval($min) && $child['total'] <= intval($max)) {
$final_array[$key]++;
}
}
}
}
I would also forgo the use of the $temp array, simply processing the results as they are returned:
if ($result = $statement->get_result ())
{
while ( $child = $result->fetch_assoc() ) {
foreach($final_array as $key => $value) {
if (strpos($key, '-') === false) {
if ($child['total'] == intval($key)) {
$final_array[$key]++;
}
} else {
list($min, $max) = explode('-', $key);
if ($child['total'] >= intval($min) && $child['total'] <= intval($max)) {
$final_array[$key]++;
}
}
}
}
}
else
{
die(mysql_error());
}
The most efficient system would load all the results in an array, pass that array through array_count_values, and then aggregate those.
This is the best way which you used & for single key count we use PHP function array_count_values
An example output of the following code may be this:
39 48 39 12 17 39 12
code:
if (mysql_num_rows($filterResult)) {
while ($filterrow = mysql_fetch_array($filterResult)) {
$vidID = $filterrow['routineID'];
...
...
echo "<video id='video$vidID'></video>";
}
}
I need it to output like this:
39 48 39_1 12 17 39_2 12_1
Notice how value 39 occurs three times and value 12 occurs twice.
After the first occurence of a value I need it
formatted like ##_#.
Can you help me code this up?
I appreciate your time and assistnace -
Derek
Use array_count_values like this:-
$array = array(1, 38, 1, 38,35);
print_r(array_count_values($array));
Output:-
Array
(
[1] => 2
[38] => 2
[35] => 1
)
Apply some logic to achieve what you want.
if (mysql_num_rows($filterResult)) {
$tmp = array();
while ($filterrow = mysql_fetch_array($filterResult)) {
$vidID = $filterrow['routineID'];
if(isset($tmp[$vidID]) {
$tmp[$vidID] = $tmp[$vidID] + 1;
$vidID = $vidID . '_' . $tmp[$vidID];
} else {
$tmp[$vidID] = 0;
}
echo $vidID;
}
}
if (mysql_num_rows($filterResult)) {
while ($filterrow = mysql_fetch_array($filterResult)) {
$j=-1;
$vidID = $filterrow['routineID'];
$arr[]=$vidID;
for($i=0;$i<count($arr);$i++){
if($arr[$i]==$vidID)
$j++;
}
if($j==0)
$j="";
else $j="_".$j;
echo $vidID.$j;
}
}
Here is the code:
$array1 = array(39,48,39,12,17,39,12);
$array2 = array(39,48,39,12,17,39,12);
foreach($array1 as $value){
$counts1 = array_count_values($array1);
$counts2 = array_count_values($array2);
if(!empty($counts2[$value])){
if ($counts1[$value] > 1){
$count = $counts1[$value] - $counts2[$value] + 1;
if($count > 1) {
echo $value.'_'.($count - 1).' ';
} else {
echo $value.' ';
}
} else {
echo $value.' ';
}
array_shift($array2);
}
}
Here is the PHP fiddle
I have an array with values that change from time to time. It will usually look like this:
Array ( [0] => 0 [1] => 0 [2] => 9876 [3] => 0 [4] => 0 [5] => 0 [6] => 0 [7] => 0 [8] => 0 [9] => 0 [10] => 0 [11] => 0 )
All of the Values will be 0 except for one (index location will change).
If more than one value is greater than 0, I need to execute a specific command.
Else, if only one value is greater than 0, I need to take that value and pass it to a specific command.
Create a new array containing only the non-null values. array_filter without callback will return all elements which do not evaluate to FALSE.:
$a = array(...);
$values = array_filter($a);
switch(count($values)) {
case 0: echo 'All 0!'; break;
case 1: specificCommandWithValue($values[0]); break;
default: executeSpecificCommand(); break;
}
If you have false-y values, you want to keep (FALSE, NULL, '0', ''), pass a callback which does strict value comparison: function($el) { return $el !== 0; }
try
$count =0;
foreach($array as $item){
if($item !=0){
$count = $count+1;
}
}
if($count > 1){
//execute a specific command
}elseif($count == 1){
// take that value and pass it to a specific command
}else{
//all value are zero
}
Try this code.
<?PHP
$array = array(
"1" => "0",
"2" => "0",
"3" => "0",
"4" => "24",
"5" => "0");
$zero_plus_keys = 0;
$zero_plus_val = array();
foreach($array as $key => $val)
{
if($val > 0)
{
$zero_plus_keys++;
$zero_plus_val = array($key,$val);
}
}
if($zero_plus_keys == 1)
{
echo "In array '".$zero_plus_val[0]."' key contains Greater than zero value. the value is = '".$zero_plus_val[1]."'";
}
elseif($zero_plus_keys > 1)
{
echo "More keys Greater than zero(0)";
}
else
{
echo "All keys contains zero(0)s only...";
}
?>
This is #NullPointer's answer, but I added in a variable to hold "that value".
$count =0;
$nonzero = null;
foreach($array as $item){
if($item !=0){
$count = $count+1;
$nonzero = $item;
}
}
if($count > 1){
//execute a specific command
}elseif($count == 1){
specific_command($nonzero);
}else{
//all value are zero
}
$array = 'your array';
function Find($array){
$count = 0;
$needle = -1;
foreach($array as $item){
if($item > 0){
$count++;
$needle = $item;
}
if($count > 1)
return -1; //error as number of non-zeroes greater than 1
}
if($count > 0)
return $needle; //returns the required single non-zero item
return 0; // returns zero if nothing is found
}
$return = Find($array);
Just for fun :P
$array = array_flip(array_flip($array));
sort($array);
if (count($array) > 2) moreThanOne();
else onlyOne($array[1]);
Filter the array and if there is only one use current() to get it:
if(count($n = array_filter($array)) == 1) {
execute_command(current($n));
} else {
execute_command();
}