-3

This code currently outputs 0 1 0 1 1 2 F0 0 1 0 1 1 2 F1 0 1 0 1 1 3 F0 0 1 0 1 1 3 F1 0 1 0 1 1 4 F0 etc. I'm trying to find out the correct values of green, yellow, purple, orange, red and blue using brute force These values can't repeat (i.e. if red = 0 then blue != 0), but I figured this code would give me multiple solutions, from which I could choose the correct one. My question is: what is wrong with this?

#include <iostream>
using namespace std;

int main()
{
int green, yellow, purple, orange, red, blue, finalresult;
int result1, result2, result3, result4, result5, result6, fresult1, fresult2;

for (green = 0; green < 10; green++)
{

    for (yellow = 0; yellow < 10; yellow++)
    {
        for (yellow = yellow; yellow == green; yellow++)
        {
            yellow = yellow;
        }
        for (purple = 0; purple < 10; purple++)
        {
            for (purple = purple; purple == yellow; purple++)
            {
                purple = purple;
            }
             for (orange = 0; orange < 10; orange++)
             {
                for (orange = orange; orange == purple; orange++)
                {
                    orange = orange;
                }
                  for (red = 1; red < 10; red++)
                  {
                        for (red = red; red == purple; red++)
                        {
                            red = red;
                        }
                        for (blue = 1; blue < 10; blue++)
                        {
                            for (blue = blue; blue == red; blue++)
                            {
                                blue = blue;
                            }
                            finalresult = 0;
                            if(green * yellow == purple * 10 + green)
                            {
                                cout << green << endl << yellow << endl << purple << endl << orange << endl << red << endl << blue << endl;
                                cout << "F" << finalresult << endl;
                                finalresult++;
                            }
                            if (purple * 10 + orange / red == red)
                            {
                                cout << green << endl << yellow << endl << purple << endl << orange << endl << red << endl << blue << endl;
                                cout << "F" << finalresult << endl;
                                finalresult++;
                            }
                            if (yellow * 10 + orange == red * blue)
                            {
                                cout << green << endl << yellow << endl << purple << endl << orange << endl << red << endl << blue << endl;
                                cout << "F" << finalresult << endl;
                                finalresult++;
                            }
                            if (green == red * 10 + green / blue)
                            {
                                cout << green << endl << yellow << endl << purple << endl << orange << endl << red << endl << blue << endl;
                                cout << "F" << finalresult << endl;
                                finalresult++;
                            }
                            if (finalresult == 4)
                            {
                                cout << "V" << endl <<"V" << endl << "V" << endl << "V" << endl << "V" << endl << "V" << endl << "V" << endl << "V" << endl << "V" << endl << "V" << endl << "V" << endl << "V" << endl << "V" << endl;
                                cout << green << endl << yellow << endl << purple << endl << orange << endl << red << endl << blue << endl;

                            }
                        }

                  }

             }

        }

    }

}

}

