Every possible combination for grade of courses in PHP - php

I need to make a combination of all course input by the user such as the user add 5 courses it will be as this template:
Course 1
Course 2
Course 3
Course 4
Course 5
After that, I need to create a combination for all course with array of grade:
array('A+', 'A', 'B+', 'B', 'C+', 'C','D+','D','F')
Actually, I found what I need in this topic: Create every possible combination in PHP but there's something I don't understand how I can do.
Until now this code after edit:
$dict = [
'1' => ['A+', 'A', 'B+', 'B', 'C+', 'C','D+','D','F'],
'2' => ['Course 1', 'Course 2', 'Course 3', 'Course 4', 'Course 5'],
];
$str = '2 : 1';
class SentenceTemplate implements IteratorAggregate
{
private $template;
private $thesaurus;
public function __construct($str, $dict)
{
$this->thesaurus = [];
$this->template = preg_replace_callback('/\w+/', function($matches) use ($dict) {
$word = $matches[0];
if (isset($dict[$word])) {
$this->thesaurus[] = $dict[$word];
return '%s';
} else {
return $word;
}
}, $str);
}
public function getIterator()
{
return new ArrayIterator(array_map(function($args) {
return vsprintf($this->template, $args);
}, $this->combinations($this->thesaurus)));
}
private function combinations($arrays, $i = 0) {
if (!isset($arrays[$i])) {
return array();
}
if ($i == count($arrays) - 1) {
return $arrays[$i];
}
// get combinations from subsequent arrays
$tmp = $this->combinations($arrays, $i + 1);
$result = array();
// concat each array from tmp with each element from $arrays[$i]
foreach ($arrays[$i] as $v) {
foreach ($tmp as $t) {
$result[] = is_array($t) ? array_merge(array($v), $t) : array($v, $t);
}
}
return $result;
}
}
$sentences = new SentenceTemplate(1, $dict);
$i = 1;
foreach ($sentences as $sentence) {
echo "COMBINATION $i : \n";
$sentences2 = new SentenceTemplate(2, $dict);
foreach ($sentences2 as $sentence2) {
echo "$sentence2 : "."$sentence\n";
}
echo "----------\n";
$i++;
}
Output
COMBINATION 1 :
Course 1 : A+
Course 2 : A+
Course 3 : A+
Course 4 : A+
Course 5 : A+
----------
COMBINATION 2 :
Course 1 : A
Course 2 : A
Course 3 : A
Course 4 : A
Course 5 : A
----------
COMBINATION 3 :
Course 1 : B+
Course 2 : B+
Course 3 : B+
Course 4 : B+
Course 5 : B+
----------
COMBINATION 4 :
Course 1 : B
Course 2 : B
Course 3 : B
Course 4 : B
Course 5 : B
----------
COMBINATION 5 :
Course 1 : C+
Course 2 : C+
Course 3 : C+
Course 4 : C+
Course 5 : C+
----------
COMBINATION 6 :
Course 1 : C
Course 2 : C
Course 3 : C
Course 4 : C
Course 5 : C
----------
COMBINATION 7 :
Course 1 : D+
Course 2 : D+
Course 3 : D+
Course 4 : D+
Course 5 : D+
----------
COMBINATION 8 :
Course 1 : D
Course 2 : D
Course 3 : D
Course 4 : D
Course 5 : D
----------
COMBINATION 9 :
Course 1 : F
Course 2 : F
Course 3 : F
Course 4 : F
Course 5 : F
----------
And now how I can build more combinations such as:
COMBINATION 10 :
Course 1 : B+
Course 2 : A+
Course 3 : A+
Course 4 : A+
Course 5 : A+
COMBINATION 11 :
Course 1 : B
Course 2 : A+
Course 3 : A+
Course 4 : A+
Course 5 : A+
COMBINATION 12 :
Course 1 : C+
Course 2 : A+
Course 3 : A+
Course 4 : A+
Course 5 : A+
COMBINATION 13 :
Course 1 : C
Course 2 : A+
Course 3 : A+
Course 4 : A+
Course 5 : A+
COMBINATION 14 :
Course 1 : D+
Course 2 : A+
Course 3 : A+
Course 4 : A+
Course 5 : A+
COMBINATION 15 :
Course 1 : D
Course 2 : A+
Course 3 : A+
Course 4 : A+
Course 5 : A+
COMBINATION 16 :
Course 1 : F
Course 2 : A+
Course 3 : A+
Course 4 : A+
Course 5 : A+
.......
The procedure is for every course has a different grade with other courses and other courses has the same procedure, anyone has an idea to build this?

