first foreach
foreach (range(1, 70) as $num) {
echo 'Number '.$num.'<br />';
}
second
ksort($numbers);
foreach ($numbers as $key => $value){
echo 'Number '.$key.' = '.$value.' times<br />';
}
First Foreach create numbers list from 1 to 70.
Second Foreach take some info from db ($numbers) like
Number 1 = 1 times
Number 2 = 1 times
Number 6 = 1 times
Number 11 = 1 times
Number 12 = 1 times
Number 13 = 1 times
Number 14 = 1 times
Number 16 = 1 times
Number 17 = 1 times
Number 21 = 2 times
Number 24 = 1 times
Number 25 = 1 times
Number 28 = 1 times
Number 30 = 1 times
Number 31 = 2 times
Number 33 = 1 times
Number 36 = 3 times
Number 38 = 1 times
Number 63 = 1 times
Number 65 = 1 times
Now i need do this work like this:
if($key==$num){
echo 'Number '.$key.' = '.$value.' times<br />';
}else{
echo 'Number '.$key.' = 0 times<br />';
}
All this list from 1 to 70 with show how much times (if exists). Thanks
I would make an associative array for that with the number as key and the value is the number.
$numbers = array();
foreach (range(1, 70) as $num)
{
$numbers[$num] = 0;
}
and with the database loop you combine them
foreach ($dbnumbers as $num => $value)
{
$numbers[$num] += $value;
}
Then you can just iterate over it for displaying ;)
To me, it looks like you're counting occurrences of numbers.
$counter = array();
foreach ($numbers as $num) {
if (!isset($counter[$num]) {
$counter[$num] = 1;
}
else {
$counter[$num]++;
}
}
print_r($counter); # You have all of your occurrences loaded into this tidy array.
Related
I am using Laravel and MySQL,
Supposing I have a percentage value not found between the two percentage columns (percentage_from, percentage_to), for example, if it's equal to 33, I need to get the closest percentage row which is the first row in this case, if it's 35 then the second row if it's 66 then the third row.
type
attendance_from
attendance_to
payment_percentage
percentage_from
percentage_to
Monthly
1
10
100
0
32.258064516129
Monthly
11
20
70
35.483870967742
64.516129032258
Monthly
21
31
50
67.741935483871
100
I tried this function:
public function getClosest(array $array, $value) {
$closest = null;
$res = null;
foreach ($array as $item) {
if ($closest === null || abs($value - $closest) > abs($item['percentage_to'] - $value)) {
$closest = $item['percentage_to'];
$res = $item;
}
}
return $res;
}
I fixed it in another way: I have eliminated the gap between the percentages columns, so if the first row ends with 32.25, then the second row will start from 32.25.
type
attendance_from
attendance_to
payment_percentage
percentage_from
percentage_to
Monthly
1
10
100
0
32.25
Monthly
11
20
70
32.25
64.51
Monthly
21
31
50
64.51
100
I am still a novice at PHP scripting.
I have an Array
$students = array(1201=>94,1203=>94,1200=>91, 1205=>89, 1209=>83, 1206=>65, 1202=>41, 1207=>38,1208=>37, 1204=>37,1210=>94);
From the associative array, the key are the student's exam no and the values are the student's scores. Then I used the 2 inbult PHP functions array_keys and array_values to separate the exam nos from the scores.
$exam_nos=(array_keys($students));
$marks=(array_values($students));
Then I passed the $marks array through the code below:
$i=0;
$occurrences = array_count_values($marks);
$marks = array_unique($marks);
echo '<table border="1">';
foreach($marks as $grade) {
if($grade == end($marks))$i += $occurrences[$grade]-1;
echo str_repeat('<tr><td>'.$grade.': '.($i+1).'</td></tr>',$occurrences[$grade]);
$i += $occurrences[$grade];
}
echo '</table><br />';
output:
94: 1
94: 1
94: 1
91: 4
89: 5
83: 6
65: 7
41: 8
38: 9
37: 11
37: 11
And this is closer to what I want; to rank the scores such that if a tie is encountered, 1 or more positions are skipped, occurs at the end the position the items at the end are assigned a position equivalent toi the total number of ranked items. However, it would be much helpful if this could be done without separating the Array into 2 ...
Questions:
(1) I am pulling my hair how, from the $student array I could have something like:
Exam No Score Position
1201 94 1
1210 94 1
1203 94 1
1200 91 4
1205 89 5
1209 83 6
1206 65 7
1202 41 8
1207 38 9
1204 37 11
1208 37 11
(2) I would like to be able to pick any student by exam no and be able to echo or print out her position e.g
the student 1207 is number 9.
I think I need to capture the postions in a variable, but how do I capture them? Well I don't know!
Could the experts help me here with a better way to achieve my 2 goals (please see questions 1 and 2)? I will try any suggestion that will help me disolve the 'metal blockage' I have hit.
If you're pulling out the students from a database (mentioned in the comments), you could retrieve them with the desired format directly using SQL.
However, I'm going to assume that that's not an option. You could do as follows:
$students = array(1201=>94,1203=>94,1200=>91, 1205=>89, 1209=>83, 1206=>65, 1202=>41, 1207=>38,1208=>37, 1204=>37,1210=>94);
arsort($students);// It orders high to low by value. You could avoid this with a simple ORDER BY clause in SQL.
$result = array();
$pos = $real_pos = 0;
$prev_score = -1;
foreach ($students as $exam_n => $score) {
$real_pos += 1;// Natural position.
$pos = ($prev_score != $score) ? $real_pos : $pos;// If I have same score, I have same position in ranking, otherwise, natural position.
$result[$exam_n] = array(
"score" => $score,
"position" => $pos,
"exam_no" => $exam_n
);
$prev_score = $score;// update last score.
}
$desired = 1207;
print_r($result);
echo "Student " . $result[$desired]["exam_no"] . ", position: " . $result[$desired]["position"] . " and score: ". $result[$desired]["score"];
Hope it helps you.
I would use a custom object to process the students individually and store them in an array.
$students = array(1201=>94,1203=>94,1200=>91, 1205=>89, 1209=>83, 1206=>65, 1202=>41, 1207=>38,1208=>37, 1204=>37,1210=>94);
arsort($students); // Sort the array so the higher scores are on top.
$newStudents = array();
$pos = 0;
$count = 0;
$holder = -1; // Assuming no negative scores.
foreach($students as $k=>$v){
$count++; // increment real counter
if($v < $holder || $holder == -1){
$holder = $v;
$pos = $count;
}
$newStudents[] = makeStudent($pos, $v, $k);
// If you want the exam # as the array key.
// $newStudents[$k] = $student;
}
$newStudents = fixLast($newStudents);
// outputs
print_r($newStudents);
foreach($newStudents as $v){
echo "position : " . $v->position . "<br>";
echo "score : " . $v->score . "<br>";
echo "exam : " . $v->exam . "<br>";
}
function makeStudent($pos, $score,$examNo){
$student = new stdClass(); // You could make a custom, but keeping it simple
$student->position = $pos;
$student->score = $score;
$student->exam = $examNo;
return $student;
}
function fixLast($students){
$length = count($students) -1;
$count = 0;
$i = $length;
while($students[$i]->position == $students[--$i]->position){
$count++;
}
for($i = 0; $i <= $count; $i++){
$students[$length - $i]->position = $students[$length - $i]->position + $count;
}
return $students;
}
I am trying to figure out how I can loop out possible combinations of a x amount of integers to sum a specifik number.
Let's say, I have number 7 and I need to figure out how I can sum that number with integers in pairs 3.
1+2+4 = 7
3+3+1 = 7
5+1+1 = 7
2+2+3 = 7
Repeated combinations of numbers doesn't interest me, e.g.:
1+2+4 = 7
2+4+1 = 7
4+2+1 = 7
Anyone got any ideas of how I should proceed to reach this result?
Thanks.
Here is the solution for your problem.
function printPartitions($target, $max, $s){
if($target === 0 )
echo $s;
else
{
if($max > 1)
{
printPartitions($target, $max-1, $s);
}
if($max <= $target)
{
printPartitions($target-$max, $max, $max . " " . $s);
}
}
}
printPartitions(5, 5, "<br/>");
You have to specify the $target Value, $max value.
e.g.
printPartitions(7, 7, "<br/>");
It will give you output like:
1 1 1 1 1 1 1
1 1 1 1 1 2
1 1 1 2 2
1 2 2 2
1 1 1 1 3
1 1 2 3
2 2 3
1 3 3
1 1 1 4
1 2 4
3 4
1 1 5
2 5
1 6
7
I've got a solution to my problem. I feel I should defientely share it here, if anyone would ever need it. My solutions is based on this post: https://stackoverflow.com/a/19067884/3293843
<?php
function sampling($chars, $size, $combinations = array()) {
# if it's the first iteration, the first set
# of combinations is the same as the set of characters
if (empty($combinations)) {
$combinations = $chars;
}
# we're done if we're at size 1
if ($size == 1) {
return $combinations;
}
# initialise array to put new values in
$new_combinations = array();
# loop through existing combinations and character set to create strings
foreach ($combinations as $combination) {
foreach ($chars as $char) {
$new_combinations[] = $combination .'#'. $char;
}
}
# call same function again for the next iteration
return sampling($chars, $size - 1, $new_combinations);
}
// example
$chars = array('1', '2', '3','4');
$target = 7;
$maxLengthOfIntegers = 3;
$output = sampling($chars, $maxLengthOfIntegers);
$repeatedEntries = array();
//presenting the output
foreach($output as $out){
$explodeOut = explode('#',$out);
sort($explodeOut);
if(array_sum($explodeOut) == $target){
$sortedPattern = implode('',$explodeOut);
if(!in_array($sortedPattern,$repeatedEntries)){
echo $sortedPattern.'<br/>';
$repeatedEntries[] = $sortedPattern;
}
}
}
?>
Thank you for your time and efforts.
Regards,
Jacob
you can try this algorithm
$ans = array();
for($i=1;$i<=5;$i++)
{
$i1 = 7-$i;
$i2 = intval($i1 - $i);
$value = $i."+".$i1."+".$i2;
$ans = array_unshift($ans,$value);
}
print_r($ans);
hope this helps.. PLease let me know
I've got these two functions:
function drawNumber($drawnNumbers){
$unique = true;
while ($unique == true){
$number = mt_rand(10, 69);
if (!in_array($number, $drawnNumbers)){
return $number;
$unique = false;
}
}
}
fillCard(); ?>
It's a bingo game. The card gets filled with random Numbers. But I can't get it like this:
column column column column column column
row 10 13 16 14 16 19
row 24 26 28 29 23 21
row 36 33 39 30 31 35
row 46 48 42 45 43 47
row 59 56 51 52 58 50
row 60 65 68 62 61 67
So I would like to have the first row with numbers from 10 to 19
the second row from 20 to 29 and so on.
I tried like this
<?php drawnNumber(): $number = mt_rand(0,9);
fillArray(): $number = $row . $number; ?>
But that doesn't work, because there are double numbers in the card.
So before that I tried it in a different way,with in_array:
<?php
function fillCard(){
$card = array();
/* fill card with random numbers */
for($i = 0, $min = 10, $max = 19; $i < 6; $i++, $min+=10, $max += 10)
{
for($j = 0; $j < 6; $j++)
{
$number = mt_rand($min,$max) ;
if(!in_array($number, $card){
$card['row' . $i]['column' . $j]['number'] = $number;
$card['row' . $i]['column' . $j]['found'] = 0;
}
}
}
var_dump($card);
return $card;
} ?>
But there are still double random numbers in the card.
I tried a few other thinks in the last two weeks, but I just can't get it to work together.
If one thing succeeds the other thing fails.
I can get the random numbers but not unique random numbers in the card.
I hope someone can help me.
(for extra information: it's a bingo game. So drawnNumber() are the "balls", which get drawn
and stored in the array $drawnNumbers, they also are unique random numbers. fillCard() is the
function that fills the bingo card and checks if $drawNumber is in $card)
I would appreciate some help, if someone can tell me how to get it to work. Maybe in
an algorithm way or else some code?
Thank you in advance.
In general, you draw from some kind of box, right? So do the same, have an array with all available numbers and once you get a random number out of it, remove it, so the next time you search for a number, you will only pick from the remaining ones. Small example:
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4
we pick a random number between 0 and 3 inclusive (0 and the length - 1 of a that is). Let's say we picked index 2, then a will look like:
a[0] = 1
a[1] = 2
a[2] = 4
Now if you draw a number between 0 and 2 (note that you take the length - 1 of a!), you won't re-pick the already chosen number in any way thus giving you unique numbers ALL the time.
P.S. this is a simplified version, but now if you can apply that to yourself and, for your example, create several arrays you will pick from.
The simplest way would be to have an additional flat array to keep track, and loop mt_rand
Here's an example of the meat of things:
$drawn = array();
// Loop around until you have a new number in the desired range
do {
$number = mt_rand($min,$max);
} while(in_array($number, $drawn));
// And save it to the $drawn array
$drawn[] = $rand;
To clarify, the above snippet (without the initialization of $drawn) is meant to replace the line
$number = mt_rand($min,$max) ;
in your code.
define('NB_ROWS', 6);
define('NB_COLS', 6);
$rows = range(10, NB_ROWS * 10, 10);
$bingo = array();
foreach($rows as $rowIndex)
{
$availNumbers = range(0, 9);
$line = array();
for($cellIndex = 0; $cellIndex < NB_COLS; $cellIndex++)
{
// pick a random value among remaining ones for current line
$numIndex = rand(0, count($availNumbers)-1);
list($value) = array_splice($availNumbers, $numIndex, 1);
$line[] = $value + $rowIndex;
}
$bingo[] = $line;
}
print_r($bingo);
Let's say that you have an array of 30 characters and you are looping through them to build a visual grid in HTML. I want to know when it's on the last row of items and apply a CSS rule. For every 8th item, I can use the code below to apply an additional CSS rule:
$cnt=1;
foreach ($characters as $index => $character){
if ($cnt % 8==0) echo "newline";
$cnt++;
}
Since I only have 30 characters, there will be 3 lines with a shorter 4th line (it will only have 6 items). How can I flag every character from 24-30 as belonging to the last row. The total number of characters will always vary.
$rowCount = 8; // the number of items per row
$lastRowStarts = intval(floor(count($characters) / $rowCount)) * $rowCount;
// e.g: floor(30 / 8) * 8 = 3 * 8 = 24 = <index of first item in last row>
$index = 1;
foreach ($characters as $character) {
if ($index >= $lastRowStarts) echo "last line";
$index++;
}
This will work for any size of characters as long as your row length is 8. This assumes $cnt is a variable that keeps a loop counter.
$count = count($charchters)
foreach ($characters as $index => $character){
if ($cnt % 8==0) echo "newline";
if ($cnt < $count && $cnt > ($count - $count % 8)) echo "This is on the last row";
}
You can use array_pop to get the last row after groping them with array_chunk
header("Content-Type: text/plain");
$characters = range(1, 30); // Generate Random Data
$others = array_chunk($characters, 8); //Break Them apart
$last = array_pop($others); //Get last row
foreach ( $others as $characters ) {
echo implode("\t", $characters), PHP_EOL;
}
print_r($last); // Do anything you want with last row
Output
1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
Last Row
Array
(
[0] => 25
[1] => 26
[2] => 27
[3] => 28
[4] => 29
[5] => 30
)
$cnt=1;
$length = strlen($characters);//if a string
//$length = count($characters);//if an array
foreach ($characters as $index => $character){
if ($cnt % 8==0) echo "newline";
if($index > ($length - 8))//or whatever number you want
{
echo 'flagged';//flag here however
}
$cnt++;
}