Artain
  • 7
  • 2
  • 4
    " what is wrong with this? " how can we know? We dont know what you are trying to solve. You need to include the input, output and expected output in the question – 463035818_is_not_an_ai Sep 27 '18 at 12:33
  • 3
    typo: `if (green = red * 10 + green / blue)` -> `if (green == red * 10 + green / blue)` – Jarod42 Sep 27 '18 at 12:46
  • 3
    and `green / blue` is problematic when `blue == 0` – Jarod42 Sep 27 '18 at 12:46
  • Move the `cout << green << endl << yellow << endl << purple << endl << orange << endl << red << endl << blue;` into each of the above if () {} blocks. That way you print the solution each time instead of only the 4th solution. You probably want to add an << '\n'; to that. – drescherjm Sep 27 '18 at 12:50
  • user463035818 - Input is given in the code, output, as said, is F0 and expected output is described in the question. – Artain Sep 27 '18 at 13:15
  • Jarod42 - Thank you drescherjm - Thank you – Artain Sep 27 '18 at 13:16
  • 1
    Can you clearly state the problem you are trying to solve ? What are the "correct values" ? – Clonk Sep 27 '18 at 13:34
  • Also, you should use function it would make your code more readable. – Clonk Sep 27 '18 at 13:34
  • Correct values can't repeat. And the below equations must be correct using them: g * y = p * 10 + g |[end]| (p * 10 + o) / r = r |[end]| y * 10 + o = r * b |[end]| g = (r * 10 + g) / b |[end]| – Artain Sep 27 '18 at 13:45
  • 2
    `for (yellow = yellow; yellow == green; yellow++) { yellow = yellow; }` is just `yellow = green;` Could you please explain what are you trying to achive here? – Bob__ Sep 27 '18 at 14:19
  • `yellow = yellow;` is a statement with absolutely no effect. There is no reason to assign the value of the variable to itself. It already has the value that it has. What is the point of that and similar lines? – John Coleman Sep 27 '18 at 14:26
  • Bob and John Coleman - Considering I'm ultra-beginner, just a safety measure because I don't know whether a for loop needs something inside or can it just run the increment over and over. – Artain Sep 27 '18 at 15:00
  • 1
    The loop `for (orange = orange; orange == purple; orange++)` won't execute at all unless `orange == purple` before you hit that line of code. The effect of that loop is closer to `if(orange == purple)`, which probably isn't your intent. You are making what seems like it should be a simple nested loop into a massively complicated bit of spaghetti code. – John Coleman Sep 27 '18 at 15:26
  • John Coleman - Oops... Thanks for pointing that out. This problem has appeared now:? ld.exe||cannot open output file C:\Users\USERNAME\Documents\x.exe Permission denied| – Artain Sep 27 '18 at 15:35
  • Notice also that `orange / red == red` for `red == 2`, `orange == 5` (in addition to `4`) would also be a solution (integer division). – Jarod42 Sep 27 '18 at 15:49
  • Jarod42 - Okay, noticed. But, as I have stated, I'm a complete newbie, and therefore I don't know how to solve that. Additionally, I can't test anything right now due to the problem pointed out in the comment before yours. – Artain Sep 27 '18 at 15:57
  • Unreadable code. I find that most newbies tend to be too literal when they write code. This is more proof. – duffymo Sep 27 '18 at 18:36

2 Answers2

1

If I understood the problem, you have to choose between all the possible combinations of distinct color values the ones that solve your four equations.

The nested loops in OP's code will provide (almost, some loops start at 1) all the possible combinations, but the way choosen to exclude the duplicate values is completely wrong.

The equations also, could be checked in one single condition.

The following code should give the expected result:

#include <iostream>

int main(void)
{
    long int n = 0, solutions = 0;

    for (int green = 0; green < 10; ++green)
    {
        for (int yellow = 0; yellow < 10; ++yellow)
        {
            if ( yellow == green )    // skip the duplicate values
                continue;

            for (int purple = 0; purple < 10; ++purple)
            {
                if ( purple == green  ||  purple == yellow )
                    continue;

                for (int orange = 0; orange < 10; ++orange)
                {
                    if ( orange == green  ||  orange == yellow  ||  orange == purple )
                        continue;

                    for (int red = 0; red < 10; ++red)
                    {
                        if ( red == green   ||  red == yellow  ||
                             red == purple  ||  red == orange)
                            continue;

                        for (int blue = 0; blue < 10; ++blue)
                        {
                            if ( blue == green   ||  blue == yellow  ||
                                 blue == purple  ||  blue == orange  ||  blue == red )
                                continue;

                            // Now check if the values solve all the equations
                            // Assuming that you don't want integer divisions 
                            if (   purple * 10 + green  == green * yellow
                                && purple * 10 + orange == red * red
                                && yellow * 10 + orange == red * blue
                                &&    red * 10 + green  == green * blue)
                            {
                                std::cout << "Green:  " << green
                                    << "\nYellow: " << yellow
                                    << "\nPurple: " << purple
                                    << "\nOrange: " << orange
                                    << "\nRed:    " << red
                                    << "\nBlue:   " << blue << '\n';
                                ++solutions;
                            }
                            ++n;
                        }
                    }
                }
            }
        }
    }
    // The number of different combinations should be 10 * 9 * 8 * 7 * 6 * 5 = 151200 
    std::cout << "\nCombinations tested: " << n
        << " (out of " << 10*10*10*10*10*10 << ")\n"
        << "Solutions: " << solutions << '\n';
}

Once executed, it outputs:

Green:  5
Yellow: 3
Purple: 1
Orange: 6
Red:    4
Blue:   9

Combinations tested: 151200 (out of 1000000)
Solutions: 1

EDIT