This code may help. It is a PHP program to print all possible strings of length k.
<?php
// PHP program to print all possible strings of length k
// Driver method to test below methods
function main() {
$set = ['A+', 'A', 'B+', 'B', 'C+', 'C','D+','D','F'];
$k = 5;
$n = sizeof($set);
printAllKLengthRec($set, "", $n, $k);
}
// The main recursive method to print all possible strings of length k
function printAllKLengthRec($set, $prefix, $n, $k) {
// Base case: k is 0, print prefix
if ($k == 0) {
echo $prefix."\n";
return;
}
// One by one add all characters from set and recursively
// call for k equals to k-1
for ($i = 0; $i < $n; ++$i) {
// Next character of input added
$newPrefix = $prefix . $set[$i];
// k is decreased, because we have added a new character
printAllKLengthRec($set, $newPrefix, $n, $k - 1);
}
}
main();
?>
You just need to modify the printing part.
The code bellow may fulfill your purpose.
<?php
// PHP program to print all possible strings of length k
// Driver method to test below methods
function main() {
$set = ['A+', 'A', 'B+', 'B', 'C+', 'C','D+','D','F'];
$k = 5;
$n = sizeof($set);
printAllKLengthRec($set, "", $n, $k);
}
// The main recursive method to print all possible strings of length k
function printAllKLengthRec($set, $prefix, $n, $k) {
// Base case: k is 0, print prefix
if ($k == 0) {
$c = 1;
for($p=0; $p<strlen($prefix); $p++) {
echo "Course $c: ". $prefix[$p];
if(($p+1) < strlen($prefix) && ($prefix[$p+1] == '+' || $prefix[$p+1] == '-')) {
echo $prefix[$p+1];
$p++;
}
echo "\n";
$c++;
}
return;
}
// One by one add all characters from set and recursively
// call for k equals to k-1
for ($i = 0; $i < $n; ++$i) {
// Next character of input added
$newPrefix = $prefix . $set[$i];
// k is decreased, because we have added a new character
printAllKLengthRec($set, $newPrefix, $n, $k - 1);
}
}
main();
?>

Related

Integer partitioning in PHP

This feels like a very simple problem, but I can't manage to make it elegant and 'feels right'. Here's the problem:
Giving a number T, print out all possible ways to get to T.
For example :
T = 5
1 + 1 + 1 +1 + 1
2 + 1 + 1 + 1
3 + 1 + 1
2 + 2 + 1
4 + 1
3 + 2
Note that, 3 + 2 is equal than 2 + 3, so you donĀ“t have to print both cases.
I have to do it in PHP, hope anyone can help :).
One easy way to solve this problem is to solve it recursively. Following is a sample code,
<?php
function recursion($left, $last, $ar) {
if($left == 0) {
foreach ($ar as $n) {
printf("%d ", $n);
}
print "<br>";
return;
}
for($n = $last; $n <= $left; $n++) {
$b = $ar;
array_push($b, $n);
recursion($left - $n, $n, $b);
}
}
recursion(5, 1, []);
Output:
1 1 1 1 1
1 1 1 2
1 1 3
1 2 2
1 4
2 3
5
Note that, this bruteforce recursive solution won't work for bigger T. There exist some dynamic programming solutions which can solve this problm for numbers in a larger range.

While randomly and not repeating twice

Here is my code:
$answer = explode(" ", $row2['answer']);
foreach($tags as $i =>$key) {
$i >0;
echo $i.' '.$key .'</br>';
}
the output is
0 a
1 b
2 c
3 d
4 e
5 f
I'd like that the output be random, but doesn't repeat twice.
For example:
e 4
a 0
c 2
f 5
d 3
b 1
Any idea please ?
Thank you.
The simplest way I can think of to achieve this would be to use the shuffle method on an array collection. This however does not guarantee non-sequentialness:
$range = range(1,5);
shuffle($range);
foreach($range as $int){
echo $int;
}

