1

I am writing an application in PHP where users can enter two sets of information and have every possible combination of the two sets printed out. The goal is to use it as a teaching tool for learning language by practicing different patterns of a question and answer.

For example, we may practice the question "Have you ever tried...?" plus one of four activities, such as bungee jumping, para sailing, skydiving, and scuba diving. There would also be four possible answers:

  1. Yes I have, and I enjoyed it.
  2. Yes I have, but I didn't like it.
  3. No I haven't, but I want to try it.
  4. No I haven't, and I don't want to try it.

The user would input the two sets of data, and the application would then print sheets of cards containing all possible combinations of the questions and answers. For example, card 1 would look like this:

  1. skydiving: Yes I have, and I enjoyed it.
  2. scuba diving: Yes I have, but I didn't like it.
  3. parasailing: No I haven't, but I want to try it.
  4. bungee jumping: No I haven't, and I don't want to try it.

The next card might then look like this:

  1. skydiving: Yes I have, but I didn't like it.
  2. scuba diving: No I haven't, but I want to try it.
  3. parasailing: No I haven't, and I don't want to try it.
  4. bungee jumping: Yes I have, and I liked it.

So as you can see, there are many different possible combinations. The idea would be that both lists would be of the same length to allow all of the possibilities to be printed out. It is also important that no question or answer gets used more than once on any card, and that two cards can be alike. What would be the best way to go about this? The actual input and output is not the problem--I've done similar things before. I just need the algorithm to produce the combinations.

EDIT: I guess what I'm really after is to keep the activities in the same order for each card, but have every possible combinations of answers. So what I really need is to be able to produce the following set of indexes for getting data out of the answers array. So I really want something more like this:

  • 0,1,2,3
  • 0,1,3,2
  • 0,2,1,3
  • 0,2,3,1
  • 0,3,1,2
  • 0,3,2,1
  • 1,0,2,3
  • 1,0,3,2
  • 1,2,0,3
  • 1,2,3,0

...and so on until all possible combinations have been produced.

blainarmstrong
  • 1,040
  • 1
  • 13
  • 33
  • 2
    The basic algorithm would be to loop through your first element, and in that loop, loop through your second element – poudigne Oct 05 '12 at 00:00
  • This would only give a limited number of combinations where they are simply in order (e.g.: card 1: 0-0, 1-1, 2-2, 3-3; card 2: 0-1, 1-2, 2-3, 3- 0, etc). I also want all the combinations that are not in order (e.g.: card 12: 0-2, 1-1, 2-0, 3-3; card 21: 0-3, 1-1, 2-0, 3-2). – blainarmstrong Oct 05 '12 at 02:46
  • @blainarmstrong Since the edited question has clarified what you want, I've added a new answer (I'm keeping the old one even if it's no longer correct, because I feel like it answered the question with what I and others thought were the criteria at the time). – Stegrex Oct 06 '12 at 07:52

2 Answers2

5

Try this:

$activities = array(); // Input all your activities as elements here.
$responses = array(); // Input all your responses as elements here.

foreach ($activities as $activity) {
    foreach ($responses as $response) {
        echo $activities.' '.$response."\n";
    }
}
Stegrex
  • 4,004
  • 1
  • 17
  • 19
  • Note this doesn't randomizes 'the cards'. Just logical output. But that 'problem' can be solved by providing the neighbours' kid with those cards and say: "Let's play a game: it's called throw all cards in the air." – Bas van Ommen Oct 05 '12 at 00:09
1

OK, with the new criteria, I think I understand a little better.

Try recursion. My solution is messy as hell but I can walk you through it:

$activities = array('a', 'b', 'c', 'd'); // Input all your activities as elements here.
$responses = array(1, 2, 3, 4); // Input all your responses as elements here.

// Recursive function outputCombos accepts both arrays (for eventual output).
// $workingArray is the array of the current branch we're working with.
function outputCombos ($activities, $responses, $workingArray) {
    // Once the working array has been loaded to the maximum amt, print everything out.
    if (count($workingArray) == count($responses)) {
        echo "Combo\n";
        for ($x = 0; $x < count($activities); $x++) {
            echo $activities[$x].'::'.$workingArray[$x]."\n";
        }
    // If the working array isn't full, add an element that isn't currently in the working array, and recursively run the function again.
    } else {
        foreach ($responses as $response) {
            // Iterate through list of all possible responses, add it into a new working array and run the function if the response hasn't been used in this working array.
            if (!in_array($response, $workingArray)) {
                $newArray = $workingArray;
                $newArray[] = $response;
                outputCombos($activities, $responses, $newArray);
            }
        }
    }
}

foreach ($responses as $response) {
    echo '<pre>';
    // Start each branch of tree with unique response (should be 4 in this case).
    outputCombos($activities, $responses, array($response));
    echo '</pre>';
}
Stegrex
  • 4,004
  • 1
  • 17
  • 19