I need a solution how to find all possible combinations of a schedule. There are courses on given dates that can vary by length. There is a given number of weeks. I need to find a solution to all possible combinations including all courses, with no overlapping.
$courses = array ("A", "B", "C", "D");
$duration = array (2, 3, 1, 2); // duration of $courses (in weeks)
$start_dates = array (
$courses[0] => array (1, 3, 5),
$courses[1] => array (1, 2, 5, 6),
$courses[2] => array (3, 4, 5, 9),
$courses[3] => array (1, 4, 8));
I would like to get all the possible combinations, e.g. this:
Week | Course
1 | A
2 | A
3 | C
4 | D
5 | D
6 | B
7 | B
8 | B
9 | -
10 | -
Second combination would be e.g. this:
Week | Course
1 | A
2 | A
3 | -
4 | C
5 | B
6 | B
7 | B
8 | D
9 | D
10 | -
The preferred output would be an array with week => course, like this:
$combinations = array (
0 => array (
1 => $courses[0],
2 => $courses[0],
3 => $courses[2],
4 => $courses[3],
...
),
1 => array (
1 => $courses[0],
2 => $courses[0],
4 => $courses[2],
5 => $courses[1],
6 => $courses[1],
7 => $courses[1],
...
)
);
I am really stuck with this problem. Thanks a lot for your help.
Related
db_table => commitment
ref_no
comm_date
1
2022-10-05
2
2022-10-05
3
2022-10-06
4
2022-10-07
5
2022-10-07
6
2022-10-08
db_table => collection
ref_no
amount
trnx_date
1
500
2022-10-05
2
100
2022-10-05
1
700
2022-10-06
3
400
2022-10-07
3
600
2022-10-08
5
800
2022-10-08
1
700
2022-10-08
I want to achieve something like this in datatable:
ref_no
comm_date
collection summary
1
2022-10-05
500 (2022-10-05) + 700 (2022-10-06) + 700 (2022-10-08) = 1900
2
2022-10-05
100 (2022-10-05) = 100
3
2022-10-06
400 (2022-10-07) + 600 (2022-10-08) = 1000
4
2022-10-07
0
5
2022-10-07
800 (2022-10-08) = 800
6
2022-10-08
0
How can I achieve this with php and mysql and show it to datatable. Thanks in advance!
What I have tried in sql in codeigniter model:
SELECT c.*, t.*
FROM commitment c
LEFT JOIN collection t ON c.ref_no = t.ref_no
WHERE c.ref_no IN (SELECT ref_no FROM collection)
GROUP BY c.ref_no
In controller:
public function collection_statement_list() {
// Datatables Variables
$draw = intval($this->input->get("draw"));
$start = intval($this->input->get("start"));
$length = intval($this->input->get("length"));
$fetch = $this->Project_model->get_collection_statement();
$data = array();
foreach($fetch->result() as $r) {
$ref_no = $r->ref_no;
$comm_date = $this->Project_model->set_date_format($r->comm_date);
$coll_date = $this->Project_model->set_date_format($r->trnx_date);
$coll_summary = $r->amount.'<span class="text-primary"><small>('.$coll_date.')</small></span>';
$data[] = array(
$ref_no,
$comm_date,
$coll_summary,
);
}
$output = array(
"draw" => $draw,
"recordsTotal" => $fetch->num_rows(),
"recordsFiltered" => $fetch->num_rows(),
"data" => $data
);
echo json_encode($output);
exit();
}
And the output in datatable is:
| ref_no | comm_date | collection summary |
| ------ | ---------- | ------------------ |
| 1 | 2022-10-05 | 500 (2022-10-05) |
| 2 | 2022-10-05 | 100 (2022-10-05) |
| 3 | 2022-10-06 | 400 (2022-10-07) |
| 4 | 2022-10-07 | 0 |
| 5 | 2022-10-07 | 800 (2022-10-08) |
| 6 | 2022-10-08 | 0 |
And so in SQL only this query corresponds to your solution with group_concat...? I'm trying to answer to help those who would be looking for the solution in SQL only.
select COM.ref_no,
if(COL.ref_no is not null,group_concat(COL.trnx_date,' (',COL.amount,')' separator '+'),'') as 'collection summary details',
if(COL.ref_no is not null,sum(COL.amount),0) as 'collection summary'
from commitment as COM
left join collection as COL on COM.ref_no=COL.ref_no
group by COM.ref_no
I think such way. Imagine you have a table about amounts. It is will be solution by sql:
Select ref_no, comm_date, sub(summary) as collect_summary from amount;
However you may use alternative way to be group with php such:
<?php
$amount = [
['ref_no'=> 1, 'amount'=>500 , 'date'=>'2022-10-05'],
['ref_no'=> 2, 'amount'=>100 , 'date'=>'2022-10-05'],
['ref_no'=> 1, 'amount'=>700 , 'date'=>'2022-10-05'],
['ref_no'=> 3, 'amount'=>400 , 'date'=>'2022-10-05'],
['ref_no'=> 3, 'amount'=>600 , 'date'=>'2022-10-05'],
['ref_no'=> 5, 'amount'=>800 , 'date'=>'2022-10-05'],
['ref_no'=> 1, 'amount'=>700 , 'date'=>'2022-10-05'],
];
$result = [];
foreach($amount as $item) {
$ref = $item['ref_no'];
if(isset($result[$ref])) {
$result[$ref]['collect_amount'] = $result[$ref]['collect_amount'] + $item['amount'];
}else{
$result[$ref] = [
'ref_no' => $ref,
'date' => $item['date'],
'collect_amount' =>$item['amount']
];
}
}
echo '<pre>';
print_r($result);
Database:
ID | CID | HOURS
1 | 201 | 8, 8, 8, 8
2 | 201 | 2, 4, 7, 5
3 | 201 | 4, 3, 7, 1
How can I extract the values in the HOURS column and add the values to produce the results of on a HTML table:
TOTAL HOURS: 14 | 15 | 22 | 14
I am assuming that the values in Hours column need to be inserted into an array? So, I did a while loop and exploded the results and got the following:
while($row = sqlsrv_fetch_object($result)) {
$hours = explode(', ', $hours)
}
I do a print_r($hours, 1) and get the following:
Array
(
[0] => 8
[1] => 8
[2] => 8
[3] => 8
Array
(
[0] => 2
[1] => 4
[2] => 7
[3] => 5
)
Array
(
[0] => 4
[1] => 3
[2] => 7
[3] => 1
)
How do I loop this to do the calculation?
Setting aside the comma-delimeted data being an anti-pattern, it's possible to return your aggregated values in a single query without needing to loop over anything by using string_split, the basics of which are:
select
Sum(case col when 1 then v end),
Sum(case col when 2 then v end),
Sum(case col when 3 then v end),
Sum(case col when 4 then v end)
from (
select v, row_number() over(partition by id order by id) col
from t
cross apply(
select Cast(value as int)v from String_Split(t.hours,',')
)v
)v
demo Fiddle
I'm building a VERY simple threaded message system, primarily for users of my site to communicate bugs and problems to me and each other as I expand my site's functionality. But, I'm having no luck creating a properly nested list of each thread.
I have two tables: Threads and Posts, which I've simplified for presentation here.
The Threads table is substantially like so, ordered by most recently modified thread:
+----+-----------------+---------------------+
| id | thName | thModified |
+----+-----------------+---------------------+
| 5 | Thread Number 5 | 2019-06-29 20:54:59 |
+----+-----------------+---------------------+
| 4 | Thread Number 4 | 2019-06-29 20:45:22 |
+----+-----------------+---------------------+
| 3 | Thread Number 3 | 2019-06-29 20:44:20 |
+----+-----------------+---------------------+
| 2 | Thread Number 2 | 2019-06-29 20:43:00 |
+----+-----------------+---------------------+
| 1 | Thread Number 1 | 2019-06-29 20:39:25 |
+----+-----------------+---------------------+
The Posts table is substantially like so:
+----+------+-----+----------------------------------+
| Id | thID | pID | postMessage |
+----+------+-----+----------------------------------+
| 1 | 1 | 0 | First message of thread number 1 |
+----+------+-----+----------------------------------+
| 2 | 2 | 0 | First message of thread number 2 |
+----+------+-----+----------------------------------+
| 3 | 3 | 0 | First message of thread number 3 |
+----+------+-----+----------------------------------+
| 4 | 4 | 0 | First message of thread number 4 |
+----+------+-----+----------------------------------+
| 5 | 5 | 0 | First message of thread number 5 |
+----+------+-----+----------------------------------+
| 6 | 5 | 5 | First response to post 5 |
+----+------+-----+----------------------------------+
| 7 | 5 | 5 | Second response to post 5 |
+----+------+-----+----------------------------------+
| 8 | 5 | 6 | First response to post 6 |
+----+------+-----+----------------------------------+
| 9 | 1 | 1 | First response to post 1 |
+----+------+-----+----------------------------------+
Where each post is related to a thread on the other table, and parent/child relationships are determined in this table by parsing the parentID column. Posts with "0" as a parent are root nodes.
My basic plan of attack is this:
Get all threads, sorted by most recent
For each thread, get ALL posts by matching thread_ids, sorted by parent_id
For each thread, somehow (recursively?) iterate thru this list of posts and create a PHP ordered list, properly indented showing the relationship between parents and children.
Sadly, it's the last step that has brought me to an utter standstill for the past 3 days. Using "Thread 5" as an example, after step 2 I have an array that looks like this:
[0] => Array
(
[post_id] => 5
[thread_id] => 5
[parent_id] => 0
[user_id] => 9
[post_message] => First message of thread number 5
[post_created] => 2019-06-29 20:54:59
[thread_title] => Thread Number 5
)
[1] => Array
(
[post_id] => 6
[thread_id] => 5
[parent_id] => 5
[user_id] => 9
[post_message] => First response to post 5
[post_created] => 2019-06-29 21:39:00
[thread_title] => Thread Number 5
)
[2] => Array
(
[post_id] => 7
[thread_id] => 5
[parent_id] => 5
[user_id] => 9
[post_message] => Second response to post 5
[post_created] => 2019-06-29 21:52:00
[thread_title] => Thread Number 5
)
[3] => Array
(
[post_id] => 8
[thread_id] => 5
[parent_id] => 6
[user_id] => 0
[post_message] => First response to post 6
[post_created] => 2019-06-29 21:55:00
[thread_title] => Thread Number 5
)
From that array, I'd like to generate a nested list that looks something like:
Thread Number 5 - First message of thread number 5
Thread Number 5 - Second response to post 5
Thread Number 5 - First response to post 5
Thread Number 5 - First response to post 6
Notice that responses are sorted by post date (most recent first), and of course for subsequent threads I'd like the indentation to go back to the zero location again.
Added to clarify intent: in production each post would be a link that
opens to display the full text of the message. Responses would be the
same "thread name" with user and date appended. So, for example, the
tread might read "Found bug during login" and my response (1st child)
would read: "Found bug during login - Chris Conlee 19/07/01 09:10" I
realized the example above seems weird without context.
I honestly don't have any code that's working well enough to post it here. At one point I had a recursive routine which only traversed the left-most leg, and then skipped the second response to post 5.
At another point I had a routine which displayed all the nodes in duplicate and triplicate, and the indentation never worked properly.
I apologize profusely, as it seems like it should be a VERY simple exercise, but I just have worked myself into knots trying to get my head around the recursive nature of it, coupled with multiple threads, etc. If anybody can throw me a lifeline it would be HUGELY appreciated.
Well, I finally slowed down and stepped thru the iteration element by element and figured it out.
Feeding an array of posts, relative to a given thread, such as this:
[0] => Array
(
[post_id] => 5
[thread_id] => 5
[parent_id] => 0
[user_id] => 9
[post_message] => First message of thread number 5
[post_created] => 2019-06-29 20:54:59
[thread_title] => Thread Number 5
)
[1] => Array
(
[post_id] => 6
[thread_id] => 5
[parent_id] => 5
[user_id] => 9
[post_message] => First response to post 5
[post_created] => 2019-06-29 21:39:00
[thread_title] => Thread Number 5
)
[2] => Array
(
[post_id] => 7
[thread_id] => 5
[parent_id] => 5
[user_id] => 9
[post_message] => Second response to post 5
[post_created] => 2019-06-29 21:52:00
[thread_title] => Thread Number 5
)
[3] => Array
(
[post_id] => 8
[thread_id] => 5
[parent_id] => 6
[user_id] => 0
[post_message] => First response to post 6
[post_created] => 2019-06-29 21:55:00
[thread_title] => Thread Number 5
)
Into the following method:
public function buildForum($postsToThread, &$forum, $parent_id = 0) {
foreach ($postsToThread as $post) {
$time = strtotime($post['post_created']);
$tmpCurrentAuthorName = $this->getPostAuthor($post['user_id']);
$tmpCurrentThreadTitle = $post['thread_title'];
$tmpCurrentPostDate = date("M d, Y g:i A", $time);
if ($post['parent_id'] == $parent_id) {
$forum .= "<ol><li><a href='/freetools/forumViewPost/" .$post['post_id'] . "'>" . $tmpCurrentThreadTitle .= " by " . $tmpCurrentAuthorName . "</a> on " . $tmpCurrentPostDate . "</li>";
$parent_id = $post['post_id'];
$this->buildForum($postsToThread, $forum, $parent_id);
$parent_id = $post['parent_id'];
$forum .= "</ol>";
}
}
}
Recursively traverses the tree and returns a result similar to:
(source: post-tools.com)
I have a array which always the number of its keys divided by 4 is integer (in oder words, mod is 0. for example in below example: [12 , 4] {div = 3 | mod = 0}).
My array is something like this:
$arr = Array
(
[0] => 'zero',
[1] => 'one',
[2] => 'two',
[3] => 'three',
[4] => 'four',
[5] => 'five',
[6] => 'six',
[7] => 'seven',
[8] => 'eight',
[9] => 'nine',
[10] => 'ten',
[11] => 'eleven'
);
Now I have a table with 4 column and I want to put all keys of my array into my table. In fact I want to insert each 4 keys of the array in 1 row of table. something like this:
// mytable
+---------+---------+---------+---------+
| col1 | col2 | col3 | col4 |
|---------------------------------------|
| zero | one | two | three |
| four | five | six | seven |
| eight | nine | ten | eleven |
+---------+---------+---------+---------+
I tried before asking and I concluded that I should use nested for(){}. Unfortunately, in reality my array has 1000 keys, and for this reason I can't do it manually. I know only the second for(){}:
for($i; I dont know the condition; $i++){
for ($j=0;$j<=3;$j++){ // selects 4 keys
$arr[$j];
}
INSERT INTO mytable VALUES ($arr[0],$arr[1],$arr[2],$arr[3]); // mysql codes
}
I know my codes are wrong, And please if you can help me. thanks
Actually you don't need a nested for. One is enough:
for ($j=0; $j<=count($array); $j+= ){ // selects 4 keys
INSERT INTO mytable VALUES ($arr[$j],$arr[$j+1],$arr[$j+2],$arr[$j+3]); // mysql codes
}
$j += 4; is the same as $j = $j + 4; it increases counter by 4.
Hope it helped :)
I want to create a 2 dimensional array, which the second array has 2 attributes. Is it possible in php? Becuase I know it's possible in Pascal
example
| Doc | Term |
| 0 | 0 => 'Term1' |
| | 1 => 5 |
----------------------------
| 1 | 0 => 'Term'2' |
| | 1 => 2 |
My question is, How to create this 2-dimensional array and how to access each value?
Thank you
This is simple array nesting:
$a = array(array('Term1', 5), array('Term2', 2));
$a[1][1] === 2;
This is an extremely basic question. Consider consulting a php book or tutorial.
Yes, you just make the value of the item in the array, another array, you can do this as deep as you like. e.g.,
Creating the array
$doc = array(
array(
'Term1',
5
),
array(
'Term 2',
2
)
)
Since no ID is set, the id's are automatically generated, starting at 0. You can set the ID if you want like this:
$doc = array(
0 => array(
3 => 'Term1',
9 => 5
),
1 => array(
3 => 'Term 2',
10 => 2
)
)
Retrieving data from the array
$term1 = $doc[0][0];
echo $term1; // outputs 'Term 1'