How to split a list to obtain the power set of its elements? - algorithm

I have a list and I want to split it into sub lists with +/- 1 items.
Example
I have a list with 17 items in it. What I want is to split it into 4 sub lists like these
1.List = 5 elements
2.List = 4 elements
3.List = 4 elements
4.List = 4 elements
How can I do that? What algorithm I should use here?

Use integer division to get the items in each group and then use modular division to get the number of the first n groups that will have +1 item. For example:
17 items into 4 groups:
17 / 4 = 4 - So there will be 4 groups with 4 elements.
17 % 4 = 1 - So the first 1 groups will have an additional 1 element.
Another example:
18 / 4 = 4 - So there will be 4 groups with 4 elements.
18 % 4 = 2 - So the first 2 groups will have an additional 1 element.

What you want is the Power Set of your original list. The more generic approach for retrieving the power set and the respective properties are given at the Power Set page at Wikipedia

Related

How to extract vectors from a given condition matrix in Octave

I'm trying to extract a matrix with two columns. The first column is the data that I want to group into a vector, while the second column is information about the group.
A =
1 1
2 1
7 2
9 2
7 3
10 3
13 3
1 4
5 4
17 4
1 5
6 5
the result that i seek are
A1 =
1
2
A2 =
7
9
A3 =
7
10
13
A4=
1
5
17
A5 =
1
6
as an illustration, I used the eval function but it didn't give the results I wanted
Assuming that you don't actually need individually named separated variables, the following will put the values into separate cells of a cell array, each of which can be an arbitrary size and which can be then retrieved using cell index syntax. It makes used of logical indexing so that each iteration of the for loop assigns to that cell in B just the values from the first column of A that have the correct number in the second column of A.
num_cells = max (A(:,2));
B = cell (num_cells,1);
for idx = 1:max(A(:,2))
B(idx) = A((A(:,2)==idx),1);
end
B =
{
[1,1] =
1
2
[2,1] =
7
9
[3,1] =
7
10
13
[4,1] =
1
5
17
[5,1] =
1
6
}
Cell arrays are accessed a bit differently than normal numeric arrays. Array indexing (with ()) will return another cell, e.g.:
>> B(1)
ans =
{
[1,1] =
1
2
}
To get the contents of the cell so that you can work with them like any other variable, index them using {}.
>> B{1}
ans =
1
2
How it works:
Use max(A(:,2)) to find out how many array elements are going to be needed. A(:,2) uses subscript notation to indicate every value of A in column 2.
Create an empty cell array B with the right number of cells to contain the separated parts of A. This isn't strictly necessary, but with large amounts of data, things can slow down a lot if you keep adding on to the end of an array. Pre-allocating is usually better.
For each iteration of the for loop, it determines which elements in the 2nd column of A have the value matching the value of idx. This returns a logical array. For example, for the third time through the for loop, idx = 3, and:
>> A_index3 = A(:,2)==3
A_index3 =
0
0
0
0
1
1
1
0
0
0
0
0
That is a logical array of trues/falses indicating which elements equal 3. You are allowed to mix both logical and subscripts when indexing. So using this we can retrieve just those values from the first column:
A(A_index3, 1)
ans =
7
10
13
we get the same result if we do it in a single line without the A_index3 intermediate placeholder:
>> A(A(:,2)==3, 1)
ans =
7
10
13
Putting it in a for loop where 3 is replaced by the loop variable idx, and we assign the answer to the idx location in B, we get all of the values separated into different cells.

Algorithm to distribute evenly products value into care packages

