This question already has an answer here:
Python Coin change SO CLOSE
(1 answer)
Closed 3 years ago.
Given a dollar amount convert it into euro coins and bills. You are given the dollar
amount as the argument, and said that the dollar to euro rate is 1.30. You are given
that euro denomations are 500 bill, 200 bill, 100 bill, 50 bill, 20 bill, 10 bill, 5 bill, 2
bill, 1 bill, 50 cents, 25 cents, 10 cents, 5 cents, 2 cents, 1 cent. Convert that
dollar amount into the least amount of bills and coins. (Convert a numerical dollar
amount (such as $10.00) to an equivalent amount in Euro Bills and Coins.)
Disclaimer: This is a homework problem I've been given.
I've thought about solving it using a while loop which iterates through each of the denominations and subtracts it from the value. something like:
while(amount > 0){
if(amount - denomination[index] > 0) {
amount -= denomination[index];
}else{
index++;
}
}
But other sources are telling me that the coin change problems is solved with dynamic programming. I'm very confused.
For this specific denomations set change problem might be solved by greedy method, as you did.
Same is true for sets where values differ twice like 1,2,4,8..., but rules are not simple, as #Patrick87 noticed in comment. Appropriate money systems are called "canonical", but it is not easy to find whether given system is canonical: example of discussion
For arbitrary values greedy method can fail
([1,5,15,20]gives 20+5+5 for sum=30 while 15+15 is better)
That is why in general coin change problem should be solved with dynamic programming
This answer is probably not "academic" enough, but using JavScript you can boil it down to a simple application of Array.reduce() (assuming that the "greedy" approach is applicable, which it will be for the Euro currency system):
change=amnt=>(c,d,i)=>{var rest=amnt%d;
if (rest!=amnt) {c[i]=(amnt-rest)/d; amnt=rest;}
return c };
var rate=110.36; // Euro cents per USD
var res=document.querySelector('#result');
document.querySelector('#USD').onkeyup=ev=>{
var cents=Math.round(ev.target.value*90.78); // amount in Euro cents
var denom=[50000,20000,10000,5000,2000,1000,
5000,2000,1000,500,100,50,20,10,5,2,1];
var coins=denom.reduce(change(cents),[]);
res.innerHTML=cents/100+' €<br>'
+coins.map((n,i)=>n+'x'+(denom[i]>99?denom[i]/100+'€':denom[i]+'ct'))
.filter(v=>v).join(', ');
}
USD <input type="text" value="13" id="USD">
<div id="result"></div>
Traditionally, currency coin change problems like the one presented to you are designed to be dynamic programming questions. Here's an example where your approach will yield the wrong answer for a similar problem with a simpler premise:
Given an unlimited number of 7$ bills, 5$ bills, 4$ bills and 1$ bills, and a certain item with price of N$, find the optimal way of purchasing the item so that you use the least amount of bills possible.
Now if I set N=12 in the previous problem, you'll see that your algorithm will indeed break down the 12$ into 1 bill of 7$ and another bill of 5$. If I set N=9 however, then you'll notice that your algorithm will break down the 9$ into a bill of 7$ and two bills of 1$, when the optimal solution is one bill of 5$ and one bill of 4$.
So is your solution correct? Turns out, it is. That's simply because your bills are given in a way that your greedy solution will always work (I tested it up to 100000.00$ just to be 100% sure). I'm sure you can find resources online that can tell you the exact reason as to why your set of bill values works with a greedy algorithm, and unfortunately, I can't provide you with a satisfying explanation. Here's a discussion related to this issue
Although you can solve your solution with a greedy algorithm, the dynamic programming (DP) approach will also yield the correct answers, and luckily for you, there are plenty of resources that can teach you about DP, if that's what's confusing you, such as GeeksForGeeks. If you're having issues implementing the DP solution, the code is posted here!
The problem of determining optimal representation in a coin system, in general, is weakly NP-hard. Probably, for all contemporary coin systems in the World greedy algorithm works fine. Most often contemporary coin systems use so-called binary-decimal pattern 1-2-5. But your example has 25 cents which require a closer look.
But first, let's prove that 1-2-5 pattern amenable for the greedy algorithm. Observe that their LCM is 10, this means that we need to check only numbers in [1..9].
1 = 1,0,0 4 = 0,2,0 7 = 0,1,1
2 = 0,1,0 5 = 0,0,1 8 = 1,1,1
3 = 1,1,0 6 = 1,0,1 9 = 0,2,1
So, this pattern is greedy. Let's now turn our attention to the first six denominations 50, 25, 10, 5, 2, 1. Here we have the same LCM - 50. I wrote a program to check this:
#include <iostream>
#include <array>
#include <iomanip>
#include <algorithm>
#include <numeric>
#include <iterator>
bool IsOptimal(const int sum, const int numberOfCoins, std::array<int, 6>::const_iterator begin, std::array<int, 6>::const_iterator end) {
if (sum < 0 || numberOfCoins == 0) return true;
for (auto it = begin; it < end; ++it) {
const int nextSum = sum - *it;
if (nextSum == 0) return numberOfCoins == 1;
if (!IsOptimal(nextSum, numberOfCoins - 1, it, end))
return false;
}
return true;
}
int main() {
const std::array<int, 6> kDenoms = { 1,2,5,10,25,50 };
for (int i = 1; i < 50; ++i) {
std::array<int, 6> change = { 0 };
int sum = 0;
while (sum != i) {
auto it = std::upper_bound(kDenoms.cbegin(), kDenoms.cend(), i - sum);
++change[--it - kDenoms.cbegin()];
sum += *it;
}
const bool isOptimal = IsOptimal(sum, std::accumulate(change.cbegin(), change.cend(), 0), kDenoms.cbegin(), kDenoms.cend());
std::cout << std::setw(2) << i << ": ";
std::copy(change.cbegin(), change.cend() - 1, std::ostream_iterator<int>(std::cout, ","));
std::cout << change.back() << " " << std::boolalpha << isOptimal << std::endl;
}
return 0;
}
So, basically, what do we know? We know that all quantities less than 50 we can attack with the greedy algorithm to get its optimal solution.
Observe, that all denominations above 50 are divisible by 50, so they will not interfere with 50, 25, 10, 5, 2, 1. We also proved that the greedy algorithm works for pattern 1-2-5, so the whole set of denominations amenable for the greedy algorithm.
Related
This seems to be a variation of the LeetCode House Robber problem, but I found it significantly harder to tackle:
There are houses laid out on a NxN grid. Each house is known to contain some amount of valuables. The robbers task is to rob as many houses as possible to maximize the amount of loot. However there is a security system in place and if you rob two adjacent houses (to the left, right, above and below) an alarm will go off. Find the maximum loot the robber can rob.
Houses : alignment
10 20 10 0 1 0
20 40 20 => 1 0 1
10 20 10 0 1 0
This alignment results in the maximum of 80.
I've learned how to solve the optimum selection of houses for a single row with dynamic programming from https://shanzi.gitbooks.io/algorithm-notes/problem_solutions/house_robber.html:
public class HouseRobber {
public int rob(int[] nums) {
if (nums.length == 0) return 0;
if (nums.length == 1) return nums[0];
int[] dp = new int[nums.length];
dp[0] = nums[0];
int max = dp[0];
for (int i = 1; i < dp.length; i++) {
dp[i] = nums[i];
// Do not need to check k < i - 3.
for (int j = 2; i - j >= 0 && j <= 3; j++) {
dp[i] = Math.max(dp[i], dp[i - j] + nums[i]);
}
max = Math.max(dp[i], max);
}
return max;
}
}
But once I select one row's optimum selection, it might not align with with the optimum selections for the rows above and below that row. Even if I find the optimum combination for two rows, the next row might have more valuables than the two rows combined and would require another adjustment, and on and on.
This is difficult because there are a lot more variables to consider than houses on a single row and there could also be more than one optimum alignments that give the robber maximum loot (such as the example above.)
I did find what seemed to be a poorly written solution in Python, but since I only understand C-based languages (Java, C#, C++), I couldn't get much out of it. Could anyone help me with a solution or at least some pointers?
Thanks for your time!
I went through the python code you mentioned. The solution using flow looks plain wrong to me. There is no path from source to sink with finite weight. That solution basically colors the grid like a chessboard and chooses either all the black squares or all the white squares. That is not optimal in the following case:
1 500
300 1
1000 300
It is better to choose 1000 and 500 but that solution will choose 300+300+500.
The dynamic programming solution is exponential.
I don't know enough math to understand the LP solution.
Sorry to not answer your question.
I recently learned the concept of Bit Manipulation for Competitive Programming so I'm quite new to the concept ,I also read many tutorials on Bit-Masking + Dynamic Programming on Hackerearth ,CodeChef and many more .
I also solved a couple of problems on Codechef including this one problem
and I have a couple of doubts regarding Bitmasks after I have been through some questions.
The problems I solved were mostly focused on manipulating the subsets but I wonder how do I work on permutations with bitmasks , i.e when I have to work on a state where all bits in the mask need to be set.
For ex: If we have to find number of numbers that can be formed by arranging all digits of a given number A which are divisible by a given number B where (A ,B<= 10**6) how can this be done with bitmasks.(I hope this can be done with bitmask+dp)
If A= 514 ,and B=2
The question expects the answer to be
514
154
Which are both divisible by 2 .
So the answer is 2.
With the knowledge I have: 514 and 154 represent the same mask 111 where all bits are set So how do I use bitmasks here where the mask is same for two or more answers!( I hope you understand this ).
And also as it is impossible to allocate memory worth n!*n for a little large value of n since we can have that many permutations of digits how can this problem be done using bitmasks where we need only (2**n)*n space (If i'm not wrong).
So how do I approach the above problem iteratively? /Or any DP state equation which I can possibly understand ,I couldn't understand recursive approach of some similar problems I Read.
I also tried to think on a similar problem TSHIRTS but I couldn't understand the logic behind the recursion.
You don't actually need DP for this one but you can use bit manipulation nicely :) Since A <= 10^6 it means that A has most 7 digits; so you only have to check 7! = 5040 states.
const int A = 514;
const int B = 2;
vector <int> v; //contains digits of A (e.g. 5, 1, 4) this can be done before the recursive function in a while loop.
int rec(int mask, int current_number){
if(mask == (1 << v.size()) - 1){ //no digit left to pick
if(current_number % B == 0) return 1;
else return 0;
}
int ret = 0;
for(int i = 0; i < v.size(); i++){
if(mask & (1 << i)) continue; //this is already picked
ret += rec(mask | (1 << i), current_number * 10 + v[i]);
}
return ret;
}
Note that the reason I didn't use DP here was that current number might differ even if mask is the same; so you can't actually say that the situation has been repeated. Unless you memo-ize mask AND current_number which requires much more space.
I am doing a question on hackerrank(https://www.hackerrank.com/contests/w21/challenges/lazy-sorting) right now, and I am confused as to why doesn't my code fulfill the requirements. The questions asks:
Logan is cleaning his apartment. In particular, he must sort his old favorite sequence, P, of N positive integers in nondecreasing order. He's tired from a long day, so he invented an easy way (in his opinion) to do this job. His algorithm can be described by the following pseudocode:
while isNotSorted(P) do {
WaitOneMinute();
RandomShuffle(P)
}
Can you determine the expected number of minutes that Logan will spend waiting for to be sorted?
Input format:
The first line contains a single integer, N, denoting the size of permutation .The second line contains N space-separated integers describing the respective elements in the sequence's current order, P_0, P_1 ... P_N-1.
Constraints:
2 <= N <= 18
1 <= P_i <= 100
Output format:
Print the expected number of minutes Logan must wait for P to be sorted, rounded to a scale of exactly 6 decimal places (i.e.,1.234567 format).
Sample input:
2
5 2
Sample output:
2.000000
Explanation
There are two permutations possible after a random shuffle, and each of them has probability 0.5. The probability to get the sequence sorted after the first minute is 0.5. The probability that will be sorted after the second minute is 0.25, the probability will be sorted after the third minute is 0.125, and so on. The expected number of minutes hence equals to:
summation of i*2^-i where i goes from 1 to infinity = 2
I wrote my code in c++ as follow:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
map <int, int> m; //create a map to store the number of repetitions of each number
int N; //number of elements in list
//calculate the number of permutations
cin >> N;
int j;
int total_perm = 1;
int temp;
for (int i = 0; i < N; i++){
cin >> temp;
//if temp exists, add one to the value of m[temp], else initialize a new key value pair
if (m.find(temp) == m.end()){
m[temp] = 1;
}else{
m[temp] += 1;
}
total_perm *= i+1;
}
//calculate permutations taking into account of repetitions
for (map<int,int>::iterator iter = m.begin(); iter != m.end(); ++iter)
{
if (iter -> second > 1){
temp = iter -> second;
while (temp > 1){
total_perm = total_perm / temp;
temp -= 1;
}
}
}
float recur = 1 / float(total_perm);
float prev;
float current = recur;
float error = 1;
int count = 1;
//print expected number of minutes up to 6 sig fig
if (total_perm == 1){
printf("%6f", recur);
}else{
while (error > 0.0000001){
count += 1;
prev = current;
current = prev + float(count)*float(1-recur)*pow(recur,count-1);
error = abs(current - prev);
}
printf("%6f", prev);
}
return 0;
}
I don't really care about the competition, it's more about learning for me, so I would really appreciate it if someone can point out where I was wrong.
Unfortunately I am not familiar with C++ so I don't know exactly what your code is doing. I did, however, solve this problem. It's pretty cheeky and I think they posed the problem the way they did just to be confusing. So the important piece of knowledge here is that for an event with probability p, the expected number of trials until a success is 1/p. Since each trial here costs us a minute, that means we can find the expected number of trials and add ".000000" to the end.
So how do you do that? Well each permutation of the numbers is equally likely to occur, which means that if we can find how many permutations there are, we can find p. And then we take 1/p to get E[time]. But notice that each permutation has probability 1/p of occurring, where p is the total number of permutations. So really E[time] = number of permutations. I leave the rest to you.
This is just simple problem.
This problem looks like bogo sort.
How many unique permutations of the given array are possible? In the sample case, there are two permutations possible, so the expected time for any one permutation to occur is 2.000000. Extend this approach to the generic case, taking into account any repeated numbers.
However in the question, the numbers can be repeated. This reduces the number of unique permutations, and thus the answer.
Just find the number of unique permutations of the array, upto 6 decimal places. That is your answer.
Think about if array is sorted then what happen?
E.g
if test case is
5 5
5 4 3 2 1
then ans would be 120.000000 (5!/1!)
5 5
1 2 3 4 5
then ans would be 0.000000 in your question.
5 5
2 2 2 2 2
then also ans would be 0.000000
5 5
5 1 2 2 3
then ans is 60.000000
In general ans is if array is not sorted : N!/P!*Q!.. and so on..
Here is another useful link:
https://math.stackexchange.com/questions/1844133/expectation-over-sequencial-random-shuffles
I often teach large introductory programming classes (400 - 600 students) and when exam time comes around, we often have to split the class up into different rooms in order to make sure everyone has a seat for the exam.
To keep things logistically simple, I usually break the class apart by last name. For example, I might send students with last names A - H to one room, last name I - L to a second room, M - S to a third room, and T - Z to a fourth room.
The challenge in doing this is that the rooms often have wildly different capacities and it can be hard to find a way to segment the class in a way that causes everyone to fit. For example, suppose that the distribution of last names is (for simplicity) the following:
Last name starts with A: 25
Last name starts with B: 150
Last name starts with C: 200
Last name starts with D: 50
Suppose that I have rooms with capacities 350, 50, and 50. A greedy algorithm for finding a room assignment might be to sort the rooms into descending order of capacity, then try to fill in the rooms in that order. This, unfortunately, doesn't always work. For example, in this case, the right option is to put last name A in one room of size 50, last names B - C into the room of size 350, and last name D into another room of size 50. The greedy algorithm would put last names A and B into the 350-person room, then fail to find seats for everyone else.
It's easy to solve this problem by just trying all possible permutations of the room orderings and then running the greedy algorithm on each ordering. This will either find an assignment that works or report that none exists. However, I'm wondering if there is a more efficient way to do this, given that the number of rooms might be between 10 and 20 and checking all permutations might not be feasible.
To summarize, the formal problem statement is the following:
You are given a frequency histogram of the last names of the students in a class, along with a list of rooms and their capacities. Your goal is to divvy up the students by the first letter of their last name so that each room is assigned a contiguous block of letters and does not exceed its capacity.
Is there an efficient algorithm for this, or at least one that is efficient for reasonable room sizes?
EDIT: Many people have asked about the contiguous condition. The rules are
Each room should be assigned at most a block of contiguous letters, and
No letter should be assigned to two or more rooms.
For example, you could not put A - E, H - N, and P - Z into the same room. You could also not put A - C in one room and B - D in another.
Thanks!
It can be solved using some sort of DP solution on [m, 2^n] space, where m is number of letters (26 for english) and n is number of rooms. With m == 26 and n == 20 it will take about 100 MB of space and ~1 sec of time.
Below is solution I have just implemented in C# (it will successfully compile on C++ and Java too, just several minor changes will be needed):
int[] GetAssignments(int[] studentsPerLetter, int[] rooms)
{
int numberOfRooms = rooms.Length;
int numberOfLetters = studentsPerLetter.Length;
int roomSets = 1 << numberOfRooms; // 2 ^ (number of rooms)
int[,] map = new int[numberOfLetters + 1, roomSets];
for (int i = 0; i <= numberOfLetters; i++)
for (int j = 0; j < roomSets; j++)
map[i, j] = -2;
map[0, 0] = -1; // starting condition
for (int i = 0; i < numberOfLetters; i++)
for (int j = 0; j < roomSets; j++)
if (map[i, j] > -2)
{
for (int k = 0; k < numberOfRooms; k++)
if ((j & (1 << k)) == 0)
{
// this room is empty yet.
int roomCapacity = rooms[k];
int t = i;
for (; t < numberOfLetters && roomCapacity >= studentsPerLetter[t]; t++)
roomCapacity -= studentsPerLetter[t];
// marking next state as good, also specifying index of just occupied room
// - it will help to construct solution backwards.
map[t, j | (1 << k)] = k;
}
}
// Constructing solution.
int[] res = new int[numberOfLetters];
int lastIndex = numberOfLetters - 1;
for (int j = 0; j < roomSets; j++)
{
int roomMask = j;
while (map[lastIndex + 1, roomMask] > -1)
{
int lastRoom = map[lastIndex + 1, roomMask];
int roomCapacity = rooms[lastRoom];
for (; lastIndex >= 0 && roomCapacity >= studentsPerLetter[lastIndex]; lastIndex--)
{
res[lastIndex] = lastRoom;
roomCapacity -= studentsPerLetter[lastIndex];
}
roomMask ^= 1 << lastRoom; // Remove last room from set.
j = roomSets; // Over outer loop.
}
}
return lastIndex > -1 ? null : res;
}
Example from OP question:
int[] studentsPerLetter = { 25, 150, 200, 50 };
int[] rooms = { 350, 50, 50 };
int[] ans = GetAssignments(studentsPerLetter, rooms);
Answer will be:
2
0
0
1
Which indicates index of room for each of the student's last name letter. If assignment is not possible my solution will return null.
[Edit]
After thousands of auto generated tests my friend has found a bug in code which constructs solution backwards. It does not influence main algo, so fixing this bug will be an exercise to the reader.
The test case that reveals the bug is students = [13,75,21,49,3,12,27,7] and rooms = [6,82,89,6,56]. My solution return no answers, but actually there is an answer. Please note that first part of solution works properly, but answer construction part fails.
This problem is NP-Complete and thus there is no known polynomial time (aka efficient) solution for this (as long as people cannot prove P = NP). You can reduce an instance of knapsack or bin-packing problem to your problem to prove it is NP-complete.
To solve this you can use 0-1 knapsack problem. Here is how:
First pick the biggest classroom size and try to allocate as many group of students you can (using 0-1 knapsack), i.e equal to the size of the room. You are guaranteed not to split a group of student, as this is 0-1 knapsack. Once done, take the next biggest classroom and continue.
(You use any known heuristic to solve 0-1 knapsack problem.)
Here is the reduction --
You need to reduce a general instance of 0-1 knapsack to a specific instance of your problem.
So lets take a general instance of 0-1 knapsack. Lets take a sack whose weight is W and you have x_1, x_2, ... x_n groups and their corresponding weights are w_1, w_2, ... w_n.
Now the reduction --- this general instance is reduced to your problem as follows:
you have one classroom with seating capacity W. Each x_i (i \in (1,n)) is a group of students whose last alphabet begins with i and their number (aka size of group) is w_i.
Now you can prove if there is a solution of 0-1 knapsack problem, your problem has a solution...and the converse....also if there is no solution for 0-1 knapsack, then your problem have no solution, and vice versa.
Please remember the important thing of reduction -- general instance of a known NP-C problem to a specific instance of your problem.
Hope this helps :)
Here is an approach that should work reasonably well, given common assumptions about the distribution of last names by initial. Fill the rooms from smallest capacity to largest as compactly as possible within the constraints, with no backtracking.
It seems reasonable (to me at least) for the largest room to be listed last, as being for "everyone else" not already listed.
Is there any reason to make life so complicated? Why cann't you assign registration numbers to each student and then use the number to allocate them whatever the way you want :) You do not need to write a code, students are happy, everyone is happy.
I have a population of 50 ordered integers (1,2,3,..,50) and I look for a generic way to slice it "n" ways ("n" is the number of cutoff points ranging from 1 to 25) that maintains the order of the elements.
For example, for n=1 (one cutoff point) there are 49 possible grouping alternatives ([1,2-49], [1-2,3-50], [1-3,4-50],...). For n=2 (two cutoff points), the grouping alternatives are like: [1,2,3-50], [1,2-3,4-50],...
Could you recommend any general-purpose algorithm to complete this task in an efficient way?
Thanks,
Chris
Thanks everyone for your feedback. I reviewed all your comments and I am working on a generic solution that will return all combinations (e.g., [1,2,3-50], [1,2-3,4-50],...) for all numbers of cutoff points.
Thanks again,
Chris
Let sequence length be N, and number of slices n.
That problem becomes easier when you notice that, choosing a slicing to n slices is equivalent to choosing n - 1 from N - 1 possible split points (a split point is between every two numbers in the sequence). Hence there is (N - 1 choose n - 1) such slicings.
To generate all slicings (to n slices), you have to generate all n - 1 element subsets of numbers from 1 to N - 1.
The exact algorithm for this problem is placed here: How to iteratively generate k elements subsets from a set of size n in java?
Do you need the cutoffs, or are you just counting them. If you're just going to count them, then it's simple:
1 cutoff = (n-1) options
2 cutoffs = (n-1)*(n-2)/2 options
3 cutoffs = (n-1)(n-2)(n-3)/4 options
you can see the patterns here
If you actually need the cutoffs, then you have to actually do the loops, but since n is so small, Emilio is right, just brute force it.
1 cutoff
for(i=1,i<n;++i)
cout << i;
2 cutoffs
for(i=1;<i<n;++i)
for(j=i+1,j<n;++j)
cout << i << " " << j;
3 cutoffs
for(i=1;<i<n;++i)
for(j=i+1,j<n;++j)
for(k=j+1,k<n;++k)
cout << i << " " << j << " " << k;
again, you can see the pattern
So you want to select 25 split point from 49 choices in all possible ways. There are a lot of well known algorithms to do that.
I want to draw your attention to another side of this problem. There are 49!/(25!*(49-25)!) = 63 205 303 218 876 >= 2^45 ~= 10^13 different combinations. So if you want to store it, the required amount of memory is 32TB * sizeof(Combination). I guess that it will pass 1 PB mark.
Now lets assume that you want to process generated data on the fly. Lets make rather optimistic assumption that you can process 1 million combinations per second (here i assume that there is no parallelization). So this task will take 10^7 seconds = 2777 hours = 115 days.
This problem is more complicated than it seems at first glance. If you want to solve if at home in reasonable time, my suggestion is to change the strategy or wait for the advance of quantum computers.
This will generate an array of all the ranges, but I warn you, it'll take tons of memory, due to the large numbers of results (50 elements with 3 splits is 49*48*47=110544) I haven't even tried to compile it, so there's probably errors, but this is the general algorithm I'd use.
typedef std::vector<int>::iterator iterator_t;
typedef std::pair<iterator_t, iterator_t> range_t;
typedef std::vector<range_t> answer_t;
answer_t F(std::vector<int> integers, int slices) {
answer_t prev; //things to slice more
answer_t results; //thin
//initialize results for 0 slices
results.push_back(answer(range(integers.begin(), integers.end()), 1));
//while there's still more slicing to do
while(slices--) {
//move "results" to the "things to slice" pile
prev.clear();
prev.swap(results);
//for each thing to slice
for(int group=0; group<prev.size(); ++group) {
//for each range
for(int crange=0; crange<prev[group].size(); ++crange) {
//for each place in that range
for(int newsplit=0; newsplit<prev[group][crange].size(); ++newsplit) {
//copy the "result"
answer_t cur = prev[group];
//slice it
range_t L = range(cur[crange].first, cur[crange].first+newsplit);
range_t R = range(cur[crange].first+newsplit), cur[crange].second);
answer_t::iterator loc = cur.erase(cur.begin()+crange);
cur.insert(loc, R);
cur.insert(loc, L);
//add it to the results
results.push_back(cur);
}
}
}
}
return results;
}