Необходмио перечислить все возможные формулы произвольного размера, используются цифры 0, 1, 2, переменная x иоперации -, +, *, а также скобки. Размер выражения - число использованных операций. Например, формулы размера 1: 0+1, x*2, размера 4: x*x+2*x+1, (1+x)*1*2+0
Удалось сделать только "статически" и без скобок. Как это возможно реализовать в "движении" ??
https://repl.it/repls/AntiqueHoneydewCharactermapping //код и тамже можно выполнить его
using System;
using System.Linq;
class MainClass {
public static bool onlyOneVariable(params char[] values) => values.Count(char.IsLetter) == 1;
public static void Main (string[] args) {
var formulas = (
from num1 in new[] { '0', '1', '2', 'X' }
from num2 in new[] { '0', '1', '2', 'X' }
from op1 in new[] { '-', '+', '*' }
where onlyOneVariable(num1, num2)
select $"{num1} {op1} {num2} "
);
foreach(var formula in formulas.Take(10)) {
Console.WriteLine(formula);
}
}
}
Рассмотрим часть задачи, где надо только сегенерировать формулы, без проверки уникальности и скобочек.
Бинарная операция, которыми являются +, - и *, всегда содержат левую сторону, правую и операнд. Например, x+1, где x -левая, 1- правая, + - операнд.
Предположим, что мы строим уравнение, и у нас уже есть левая сторона и операнд, например x+, тогда осталось добавить к нему правую сторону, которая может либо закончить выражение, например x+1, либо оставить его незаконченным, чтобы можно было операцию по добавлению правой сторны повторить x+1+.
Отсюда появляется рекурсивная функция. Я добавли только отслеживание уже использованных операций и операнодов, чтобы они в формулах не дублировались
public IEnumerable<string> GetFormulas(string[] operands, string[] operators,
bool[] operandsUsed, bool[] operatorsUsed,
int operCount, List<string> states)
{
if (operCount == 0)
{
for (int i=0; i<operands.Length; i++)
{
if (operandsUsed[i]) continue;
var oper = operands[i];
var sb = new StringBuilder();
foreach (var state in states) sb.Append(state);
sb.Append(oper);
yield return sb.ToString();
}
}
else
{
for (int j=0; j<operators.Length; j++)
{
if (operatorsUsed[j]) continue;
var op = operators[j];
for (int i=0; i<operands.Length; i++)
{
if (operandsUsed[i]) continue;
var oper = operands[i];
operandsUsed[i] = true;
operatorsUsed[j] = true;
states.Add(oper);
states.Add(op);
foreach(var f in GetFormulas(operands, operators,operandsUsed, operatorsUsed, operCount-1, states))
yield return f;
operandsUsed[i] = false;
operatorsUsed[j] = false;
states.RemoveAt(states.Count-1);
states.RemoveAt(states.Count-1);
}
}
}
}
Как использовать:
var operands = new[] { "0", "1", "2", "X" };
var operators = new[] { "+", "-", "*" };
var L = 1;
foreach (var f in GetFormulas(operands,operators,
new bool[operands.Length], new bool[operators.Length],
L, new List<string>()))
Console.WriteLine(f);
Где L - может принимать значение от 0 до 3, так как у нас только максимум 3 не повторяющихся оператора.
Пример вывода:
0+1
0+2
0+X
1+0
1+2
1+X
2+0
2+1
2+X
X+0
X+1
X+2
0-1
0-2
0-X
1-0
1-2
1-X
2-0
2-1
2-X
X-0
X-1
X-2
0*1
0*2
0*X
1*0
1*2
1*X
2*0
2*1
2*X
X*0
X*1
X*2
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости