PHP array read out succession - php

In PHP I have an Array like this:
$BulkArray[$i]
This Array is feed with plenty of Numbers (e.g. 1 => 100, 2 => 300, 3 => 100, and so on).
Now I want to find within the whole range of numbers, the greatest succession of a number equal or less than 500. I want to write the number of succession.
for example I have the array
1 => 100, 2 => 300, 3 => 100,
4 => 50, 5 => 50, 6 => 50, 7 => 50, 8 => 50,
9 => 500, 10 => 200, 11 => 100
as you can see, number 1,2 & 3 are together 500. So this is the first succession.
2,3,4,5 are also 500 together. (This succession(4) is bigger than the first succession(3))
And so on,then you will get the highest succession: 3,4,5,6,7,8 (succession with 6 numbers) which is 350 (but lower than 500m, as we searched for it)
Now, how can I write with the Array:
$BulkArray[$i], that the highest succession is 6 ?
Because 6 is the highest succession found in the whole array for 500!
(It's for categorizing specific Carparts)

The answer of User "fas M" here again, with little improvement:
<?php //lets call your $BulkArray = $values;
$values=array( 1 => 100, 2 => 300, 3 => 100,
4 => 50, 5 => 50, 6 => 50, 7 => 50, 8 => 50,
9 => 500, 10 => 200, 11 => 100 );
$sum=0; // to sum up until 500
$Vals500=array(); // array to store index with <= 500
$i=0; // index for new aaray that will store keys that made up <= 500
$key1=1; //value to iterate the array defined above
for($key=1; $key <= count($values); $key++){
$sum = $sum + $values[$key]; // get sum of values
if($sum <= 500){ $Vals500[$i][]=$key; } //append all key of sum ==500
if($sum >= 500) { $i++; $key=$key1++; $sum=0; } //check sum then reintialize
//added bigger equal
}
echo count(max($Vals500)); // read out the biggest succession
?>
Thanks again to fas M !

Click Here or here you can see somehing
<?php //lets call your $BulkArray = $values;
$values=array( 1 => 100, 2 => 300, 3 => 100,
4 => 50, 5 => 50, 6 => 50, 7 => 50, 8 => 50,
9 => 500, 10 => 200, 11 => 100 );
$sum=0; // to sum up until 500
$Vals500=array(); // array to store index with <= 500
$i=0; // index for new aaray that will store keys that made up <= 500
$key1=1; //value to iterate the array defined above
//print_r($values); echo '<br/>';
for($key=1; $key <= count($values); $key++){
$sum = $sum + $values[$key]; // get sum of values
if($sum <= 500){ $Vals500[$i][]=$key; } //append all key of sum ==500
if($sum == 500) { $i++; $key=$key1++; $sum=0; } //check sum then reinitialize values
}
foreach($Vals500 as $val){} //search for second array with many indeces in $Vals500. NB: i fail this place
echo print_r($Vals500);
print 'the highest succession found is '; print_r($Vals500[2]); //
?>

Related

Php random number total 3000 [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 12 months ago.
Improve this question
i want to generate 630 random numbers between 1 and 20. So far, so good. However, the sum of the numbers between 1 and 20 of these 630 produced should not exceed 3000. I could not write such an algorithm. Could you help?
Your problem is that 3000 / 630 = 4.76 which is far from the average number between 1-20. What we can do is constrain the random numbers' ranges to accommodate this, and get a distribution slant with an average sum approximate to the maximum sum.
Given the required maximum average of 4.76, we can for example generate 1/4 of the random numbers as between 1-20, and 3/4 as between 1-4 to slant the distribution:
function get_slanted_rands() {
$rands = [];
for($i = 1; $i <= 630; $i++) {
// For every 4th iteration, get random from the full range
$rands[] = $i % 4 === 0
? mt_rand(1,20)
: mt_rand(1,4);
}
$sum = array_sum($rands);
// If the sum is over the max, recall:
if($sum > 3000) {
return get_slanted_rands();
}
// Log the average for debugging:
$avg = round($sum / count($rands), 2);
return compact('sum', 'avg', 'rands');
}
Notice that the function checks the sum and recalls itself on the odd occasion that the sum exceeds 3000. On a typical call, the sum 3000 isn't exceeded with the above "calibration" — since we split 1:3 in favor of the lower range. But random is random, so there's no "average" guaranteed.
Let's test-drive this contraption for 100 iterations and see what we get:
$test = [];
for($t = 1; $t <= 100; $t++) {
$test[] = get_slanted_rands();
}
$sums = array_column($test, 'sum');
rsort($sums);
echo "==== SUMS ====\n" . implode(', ', $sums) . "\n\n";
$avgs = array_column($test, 'avg');
rsort($avgs);
echo "==== AVGS ====\n" . implode(', ', $avgs);
This yields for the following (reverse sorted), sums between 2600+ and 3000 and averages between 4.75 and 4.19. (On average, ~1:100 iterations exceeds 3000 and is recalled.)
==== SUMS ====
2993, 2985, 2975, 2969, 2959, 2947, 2941, 2933, 2926, 2919, 2919, 2917, 2911, 2909, 2908, 2904, 2903, 2901, 2894, 2894, 2892, 2886, 2884, 2884, 2882, 2881, 2879, 2876, 2871, 2869, 2867, 2863, 2861, 2853, 2852, 2852, 2851, 2851, 2850, 2848, 2844, 2843, 2842, 2838, 2838, 2837, 2837, 2837, 2836, 2834, 2834, 2826, 2826, 2825, 2820, 2814, 2813, 2812, 2802, 2801, 2799, 2799, 2799, 2798, 2796, 2795, 2792, 2789, 2789, 2787, 2784, 2784, 2784, 2783, 2778, 2778, 2776, 2768, 2767, 2764, 2762, 2754, 2754, 2747, 2743, 2737, 2736, 2728, 2727, 2724, 2723, 2721, 2719, 2718, 2707, 2706, 2690, 2673, 2642
==== AVGS ====
4.75, 4.74, 4.72, 4.71, 4.7, 4.68, 4.67, 4.66, 4.64, 4.63, 4.63, 4.63, 4.62, 4.62, 4.62, 4.61, 4.61, 4.6, 4.59, 4.59, 4.59, 4.58, 4.58, 4.58, 4.57, 4.57, 4.57, 4.57, 4.56, 4.55, 4.55, 4.54, 4.54, 4.53, 4.53, 4.53, 4.53, 4.53, 4.52, 4.52, 4.51, 4.51, 4.51, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.49, 4.49, 4.48, 4.48, 4.47, 4.47, 4.46, 4.45, 4.45, 4.44, 4.44, 4.44, 4.44, 4.44, 4.44, 4.43, 4.43, 4.43, 4.42, 4.42, 4.42, 4.42, 4.42, 4.41, 4.41, 4.41, 4.39, 4.39, 4.39, 4.38, 4.37, 4.37, 4.36, 4.35, 4.34, 4.34, 4.33, 4.33, 4.32, 4.32, 4.32, 4.32, 4.31, 4.3, 4.3, 4.27, 4.24, 4.19
You can always tweak the slanting condition if you feel it should on average be closer to 3000... Or simply add a recall condition with a "minimum sum" check and "brute force" it. But this suffices to give you the general idea: You need to generate random numbers of a limited range in proportion to what your "average for target sum" demands. Demo at 3v4l: https://3v4l.org/fG74X
Finally, a sample of the sort of distribution you get. Given as "number" => "instances" in a set of 630. It's heavily slanted to 1, 2, 3, 4 there — and that's how it must be to meet your specs!
$nums = get_slanted_rands();
$distribution = array_count_values($nums['rands']);
arsort($distribution);
print_r($distribution);
// yields:
[3] => 143
[4] => 125
[2] => 125
[1] => 110
[8] => 13
[9] => 12
[18] => 12
[19] => 10
[11] => 9
[5] => 8
[17] => 8
[14] => 7
[12] => 7
[10] => 7
[16] => 7
[6] => 7
[15] => 6
[7] => 6
[20] => 5
[13] => 3
$result = [];
$sumCurrent = 0;
$barrier = 3000 / 630;
for ($i = 1; $i <= 630; $i++) {
$sumBarrier = intval($i * $barrier);
while (true) {
$number = random_int(1, 20);
if ($sumCurrent + $number <= $sumBarrier) {
break;
}
}
$result[] = $number;
$sumCurrent += $number;
}
$sum = array_sum($result);
$occurrences = array_count_values($result);
uksort($occurrences, fn($key1, $key2) => $key1 <=> $key2);
print_r($result); echo "\n";
print_r($sum); echo "\n";
print_r($occurrences); echo "\n";

Calculating Median of an array in PHP

I'm trying to figure out how to calculate the median of an array of randomly generated numbers. I have the array all set up, but I'm having trouble putting together a function for the calcuation.
This is what I have so far:
//array
$lessFifty = array();
$moreFifty = array();
//number generation
for ($i = 0; $i<=30; $i++) {
$number = rand(0, 100);
//Sorting <50>
if ($number < 50 ) {
$lessFifty[] = $number;
} else {
$moreFifty[] = $number;
}
}
echo print_r($lessFifty);
echo "<br>" ;
echo print_r($moreFifty);
//Average
echo "<p> Average of values less than fifty: </p>";
print array_sum($lessFifty) / count($lessFifty) ;
echo "<p> Average of values greater than fifty: </p>" ;
print array_sum($moreFifty) / count($moreFifty) ;
//Median
$func = function (median ($array, $output = $median)){
if(!is_array($array)){
return FALSE;
}else{
switch($output){
rsort($array);
$middle = round(count($array) 2);
$total = $array[$middle-1];
break;
return $total;
}
}
echo $func ;
I'm pretty sure that I'm doing this median section completely wrong. I'm just learning and its proving to be a challenge.
Be careful about how you write your for() loop. If you want 30 entries, then you should not use <= or you will end up with 31 because $i starts with 0.
Build an array of the random numbers, then sort them.
Then determine if you have a central entry (odd array length) or if you need to average the middle two entries (even array length).
Here is a modern implementation of a median method posted in 2022 on CodeReview.
Code: (Demo)
$limit = 30; // how many random numbers do you want? 30 or 31?
for ($i = 0; $i < $limit; ++$i) {
$numbers[] = rand(0, 100);
}
var_export($numbers);
//echo "\n---\nAverage: " , array_sum($numbers) / $limit;
echo "\n---\n";
sort($numbers);
$count = sizeof($numbers); // cache the count
$index = floor($count/2); // cache the index
if (!$count) {
echo "no values";
} elseif ($count & 1) { // count is odd
echo $numbers[$index];
} else { // count is even
echo ($numbers[$index-1] + $numbers[$index]) / 2;
}
Possible Output:
array (
0 => 27,
1 => 24,
2 => 84,
3 => 43,
4 => 8,
5 => 51,
6 => 60,
7 => 86,
8 => 9,
9 => 48,
10 => 67,
11 => 20,
12 => 44,
13 => 85,
14 => 6,
15 => 63,
16 => 41,
17 => 32,
18 => 64,
19 => 73,
20 => 43,
21 => 24,
22 => 15,
23 => 19,
24 => 9,
25 => 93,
26 => 88,
27 => 77,
28 => 11,
29 => 54,
)
---
43.5
After sorting, elements [14] and [15] hold 43 and 44 respectively. The average of these "middle two" values is how the result is determined. (Hardcoded numbers demo)
If you want a short, inflexible, hardcoded snippet, then you can use 30 and 14 and 15 as your predetermined size and indexes.
for ($i = 0; $i < 30; ++$i) {
$numbers[] = rand(0, 100);
}
sort($numbers);
echo ($numbers[14] + $numbers[15]) / 2;

Print 10 largest numeric array values in PHP

Whenever someone adds an 'item' on my website, I log the item number in a file called items_added.log. I want to make a script which shows me the 5 most commonly added items. Let's say this is my array:
1 => 100
2 => 200
3 => 300
4 => 400
5 => 500
6 => 600
7 => 700
8 => 800
9 => 900
10 => 1000
In this case, I would want to print this array;
10 => 1000
9 => 900
8 => 800
7 => 700
6 => 600
5 => 500
How can I do so? Here's my code so far:
<?php
$file = 'items_added.log';
$content = file_get_contents($file);
$arrItems = explode("\n", $content);
function array_count_values_of($value, $array) {
$counts = array_count_values($array);
return $counts[$value];
}
$itemCounts = array();
foreach($arrItems as $item) {
$itemCounts[$item] = array_count_values_of($item, $arrItems);
}
// Somehow print the 5 largest values (the 5 most commonly added items)
// $itemCounts is an array which contains all items ever added & how many times they have been added
// The structure is ItemNumber => Frequency
?>
You should use arsort, this sorts the array on the value (but in reverse, so from highest to lowest).
arsort($itemCounts);
$top5 = array_slice($itemCounts, 0, 5);
Then you have the $top5 of your array in the variable $top5.
Try arsort and array_splice.
No need to use any custom code.
<?php
$arr = [
1 => 100,
2 => 200,
3 => 300,
4 => 400,
5 => 500,
6 => 600,
7 => 700,
8 => 800,
9 => 900,
10 => 1000
];
arsort($arr);
$arr = array_slice($arr, 0, 5, 1);
print_r($arr);
?>
Hope that helps. Please let me know in case of further issues.
<?php
$arr = [
1 => 100,
2 => 200,
3 => 300,
4 => 400,
5 => 500,
6 => 600,
7 => 700,
8 => 800,
9 => 900,
10 => 1000
];
rsort($arr);
print_r($arr);
?>

How to remove integers in array less than X?

I have an array with integers of values from 0 to 100. I wish to remove integers that are less than number X and keep the ones that are equal or greater than number X.
A little ugly using the clunky create_function, but straight forward:
$filtered = array_filter($array, create_function('$x', 'return $x >= $y;'));
For PHP >= 5.3:
$filtered = array_filter($array, function ($x) { return $x >= $y; });
Set $y to whatever you want.
Smarter than generating an array that is too big then cutting it down to size, I recommend only generating exactly what you want from the very start.
range() will do this job for you without the bother of an anonymous function call iterating a condition.
Code: (Demo)
$rand=rand(0,100); // This is your X randomly generated
echo $rand,"\n";
$array=range($rand,100); // generate an array with elements from X to 100 (inclusive)
var_export($array);
Potential Output:
98
array (
0 => 98,
1 => 99,
2 => 100,
)
Alternatively, if you truly, truly want to modify the input array that you have already generated, then assuming you have an indexed array you can use array_slice() to remove elements using X to target the starting offset and optionally preserve the indexes/keys.
Code: (Demo)
$array=range(0,100);
$rand=rand(0,100); // This is your X randomly generated
echo $rand,"\n";
var_export(array_slice($array,$rand)); // reindex the output array
echo "\n";
var_export(array_slice($array,$rand,NULL,true)); // preserve original indexes
Potential Output:
95
array (
0 => 95,
1 => 96,
2 => 97,
3 => 98,
4 => 99,
5 => 100,
)
array (
95 => 95,
96 => 96,
97 => 97,
98 => 98,
99 => 99,
100 => 100,
)

Autogenerate array values with a loop?

I know this doesn't work but is there any way of autogenerating values? It can be pretty tedious to put so many values in specially if it's 50 or maybe 100 numbers...
Here's the code so you get my idea:
for ($num = 1; $num <= 20; $num++){
$arr = array($num);
echo $arr[2];
};
Solved: It was the range() and arrayfill(). :)
Take a look at the range() function.
>> $a = range(1, 10);
array (
0 => 1,
1 => 2,
2 => 3,
3 => 4,
4 => 5,
5 => 6,
6 => 7,
7 => 8,
8 => 9,
9 => 10,
)
>>
Or maybe array_fill()?
Are you talking about the rand() function? That surely exist ;)
PHP Rand Function

Categories