Spurred by Jarod42's answer, I'd like to show a more efficient solution, which takes advantages of the standard library function std::next_permutation (and std::prev_permutation too) and instead of skipping the unwanted permutations, directly generates only the needed ones.

#include <iostream>
#include <vector>
#include <array>
#include <algorithm>
#include <numeric>

// Applies f() to all the permutations of n values taken k at a time
// where k is the size of the range [first, last)
// n!/(n − k)! iterations are performed
template<class Iterator, class Func>
void for_each_n_permute_k(int n, Iterator first, Iterator last, Func f);

int main()
{
    std::array<int, 6> chosen;
    int solutions = 0;

    for_each_n_permute_k(10, chosen.begin(), chosen.end(), [&chosen, &solutions] () {
        auto & [green, yellow, purple, orange, red, blue] = chosen;

        if (   purple * 10 + green  == green * yellow
            && purple * 10 + orange == red * red
            && yellow * 10 + orange == red * blue
            &&    red * 10 + green  == green * blue)
        {
            std::cout << "Solution found (" << ++solutions << ")\n"
                << "Green:  " << green
                << "\nYellow: " << yellow
                << "\nPurple: " << purple
                << "\nOrange: " << orange
                << "\nRed:    " << red
                << "\nBlue:   " << blue << '\n';
        }
    });
}

// copy the elements from [it1, last) to dest if the predicate applied to
// the corresponding element of [it2, it2 + distance(it1, last)) returns true
template<class Input1It, class Input2It, class OutputIt, class Predicate>
constexpr OutputIt select_if(Input1It it1, Input1It last,
                             Input2It it2, OutputIt dest, Predicate pred)
{
    for( ; it1 != last; ++it1, ++it2)
    {
        if (pred(*it2))
        {
            *dest++ = *it1;
        } 
    }
    return dest;
}

template<class Iterator, class Func>
void for_each_n_permute_k(int n, Iterator first, Iterator last, Func f)
{
    // e.g. for n == 10 -> {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    std::vector<int> numbers(n);
    std::iota(numbers.begin(), numbers.end(), 0);

    // e.g. for n == 10 and k == 6 -> {1, 1, 1, 1, 1, 1, 0, 0, 0, 0};
    std::vector<int> flags(n);
    std::fill(flags.begin(), flags.begin() + std::distance(first, last), 1);

    long long int tested = 0;

    do
    {
        // choose the k elements, e.g. for n == 10 and k == 6 -> {0, 1, 2, 3, 4, 5};
        select_if(numbers.begin(), numbers.end(), flags.begin(), first,
                  [] (int x) { return x == 1; });
        do
        {
            ++tested;
            f();
        } while (std::next_permutation(first, last));

    // 'flags' starts sorted in descending order, so I need the previous permutation
    } while (std::prev_permutation(flags.begin(), flags.end())); 

    std::cout << "\nPermutations tested: " << tested << '\n';
}

It finds the same solution traversing all and only the distinct (10! / (10 - 6)!) = 151 200 permutations.

Bob__
  • 12,361
  • 3
  • 28
  • 42
0

An other brute-force way, but limiting the cumber of combinations:

#include <iostream>
#include <algorithm>

int main()
{
    int numbers[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

    int tested_combination_count = 0;
    int total_permutation_count = 0;
    int last_blue = 0;
    do
    {
        int green = numbers[0];
        int yellow = numbers[1];
        int purple = numbers[2];
        int orange = numbers[3];
        int red = numbers[4];
        int blue = numbers[5];

        ++total_permutation_count;
        if (last_blue == blue) {
            continue;
        }
        last_blue = blue;
        ++tested_combination_count;
        if (purple * 10 + green  == green * yellow
            && purple * 10 + orange == red * red
            && yellow * 10 + orange == red * blue
            &&    red * 10 + green  == green * blue) {
            std::cout << green << " " << yellow << " " << purple << " "
                      << orange << " " << red << " " << blue << std::endl;
        }
    } while (std::next_permutation(std::begin(numbers), std::end(numbers)));
    std::cout << "Combination tested:" << tested_combination_count
              << " on a total of " << total_permutation_count << std::endl;
}

Demo

5 3 1 6 4 9
Combination tested 151192 on a total of 3628800
Jarod42
  • 203,559
  • 14
  • 181
  • 302