i'm currently solving a problem that states:
A company filed for bankruptcy and decided to pay the employees with the last remaining valuable items in the company only if it can be distributed evenly among them so that all of them have at least received 1 item and that the difference between the employee carrying the most valuable items and the employee carrying the least valuable items can not exceed a certain value x;
Input:
First row contains number of employee;
Second row contains the x value so that the the difference between the employee carrying the most valuable items and the employee carrying the least valuable items can not exceed;
Third row contains all the items with their value;
Output:
First number is the least valuable basket of items value and the second is the most valuable basket;
Example:
Input:
5
4
2 5 3 11 4 3 1 15 7 8 10
Output:
13 15
Input:
5
4
1 1 1 11 1 3 1 2 7 8
Output:
NO (It's impossible to distribute evenly)
Input:
5
10
1 1 1 1
Output:
NO (It's impossible to distribute evenly)
My solution to resolve this problem taking the first input is to, sort the items in ascending or descending order so from
2 5 3 11 4 3 1 15 7 8 10 --> 1 2 3 3 4 5 7 8 10 11 15
then create an adjacency list or just store it in simple variables where we add the biggest number to the lowest basket while iterating the item values array
Element 0: 15
Element 1: 11 <- 3 (sum 14)
Element 2: 10 <- 3 (sum 13)
Element 3: 8 <- 4 <- 1 (sum 13)
Element 4: 7 <- 5 <- 2 (sum 14)
So that my solution will have O(nlogN + 2n), first part using merge sort and then finding max e min value, what do you guys think about this solution?

How to find number of cell from numbers of rows and columns of a table?

This may look like a really bad homework but it isn't. I don't know how to call this correctly. It is going to use in tic-tac-toe
I have a table with 3 rows and 3 columns. The structure look like this
1 2 3
- - -
1 | 1 2 3 <---- Cell number
2 | 4 5 6
3 | 7 8 9
I am going to use nested for loop to create a table for tic-tac-toe. For example,When a user click on cell number 1 it will look like this.
1 2 3
- - -
1 | O 2 3 <---- Cell number 1 is toggled
2 | 4 5 6
3 | 7 8 9
I have a problem that I don't know how to assign cell with correct number in for loop. I don't use nested array because it will make code too long.
It sounds to me that you don't want to use a 2D array. Instead, you wish to use a single array and access it as it would be a 2D array. Is this correct?
This means that you have to apply some simple math to your problem.
Based on your description, your 2D table has the same height and width, so height = width.
If you wish to obtain the index of an
index = column + width * row
If you wish to obtain x and y based on the index:
column = index % width;
row = index / width;

Bipartie Matching to form an Array

I am given a number from 1 to N , and there are M relationship given in the form a and b where we can connect number a and b.
We have to form the valid array , A array is said to be valid if for any two consecutive indexes A[i] and A[i+1] is one of the M relationship
We have to construct a valid Array of Size N, it's always possible to construct that.
Solution: Make A Bipartite Graph of the following , but there is a loophole on this,
let N=6
M=6
1 2
2 3
1 3
4 5
5 6
3 4
So Bipartite Matching gives this:
Match[1]=2
Match[2]=3
Match[3]=1 // Here it form a Loop
Match[4]=5
Match[5]=6
So how to i print a valid Array of size N , since N can be very large so many loops can be formed ? Is there any other solution ?
Another Example:
let N=6
M=6
1 3
3 5
2 5
5 1
4 2
6 4
It's will form a loop 1->3->5->1
1 3 5 2 4 6

I know how Merge Sort works, but How Merge Sort Code Works?

You can read this on Wikipedia:
function merge_sort(list m)
// Base case. A list of zero or one elements is sorted, by definition.
if length(m) <= 1
return m
// Recursive case. First, *divide* the list into equal-sized sublists.
var list left, right
var integer middle = length(m) / 2
for each x in m before middle
add x to left
for each x in m after or equal middle
add x to right
// Recursively sort both sublists
left = merge_sort(left)
right = merge_sort(right)
// Then merge the now-sorted sublists.
return merge(left, right)
On line 1 there's a list of numbers, let's say 9 6 3 7 5 1 8 2
They say that merge_sort divides the list on 2 and 2 again and again until each list has only 1 integer left, like this one:
9 6 3 7 5 1 8 2 -->
9 6 3 7 - 5 1 8 2 -->
9 6 - 3 7 - 5 1 - 8 2 -->
9 - 6 - 3 - 7 - 5 - 1 - 8 - 2
And then the numbers are put together like this:
6 9 - 3 7 - 1 5 - 2 8 -->
3 6 7 9 - 1 2 5 8 -->
1 2 3 5 6 7 8 9 -->
But I don't see where in the code the list of integers are divided on 2 again and again until each has only 1 integer left?
var list left, right
var integer middle = length(m) / 2
for each x in m before middle
add x to left
for each x in m after or equal middle
add x to right
As I understand, on the code above, the list of numbers is divided to two different lists:
9 6 3 7 and 5 1 8 2
What then happens on the code below?
left = merge_sort(left)
right = merge_sort(right)
Can someone explain me how the merge_sort code above exactly works step by step?
But I don't see where in the code the list of integers are divided on 2 again and again until each has only 1 integer left?
var list left, right
var integer middle = length(m) / 2 --------statement-1
for each x in m before middle --------statement-2
add x to left
for each x in m after or equal middle --------statement-3
add x to right
At the statement-1 you divide the array into two parts and add them to the left and right sub-array. In the statement-2, you are adding all the element before middle, which is your middle element of the array. Similarly statement-3, you are adding rest of the element in right sub-array. So essentially, you keep on dividing the array in two parts until their size is 1 or 0.
if length(m) <= 1
return m
In the start you have above conditional check, which return the method call if the size of the array is less then or equal to one.
What then happens on the code below?
left = merge_sort(left)
right = merge_sort(right)
This is a recursive call to sort (divide the array until size is one) the each sub array. Which is created in the above pseudo-code. You sort left and right sub-array separately and then join them into a single array.
return merge(left, right)
Here both left and right sub-array are passed to a merge function. These both array are sorted array. The task of the merge function is merge these sub-array into a single sorted array.
The pseudo code is missing some details. There was debate on the talk page about removing it or fixing it. Note it's supposed to be working with a list, not an array, which is why elements can only be appended one at a time. The list is not really split into 2 parts; instead two new initially empty lists left and right are created, then (middle = length/2) elements are moved from list to left, then (length - middle) elements are moved from list to right. This cleaned up example with C++ comments may make more sense, but it's still an inefficient way to sort a list. A bottom up merge sort using an array of pointers is much more efficient. I can add example code here if anyone is interested.
var list left, right
var integer middle = length(m) / 2
var integer count
for (count = 0; count < middle; count += 1)
get x from front of list // x = *list.front()
remove first element from list // list.pop_front()
add x to left // left.push_back(x)
for (count = middle; count < length; count += 1)
get x from front of list // x = *list.front()
remove first element from list // list.pop_front()
add x to right // right.push_back(x)
In that same wiki article, there are two C / C++ like code examples, which should be easier to understand. The examples are simplified and copy data back to the original array after each merge step, which could be avoided with more optimized code.
http://en.wikipedia.org/wiki/Merge_sort#Top-down_implementation
http://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation
The sequence is different for top down merge sort, it's depth first, left first:
9 6 3 7 5 1 8 2
9 6 3 7|5 1 8 2
9 6|3 7
9|6
6 9
3|7
3 7
3 6 7 9
5 1|8 2
5|1
1 5
8|2
2 8
1 2 5 8
1 2 3 5 6 7 8 9
Bottom up merge sort skips the recursion and just starts off assuming a run size of 1, and merges width first, left to right:
9 6 3 7 5 1 8 2
9|6|3|7|5|1|8|2 run size = 1
6 9|3 7|1 5|2 8 run size = 2
3 6 7 9|1 2 5 8 run size = 4
1 2 3 5 6 7 8 9 done
Another example of bottom up merge sort algorithm:
http://www.mathcs.emory.edu/~cheung/Courses/171/Syllabus/7-Sort/merge-sort5.html

Resources