|
Вопрос # 550/ вопрос открыт / |
|
Здравствуйте, уважаемые эксперты!
Делаю программу в делфи по нахождению возможных вариантов решения. Программа сама по себе простая. Дана строка цифр и надо чтоб компьютер произвел над этими цифрами 4 операции или сложение, или вычитание, или умножение, или деление чтобы получить определенную цифру. Например дана строка 123456, а надо получить 10. Решение 1*2+3+4-5+6=10. Исходная строка может быть любой длины. Помогите написать код для вычисления всевозможных решений. Можно конечно самому написать эти решения, но этих же решений может быть тысячи, и каждый вариант описыть это долго. И еще вопрос. У меня каждый элемент массива "a" присваивает каждую цифру из строки.Длина массива 15. Как сделать, если введенная строка меньше 15 элементов чтоб массив сам уменьшился до количества элементов строки. И потом уже производить операции над этими элементами массива. Надеюсь что найдется решение этих вопросов, ведь нет ничего невозможного. За ранее благодарен.
Приложение: Переключить в обычный режим- unit Unit1;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls;
-
-
- type
- TForm1 = class(TForm)
- Edit1: TEdit;
- Label1: TLabel;
- Label2: TLabel;
- Label3: TLabel;
- Button1: TButton;
- Label4: TLabel;
- Label5: TLabel;
- Label6: TLabel;
- Edit2: TEdit;
- procedure Edit1KeyPress(Sender: TObject; var Key: Char);
- procedure Edit2KeyPress(Sender: TObject; var Key: Char);
- procedure Button1Click(Sender: TObject);
- procedure Edit1Exit(Sender: TObject);
- procedure Edit2Exit(Sender: TObject);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
-
- var
- Form1: TForm1;
- a: array[1..15] of integer;
- i,rez,summ: integer;
- implementation
-
- {$R *.dfm}
-
- procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
- begin
-
- Key := #0;
- end;
-
- procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);
- begin
-
- Key := #0;
- end;
-
- procedure TForm1.Button1Click(Sender: TObject);
- begin
-
-
-
-
-
- end;
-
- procedure TForm1.Edit1Exit(Sender: TObject);
- begin
- for i:=1 to 15 do
- begin
-
-
-
- end;
-
- Edit2.SetFocus;
- Button1.Enabled:=true;
- end;
-
- procedure TForm1.Edit2Exit(Sender: TObject);
- begin
-
- end;
-
- end.
 |
Вопрос задал: Курцетов И.А. (статус: Посетитель)
Вопрос отправлен: 4 мая 2007, 12:35
Состояние вопроса: открыт, ответов: 1.
|
Ответ #1. Отвечает эксперт: min@y™
Чтобы массивы были нужной длины, надо использовать динамические массивы. Вот за 15 минут я написал вполне работающий пример такого брутфорса (в приложении). Там как раз используются динамические массивы.
Результат, выдаваемый программой при строке цифр 123456 и ответе 10 такой:
Enter the digits: 123456
Enter the result: 10
//----------------------------------------
1 / 2 + 3 - 4 + 5 + 6 = 10
1 - 2 - 3 / 4 + 5 + 6 = 10
1 * 2 + 3 + 4 - 5 + 6 = 10
1 + 2 + 3 * 4 / 5 + 6 = 10
1 * 2 + 3 * 4 / 5 + 6 = 10
1 * 2 * 3 * 4 / 5 + 6 = 10
1 + 2 * 3 + 4 * 5 / 6 = 10
1 / 2 + 3 * 4 * 5 / 6 = 10
//----------------------------------------
Total equals: 8
Приложение: Переключить в обычный режим- program Q_0550;
-
- {$APPTYPE CONSOLE}
-
- uses
- SysUtils;
-
- type
- TOperation = (opAdd, opSub, opMul, opDiv);
-
- var
-
-
-
-
-
-
-
- function PrepareArrays: Boolean;
- var
- Index: Integer;
- begin
- if Length(Digits) < 2
-
- Result:= False;
- Exit;
- end;
-
-
-
-
- try
- for Index:= 1 to Length(Digits) do
- Values[Index - 1]:= StrToInt(Digits[Index]);
-
- Result:= True;
- except
-
- end;
-
-
- if Result
- then begin
- SetLength(Operations, Length(Digits) - 1);
- FillChar(Operations[0], Length(Operations), opAdd);
- end;
- end;
-
-
- procedure IncOperations;
- var
- Index: Integer;
- begin
- for Index:= 0 to Length(Operations) - 1 do
- begin
- if Operations[Index] <> opDiv
- then Inc(Operations[Index])
- else Operations[Index]:= opAdd;
-
- if Operations[Index] <> opAdd
- then Break;
- end;
- end;
-
-
- function Power4(const APower: Integer): Integer;
- var
- p: Integer;
- begin
- Result:= 4;
- for p:= 2 to APower do
- Result:= Result * 4;
- end;
-
-
- function Operation2Char(const Op: TOperation): Char;
- begin
- case Op of
- opAdd: Result:= '+';
- opSub: Result:= '-';
- opMul: Result:= '*';
- else Result:= '/';
- end; // of case
- end;
-
-
- function CalculateCurrent: Integer;
- var
- Index: Integer;
- begin
- Result:= Values[0];
- for Index:= 1 to Length(Values) - 1 do
- case Operations[Index - 1] of
- opAdd: Result:= Result + Values[Index];
- opSub: Result:= Result - Values[Index];
- opMul: Result:= Result * Values[Index];
- else Result:= Result div Values[Index];
- end; // of case
- end;
-
-
- procedure ResultOut;
- var
- Index: Integer;
- begin
- Write(' ', Values[0]);
- for Index:= 1 to Length(Values) - 1 do
- Write(' ', Operation2Char(Operations[Index - 1]), ' ', Values[Index]);
- WriteLn(' = ', Total: 6);
- end;
-
-
- function CalculateAll: Integer;
- var
- Index, Count: Integer;
- begin
- Result:= 0;
-
- 2 4
- 3 16 = 4^2
- 4 64 = 4^3
- N 4^(N - 1)
- }
-
- Count:= Power4(Length(Values) - 1);
- for Index:= 1 to Count do
- begin
- if CalculateCurrent = Total
- then begin
- ResultOut;
- Inc(Result);
- end;
- IncOperations;
- end;
- end;
-
- begin
- repeat
- Write(' Enter the digits: ');
- ReadLn(Digits);
- until PrepareArrays;
-
- Write(' Enter the result: ');
- ReadLn(Total);
-
- WriteLn('//----------------------------------------');
- Equals:= CalculateAll;
- WriteLn('//----------------------------------------');
- if Equals <> 0
- then WriteLn(' Total equals: ', Equals)
- else WriteLn(' Nothing found :(');
-
- ReadLn;
- end.
-
 |
Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 7 мая 2007, 10:20
|
Мини-форум вопроса
Всего сообщений: 6; последнее сообщение — 5 мая 2007, 17:50; участников в обсуждении: 2.
|
Дмитрий-998 (статус: 1-ый класс), 4 мая 2007, 21:46 [#1]:
Есть вот такой вариант:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
Label1: TLabel;
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure Edit2KeyPress(Sender: TObject; var Key: Char);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TMyThread = class(TThread)
private
Num: Array of Integer;
Ch: Array of Char;
NotFind: Boolean;
procedure UpdateLabel;
protected
procedure Execute; override;
end;
var
Form1: TForm1;
MyThread: TMyThread;
implementation
{$R *.dfm}
procedure TMyThread.UpdateLabel;
var
Str: String;
I: Integer;
begin
Str:= IntToStr(Num[0]);
For I:= 0 to Length(Ch) - 1 do
Str:= Str + (Ch[I] + IntToStr(Num[I+1]));
if not NotFind then
Form1.Label1.Caption:= 'Результат равен: ' + Str
else Form1.Label1.Caption:= 'Вариант не найден!'
end;
procedure TMyThread.Execute;
var
Res: Integer;
Tmp: Integer;
Str: String;
CountNum, I: Integer;
procedure Change;
var
J: Integer;
begin
For J:= CountNum-1 downto 0 do
begin
if Ch[J] = '+' then
begin
Ch[J]:= '-';
Break;
end;
if Ch[J] = '-' then
begin
Ch[J]:= '/';
Break;
end;
if Ch[J] = '/' then
begin
Ch[J]:= '*';
Break;
end;
if Ch[J] = '*' then
begin
if J = 0 then NotFind:= True;
Ch[J]:= '+';
end;
end;
end;
begin
NotFind:= false;
Str:= Form1.Edit1.Text;
Res:= StrToInt(Form1.Edit2.Text);
CountNum:= Length(Str);
SetLength(Num, CountNum);
Dec(CountNum);
SetLength(Ch, CountNum);
For I:= 0 to CountNum do
Num:= StrToInt(Str[I+1]);
For I:= 0 to CountNum do
Ch:= '+';
repeat
Tmp:= Num[0];
for I:= 1 to CountNum do
begin
if Ch[I-1] = '+' then
Tmp:= Tmp + Num;
if Ch[I-1] = '-' then
Tmp:= Tmp - Num;
if Ch[I-1] = '/' then
Tmp:= Tmp div Num;
if Ch[I-1] = '*' then
Tmp:= Tmp * Num;
end;
if Tmp <> Res then Change;
// Sleep(100);
Synchronize(UpdateLabel);
until (Tmp = Res) or (NotFind);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
MyThread:= TMyThread.Create(false);
end;
end.
|
|
Курцетов И.А. (статус: Посетитель), 5 мая 2007, 08:26 [#2]:
Спасибо за код, но этот код выдает неправильные ответы, ну главное смысл как описать эти варианты понятен. Постараюсь доработать этот код, правда пока не все понимаю в нем. Буду разбираться в нем.
|
|
Дмитрий-998 (статус: 1-ый класс), 5 мая 2007, 08:42 [#3]:
В программе используется второй процесс, во избежании зависания основной программы, во время просчета, вы можете раздокументировать функцию Sleep для того чтоб видеть как он перебирает варианты...
|
|
Курцетов И.А. (статус: Посетитель), 5 мая 2007, 09:28 [#4]:
Прошу прощения за предыдущий ответ, программа работает, не все варианты правильные выдает.Я думаю убрать деление т.к. в некоторых случаях при делении программы выделяет только целую часть. А это неподходит для меня. Точнее для ребенка не подойдет. И я ща столкнулся с таким вариантом деления на 0, и сразу это вызвало ошибку, так что я лучше уберу деление. А так спасибо Вам. Если бы можно было этот ответ оценить, я бы поставил вам 5. Спасибо.
|
|
Курцетов И.А. (статус: Посетитель), 5 мая 2007, 09:32 [#5]:
Еще я думаю добавить в эту программу несколько вариантов, это соединение строк. Например 123456
чтобы не только программа брала отдельно цифры 1 или 2 или 3, а 12+3 уже или 23+4 и т.д. Но думаю уже сам справлюсь. Ведь основной код уже написан.
|
|
Дмитрий-998 (статус: 1-ый класс), 5 мая 2007, 17:50 [#6]:
Спасибо за оценку, код был написан за пять минут, поэтому нет проверок на ошибки, такие как деление на ноль, а для чисел с плавующей точкой используйте вычисление в нутри команды ROUND...
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|