Необходмио перечислить все возможные формулы произвольного размера, используются цифры 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
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Задание: В каждой нечетной строке ступенчатой матрице найти произведение элементовВыбрать отрицательные и посчитать их количество, если...
В компоненте Rigidbody2D есть такой параметр как Gravity Scale каким образом он влияет на глобальный компонент гравитации? Те
Можно ли обойтись без методов типа Update что бы заставить кнопку "назад" вызывать какой либо метод? Хотелось бы обойтись без постоянного вызова...