Как и мой школьный проект, мне нужно построить решатель для раундов Countdown Numbers & Letters. Я хотел разработать структуру, которую я мог бы использовать для создания обоих решателей, и сначала я разработал решатель Numbers. Однако, прежде чем использовать это решение для писем, мне нужно улучшить мой текущий алгоритм. Я думаю, что где-то не прав, потому что я не получаю те же результаты с другими инструментами, которые я использую для сравнения моей программы. Вот программа для моего решателя:
/// numbers_game_solver.dart
import 'dart:collection';
import 'package:trotter/trotter.dart';
/* Import statements was package-based, I turned them into relative paths for question. */
import 'number_generator.dart';
import 'operation.dart';
import 'solution.dart';
import 'solutions.dart';
/* Will try to combine numbers with operations, as shown below;
* List<List<Operation>> operations = <Operations>[a, ,b, ,c, ,d, ,e, ,f
* + - + * / ]
* Then if last operations result is equal to target, will result it.
* If not will show closest result.
*/
const List<String> kOperators = const <String>[kOpAdd, kOpDiv, kOpMul, kOpSub];
class NumbersGameSolver {
NumbersGameSolver()
: this.solutions = Solutions(_expectedResult);
/* TODO: Do tests with smaller numbers and targets. */
final List<int> _numbers = const <int>[1, 2, 3, 4]; // NumberGenerator.numbers;
static final int _expectedResult = 15; //NumberGenerator.expectedResult;
final Solutions solutions;
void solve() {
/* All permutations of operators with replacement, which will be inserted between numbers. */
final Set<List<String>> amalgamsOperators = Amalgams<String>(_numbers.length - 1, kOperators)().toSet();
/* There may duplicates occur in numbers list, because of this, numbers will be mapped
using permutations of indices. */
final List<int> indices = List<int>.generate(_numbers.length, (int index) => index);
final Iterable<List<int>> permutationsIndices = Permutations<int>(indices.length, indices)();
final Set<List<int>>
permutationsNumbers = permutationsIndices.map(
(List<int> listPerm) => listPerm.map(
(int index) => _numbers[index]
).toList()
).toSet();
for (final List<int> numbers in permutationsNumbers) {
for (final List<String> operators in amalgamsOperators) {
Queue<int> stackNums = Queue<int>.from(numbers);
Queue<String> stackOprts = Queue<String>.from(operators);
Solution tempSolution = Solution(_expectedResult);
do {
int left = stackNums.removeFirst(), right = stackNums.removeFirst();
Operation tempOperation = Operation(stackOprts.removeFirst(), left, right);
/* Record solutions current state. */
SolutionState solutionState = tempSolution.addOperation(tempOperation);
if (solutionState == SolutionState.currentlyValid) {
/* If valid, add result to the current numbers stack. */
stackNums.addFirst(tempOperation.result);
} else if (solutionState == SolutionState.lastOperationRedundant) {
/* If operation is redundant, dispose it and continue. */
continue;
} else if (solutionState == SolutionState.lastResultInvalid) {
/* If results is invalid at any stage, dispose whole solution. */
break;
}
if (solutions.addSolution(tempSolution) == true) break;
} while (stackNums.length > 1);
}
}
/* Will show only accurate solutions.
* If there is no accurate solutions, will show solutions which results
* are closest to the expected result.
*/
solutions.showSolutions();
}
}
Есть 5 классов, чтобы сократить вопрос, я добавил их в этом Суть .
Мой алгоритм следующий:
- Правила для этого проекта таковы; Программа должна случайным образом сгенерировать 5 одиночных чисел di git и 1 двух чисел di git, где
twoDigitNumber % 10 == 0
и число трех di git в виде target . - Я получаю перестановки 4 оператора и числа, которые будут использоваться в операциях ( Использование пакета trotter . )
- Для каждой перестановки чисел я применяю каждую перестановку операторов; используя класс
Operation
и добавляя их в экземпляр Solution
для каждой перестановки. - Я пропускаю некоторые избыточные операции в каждой итерации, и если на каком-либо этапе есть недопустимый результат, я распоряжаюсь этим решением и продолжаю , (я беру этот блог DataGenetics об этой топике c в качестве ссылки.)
Чтобы проверить мой алгоритм, я использовал числа 1, 2, 3, 4
и установите цель как 15
. Результаты dcode.fr Solver такие, как есть;
15 (2 op.)
4 + 1 = 5
5 x 3 = 15
15 (3 op.)
4 + 3 = 7
7 x 2 = 14
14 + 1 = 15
15 (3 op.)
4 x 3 = 12
12 + 2 = 14
14 + 1 = 15
15 (3 op.)
4 x 3 = 12
2 + 1 = 3
12 + 3 = 15
15 (3 op.)
3 + 2 = 5
4 - 1 = 3
5 x 3 = 15
15 (3 op.)
4 x 3 = 12
12 + 1 = 13
13 + 2 = 15
15 (3 op.)
4 - 1 = 3
3 + 2 = 5
5 x 3 = 15
15 (3 op.)
4 + 2 = 6
6 - 1 = 5
5 x 3 = 15
15 (3 op.)
2 + 1 = 3
4 x 3 = 12
12 + 3 = 15
15 (3 op.)
2 - 1 = 1
4 + 1 = 5
5 x 3 = 15
(A total of 10 solutions.)
и решения, найденные моей программой, как есть;
> SOLUTION 1 ~
4 - 1 = 3
3 + 2 = 5
5 x 3 = 15
> SOLUTION 2 ~
4 + 1 = 5
5 x 3 = 15
(A total of 2 solutions.)
Можете ли вы скажи мне, что я неправильно думаю; Почему я не могу найти все решения? Какие альтернативные подходы я могу использовать для решения этой проблемы? Я что-то упускаю?
TY за то, что нашли время.