I have a PHP page with two variables: $nbRank and $nbNumeric. Depending of these two variables, I want to generate an array containing all combinations existing. For example:
If $nbRank = 3 and $nbNumeric = 2 I would have:
0 0 0
0 0 1
0 0 2
0 1 0
0 1 1
0 1 2
0 2 0
0 2 1
0 2 2
1 0 0
1 0 1
1 0 2
1 1 0
1 1 1
1 1 2
1 2 0
1 2 1
1 2 2
2 0 0
2 0 1
2 0 2
2 1 0
2 1 1
2 1 2
2 2 0
2 2 1
2 2 2
So, I create different loop and formulas to get the final result, but it doesn't works. This is what I did :
$result = array();
$nbIntRank = 0;
$nbIntNumeric = 0;
$nbRank = array();
$nbNumeric = array();
$nb_rangs = 3;
$nb_chiffres = 2;
for ($i = 1; $i <= $nb_rangs; $i++){
$nbRank[$i] = 0;
}
$nbIntRank = count($nbRank);
for ($i = 0; $i <= $nb_chiffres; $i++){
$nbNumeric[$i] = $i;
}
$nbIntNumeric = count($nbNumeric);
$algo = ($nb_rangs * ($nb_chiffres + 1)) * ($nb_rangs * ($nb_chiffres + 1));
$nbLine = $algo / ($nb_rangs);
$occ = 0;
for ($i = 0; $i < $nbLine; $i++){
foreach ($nbRank as $nbrItem => $nbrValue){
$result[$i][] = $nbrValue;
$occ++;
}
}
echo '#############<br />';
echo '### DATAS ###<br />';
echo '#############<br /><br />';
echo '- Nb Elements : '.$algo.'<br />';
echo '- Nb Lines : '.$nbLine.'<br />';
echo '- Nb Valuable Occurency : '.$occ.'<br />';
echo '<br /><hr /><br />';
echo '##############<br />';
echo '### PARSER ###<br />';
echo '##############<br /><br />';
echo '<pre>';
var_dump($result);
echo '</pre>';
I managed to create my final array with empty values (81 values, in 27 lines of 3 elements) but it only contains 0.
You indicated you'll be fine with pseudo-code.. Sorry I cannot offer specific correction for your php code [if these answers appear - they might be more educating], but I'd chose a recursive solution for this problem.
In each level of the recursion, try all possibilities, and call the same function to find all combinations of one smaller size.
Pseudo-Code:
findCombinations(range,size,sol,resultList):
if (size ==0): #base clause
resultList.append(copy(sol)) #making a copy of sol and appending it as a solution
return
for each i in (0,range):
sol.append(i)
findCombinations(range,size-1,sol,resultList) #recursive invokation, with smaller size
sol.deleteLast() #clean up environment before next calls
Invoke with findCombinations(3,3,[],resultList) where [] is just empty list, and resultList will hold the list of combination when the algorithm is done. this invokation will get all combinations of size 3 with elemenets 0,1,2.
Complexity note:
The number of possibilities is growing exponentially [O(rangesize)], so if you try to invoke it with 20,20 for instance - it might take some [very long] time, for any solution.
$nbRank = 3;
$nbNumeric = 2;
foreach (range(0, base_convert(str_pad('', $nbRank, $nbNumeric), $nbNumeric+1, 10)) as $i) {
echo str_pad(base_convert($i, 10, $nbNumeric+1), 3, 0, STR_PAD_LEFT) . PHP_EOL;
}
Simple idea: What you want is every number from 0 to X with base $nbNumeric, thus we just convert the maximum number to base 10, iterate over it with the common 10-based operators, and convert it back to base $nbNumeric again.
Probably more readable, but in fact exactly the same
$nbRank = 3;
$nbNumeric = 2;
// Top is "base_convert(222, 3, 10);" and therefore the upper limit
$top = base_convert(str_pad('', $nbRank, $nbNumeric), $nbNumeric+1, 10);
for ($i = 0; $i <= $top; $i++) {
echo str_pad(base_convert($i, 10, $nbNumeric+1), 3, 0, STR_PAD_LEFT) . PHP_EOL;
}
Here's a recursive solution:
$nbRank = 3;
$nbNumeric = 2;
function getCombinations ($length, $min, $max, $aStartingCombinations)
{
if ($length == 1)
{
return range ($min, $max);
}
$final = array ();
foreach (getCombinations ($length - 1, $min, $max, $aStartingCombinations) as $combination)
{
for ($i = $min; $i <= $max; $i++)
{
$final [] = $combination . $i;
}
}
return $final;
}
print_r (getCombinations ($nbRank, 0, $nbNumeric, array ()));
Related
I have a cloumn like token_number in table the values inserted in this row are like
token_number
1
2
3
15
4
5
6
14
7
8
18
10
11
9
etc..
I sort these values
1,2,3,4,5,6,7,8,9,10,11,14,15,18
I want to get the value 11 from this sorted array
ie the highest number with common difference 1
How to get 11 from this array?
Since the array is sorted, you can start from the bottom e loop it backwards:
$arr = // sorted array;
$max = null;
for( $i = count($arr) - 1 ; $i > 0 ; $i++ ){
if($arr[$i] - 1 == $arr[$i-1]){
$max = $arr[$i-1];
break;
}
}
if($max !== null){
echo "founded: " . $max;
}
You can find highest number with command difference as follow.
$arr= array(1,2,3,4,5,6,7,8,9,10,11,14,15,18);
$highestNo = null;
for($i=0 ;$i <= count($arr) - 1 ; $i++ ){
$diff = $arr[$i+1] - $arr[$i]; //check difference of current and next number
if($diff != 1){
$highestNo = $arr[$i];
break;
}
}
echo "Highest number with comman difference is: " . $highestNo;
I want to turn the $i variable value to start counting from 1 if the given value is greater than 10:
here is what i am trying to achieve
<?php
$givenValue = 15; //number of x value
for ($i = 1; $i < $givenValue; $i++) {
if ($givenValue > 10){
$i = 1;
}
echo $i."<br>";
}
?>
This is how i want my result to look like
output: 1
output: 2
output: 3
output: 4
output: 5
output: 6
output: 7
output: 8
output: 9
output: 10
output: 1
output: 2
output: 3
output: 4
output: 5
in for loop body
Any help is welcome
You can use modulo calculation to get the result you want.
I also changed your if from $givenvalue to $i as $givenvalue will "always" be 10+.
$givenValue = 15; //number of x value
for ($i = 1; $i <= $givenValue; $i++) {
if ($i > 10){
Echo $i%10 . "\n";
}else{
echo $i . "\n";
}
}
https://3v4l.org/5afc5
Another option, if that is possible for you, is to start at zero and only use modulo calculation and add one to it to get the same result.
This also means I need to stop the loop at <$givenvalue as your original code shows.
$givenValue = 15; //number of x value
for ($i = 0; $i < $givenValue; $i++) {
Echo $i%10+1 . "\n";
}
https://3v4l.org/r0sgA
A method that uses less looping is to add 10 to the loop on each iteration and create the values using range().
Then add them to the array with array_merge, and output with implode.
$givenValue = 47; //number of x value
$breakpoint = 10;
$arr=[];
For($i = $breakpoint; $i< $givenValue;){
// Add new values from 1-$breakpoint in array
$arr = array_merge($arr, range(1,$breakpoint));
$i +=$breakpoint;
}
// Loop will exit before all values been collected
// Add the rest of the values
$arr = array_merge($arr, range(1,$givenValue-($i-10)));
// Echo the values in array
Echo implode("\n", $arr);
https://3v4l.org/jGsO4
Your code can be written like this:
<?php
$givenValue = 15; //number of x value
for ($i = 1; $i <= $givenValue; $i++)
{
if ($i > 10)
{
$i = 1;
$givenValue-=10;
}
echo "output: $i\n";
}
?>
http://sandbox.onlinephpfunctions.com/code/ed34d8dcd12a9a5a866b73338ad1209f55298519
You are resenting the counter, I would expect the behaviour you have. To do what you want add another counter to the mix
$j=1;
$givenValue = 15; //number of x value
for ($i = 1; $i <= $givenValue; $i++) {
if ($j > 10){
$j = 1;
}
echo $j."\n";
++$j;
}
You also had several missing ;
Output:
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
If you want to end on 5 you have to do 16 as the $givenValue or change it to <= less than or equal
See it here live
See what I have now, the $i variable counts to the $givenValue then the $j variable counts along side it, but with a range of 1-10 ( resets to 1 after 10 )
in an N numbers of array a number is a X-number if it is divisible by atleast one other number in the array. Program to find how many such numbers exists in an given array
example 1 : in array [1,2,3] , number of x-numbers is 2 ( 2 and 3 as they are divisible by number 1 )
example 2 : in array [2,3,5,8] , number of x-numbers is 1 ( 8 is divisible by 2 )
example 3 : in array [2,3,6,12] , number of x-numbers is 2 ( 6 is divisible by 2 and 3 , 12 is divisible by 2 and 3 and 6 )
I am using the below code, but i want to optimize it in a way if the array size increase the performance should not hamper :
$arr = array(2,3,6,12);
$count = 0;
function check_special_num($tnum, $tarr){
sort($tarr);
for($i=0;$i<sizeof($tarr);$i++){
if( $tnum % $tarr[$i] == 0 ){
return true;
}
}
return false;
}
for($i=0;$i<sizeof($arr);$i++){
$temp = $arr;
$num = $arr[$i];
array_splice($temp, $i, 1);
if( check_special_num( $num, $temp ) ){
$count += 1;
}
}
echo $count;
Coding language is PHP
It might be faster this way:
$arr = array(2,3,6,12);
function x_numbers_count($arr) {
$count = 0;
sort($arr);
foreach ($arr as $i => $number) {
for ($j = 0; $j < $i; $j++) {
if ($number % $arr[$j] == 0) {
$count++;
break;
}
}
}
return $count;
}
echo x_numbers_count($arr);
The main differences, which can be expected to improve performance:
the array is sorted only once, before beginning to work (this could also improve your own method, without changing anything else)
the search loop stops as soon as it is to reach the current investigated number
less variables are used
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 need this output..
1 3 5
2 4 6
I want to use array function like array(1,2,3,4,5,6). If I edit this array like array(1,2,3), it means the output need to show like
1 2 3
The concept is maximum 3 column only. If we give array(1,2,3,4,5), it means the output should be
1 3 5
2 4
Suppose we will give array(1,2,3,4,5,6,7,8,9), then it means output is
1 4 7
2 5 8
3 6 9
that is, maximum 3 column only. Depends upon the the given input, the rows will be created with 3 columns.
Is this possible with PHP? I am doing small Research & Development in array functions. I think this is possible. Will you help me?
For more info:
* input: array(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
* output:
1 6 11
2 7 12
3 8 13
4 9 14
5 10
You can do a loop that will automatically insert a new line on each three elements:
$values = array(1,1,1,1,1);
foreach($values as $i => $value) {
printf('%-4d', $value);
if($i % 3 === 2) echo "\n";
}
EDIT: Since you added more information, here's what you want:
$values = array(1,2,3,4,5);
for($line = 0; $line < 2; $line++) {
if($line !== 0) echo "\n";
for($i = $line; $i < count($values); $i+=2) {
printf('%-4d', $values[$i]);
}
}
And if you want to bundle all that in a function:
function print_values_table($array, $lines = 3, $format = "%-4d") {
$values = array_values($array);
$count = count($values);
for($line = 0; $line < $lines; $line++) {
if($line !== 0) echo "\n";
for($i = $line; $i < $count; $i += $lines) {
printf($format, $values[$i]);
}
}
}
EDIT 2: Here is a modified version which will limit the numbers of columns to 3.
function print_values_table($array, $maxCols = 3, $format = "%-4d") {
$values = array_values($array);
$count = count($values);
$lines = ceil($count / $maxCols);
for($line = 0; $line < $lines; $line++) {
if($line !== 0) echo "\n";
for($i = $line; $i < $count; $i += $lines) {
printf($format, $values[$i]);
}
}
}
So, the following:
$values = range(1,25);
print_array_table($values);
Will output this:
1 10 19
2 11 20
3 12 21
4 13 22
5 14 23
6 15 24
7 16 25
8 17
9 18
One solution is to cut the array into chunks, representing the columns, and then print the values in row order:
$cols = array_chunk($arr, ceil(count($arr)/3));
for ($i=0, $n=count($cols[0]); $i<$n; $i++) {
echo $cols[0][$i];
if (isset($cols[1][$i])) echo $cols[1][$i];
if (isset($cols[2][$i])) echo $cols[2][$i];
}
If you don’t want to split your array, you can also do it directly:
for ($c=0, $n=count($arr), $m=ceil($n/3); $c<$m; $c++) {
echo $arr[$c];
for ($r=$m; $r<$n; $r+=$m) {
echo $arr[$c+$r];
}
}
$a = array(1,2,3,4,5);
"{$a[0]} {$a[1]} {$a[2]}\n{$a[3]} {$a[4]}";
or
$a = array(1,2,3,4,5);
"{$a[0]} {$a[1]} {$a[2]}".PHP_EOL."{$a[3]} {$a[4]}";
or
$a = array(1,2,3,4,5);
$second_row_start = 3; // change to vary length of rows
foreach( $a as $index => $value) {
if($index == $second_row_start) echo PHP_EOL;
echo "$value ";
}
or, perhaps if you want a longer array split into columns of 3?
$a = array(1,2,3,4,5,6,7,8,9,10,11,12,13);
$row_length = 3; // change to vary length of rows
foreach( $a as $index => $value) {
if($index%$row_length == 0) echo PHP_EOL;
echo "$value ";
}
which gives
1 2 3
4 5 6
7 8 9
10 11 12
13
one solution is :
your array has N elements, and you want 3 columns, so you can get the value of each cell with $myarray[ column_index + (N/3) + line_index ] (with one or two loops for columns and lines, at least for lines)
I hope this will help you
Bye
Here's something I whipped up. I'm pretty sure this could be more easily accomplished if you were using HTML lists, I've assumed you can't use them.
$arr = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14, 15, 16);
$max = count($arr);
$cols = 3;
$block = ceil($max / $cols);
for ($i = 0; $i < $block ; $i++) {
echo $arr[$i] . ' ';
for ($j = 1; $j < $cols; $j++) {
$nexKey = $i + $block * $j;
if (!isset($arr[$nexKey])) break;
echo $arr[$nexKey] . ' ';
}
echo '<br>';
}
NOTE : You can easily refactor the code inside the loop that uses $nexkey variable by making it into a loop itself so that it works for any number of columns. I've hardcoded it.
Uses loops now.