How to check total occurrence of a character in string

I want to find out total occurrence of particular character in string.
my code is:
$str = 'aabbbcccccaa';
for ($i=0;$i<strlen($str);$i++){
$len = 0;
for ($j=$i;$j<=strlen($str);$j++){
if($str[$i] == $str[$j]){
$len++;
}
}
echo "\n".$str[$i].' len is '.$len;
}
my output is like:
a len is 4
a len is 3
b len is 3
b len is 2
b len is 1
c len is 5
c len is 4
c len is 3
c len is 2
c len is 1
a len is 2
a len is 1
but I want something like:
a len is 4
b len is 3
c len is 5 only
How can I achieve this?
RTM
<?php
$data = "Two Ts and one F.";
foreach (count_chars($data, 1) as $i => $val) {
echo "There were $val instance(s) of \"" , chr($i) , "\" in the string.\n";
}
?>
You should use substr_count(). It's right here in the manual:
http://php.net/manual/en/function.substr-count.php
or perhaps count_chars() would be even better for a generic solution:
http://php.net/manual/en/function.count-chars.php
Always check the manuals before creating something yourself.. there just might be a function there that does exactly what you want..
$str = 'aabbbcccccaa';
foreach (count_chars($str, 1) as $i => $val) {
echo chr($i), " len is $val " , "<br>";
}
Hello Simply Implement the bellow way !
Our Custom Function :
function count_chars_unicode($str, $x = false) {
$tmp = preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY);
foreach ($tmp as $c) {
$chr[$c] = isset($chr[$c]) ? $chr[$c] + 1 : 1;
}
return is_bool($x)
? ($x ? $chr : count($chr))
: $chr[$x];
}
Usage :
print_r(count_chars_unicode('aabbbcccccaa', true));
O/P
Array ( [a] => 4 [b] => 3 [c] => 5 )
print_r(count_chars_unicode('aabbbcccccaa', 'a')); // frequency of "a"
O/P : 4
print_r(count_chars_unicode('aabbbcccccaa')); // count of uniq chars
O/P : 3

Finding out combinations of x amount of integers to sum a given number

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

How to display individual options by knowing the full option type

I have a sample database below:
Question Table:
QuestionId (PK auto) QuestionNo OptionId (FK)
11 1 1
12 2 3
13 3 26
Option Table
OptionId OptionType
1 A-C
2 A-D
3 A-E
4 A-F
...
25 True or False
26 Yes or No
Now below I have displayed each question number and their recognised option typea:
foreach ($arrQuestionId as $key=>$question) {
?>
<p><?php echo htmlspecialchars($arrQuestionNo[$key]) . ": " . htmlspecialchars($arrOptionType[$key]); ?></p>
<?php
}
?>
So the output looks like this:
1: A-C
2: A-E
3: Yes or No
But what I want to do is also display each indivdual option now by determining the full option type. For example if the option type is A-C, then it should display A B C, if option type is A-E display A B C D E, if option type is Yes or No, then display Yes No.
Each indivdual option should be displayed as a checkbox. So if you have A B C, then it should be:
A (checkbox)
B (checkbox)
C (checkbox)
My question is how can this be achieved?
One way is to use a combination of explode and increment operator on characters. For example:
<?php
$questions = array(
array(1, "A-E"),
array(2, "Yes or No"),
array(3, "A-C"),
array(4, "True or False")
);
foreach ($questions as $question) {
echo $question[0] , ': ' , ExpandOptionType($question[1]), '<br/>';
}
function ExpandOptionType($option) {
$options = explode('-', $option);
if(count($options) > 1) {
$start = array_shift($options);
$end = array_shift($options);
do {
$options[] = $start;
}while(++$start <= $end);
}
else{
$options = explode(' or ', $option);
}
return implode(" ", $options);
}
?>
Output:
1: A B C D E
2: Yes No
3: A B C
4: True False

Categories