Я пытаюсь найти шесть значений на основе 4 уравнений

Этот код в настоящее время выходы
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
и т.п.
Я пытаюсь найти правильные значения зеленого, желтого, фиолетового, оранжевого, красного и синего с помощью грубой силы
Эти значения не могут повторяться (т. Е. Если красный = 0, то синий! = 0), но я подумал, что этот код даст мне несколько решений, из которых я мог бы выбрать правильное.
Мой вопрос: что не так с этим?

#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;

}
}

}

}

}

}

}

}

-3

Решение

Если я понял проблему, вы должны выбрать между всеми возможными комбинациями различных значений цвета, которые решают ваши четыре уравнения.

Вложенные циклы в коде OP предоставят (почти, некоторые циклы начинаются с 1) все возможные комбинации, но способ, который исключает дублирующиеся значения, совершенно неверен.

Уравнения также могут быть проверены в одном условии.

Следующий код должен дать ожидаемый результат:

#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';
}

После выполнения выдает:

Зеленый: 5
Желтый: 3
Фиолетовый: 1
Оранжевый: 6
Красный: 4
Синий: 9

Проверенные комбинации: 151200 (из 1000000)
Решения: 1

РЕДАКТИРОВАТЬ

Подстрекаемый Jarod42«s ответ, Я хотел бы показать более эффективное решение, которое использует преимущества стандартной функции библиотеки std::next_permutation (а также std::prev_permutation тоже) и вместо того, чтобы пропускать нежелательные перестановки, напрямую генерирует только нужные.

#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';
}

Он находит то же решение, пересекая все и только различные (10! / (10 — 6)!) = 151 200 перестановок.

1

Другие решения

Другой способ грубой силы, но ограничивающий количество комбинаций:

#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;
}

демонстрация

5 3 1 6 4 9
Combination tested 151192 on a total of 3628800
0

По вопросам рекламы [email protected]