Египетские пирамиды в Delphi

Компьютер — страшная сила!

Программистская банальность


Всё врут календари.

А.  С. Грибоедов. Горе от ума

 

Пирамиды - большая загадка для всего человечества, нам, конечно, её не решить даже с помощью компьютера, но в мире есть и другие причудли­вые пирамиды, - например, числовые!

В довольно увесистой книге GehirnJogging под номером 147 можно найти вот такую задачу:

Египетские пирамиды в Delphi

Условие таково: в основании пирамиды находятся все числа от 1 до 6, найти числа в пустых клетках, если каждое число, опирающееся на два нижних, равно их сумме.

 

Ясно, что в клетке над двойкой и пятёркой стоит число 2 + 5 = 7:

Египетские пирамиды в Delphi

Что делать? - Либо думать, либо писать программу. Лень - двигатель про­гресса, поэтому мы напишем программу, которая решит не только эту за­дачу, но и все подобные.

Интерфейс собираем, не мудрствуя лукаво, на один раз любой сгодится:

Египетские пирамиды в Delphi

Результаты наших поисков выводим в список lstProtokol. Магическая кнопка sbtSolveнаходит все перестановки чисел 1, 2, 3, 4, 5, 6 в основании пирамиды, а также сумму, которая получается при этом в её вершине. За­тем список сохраняем на диске, ублажив курсором кнопку sbtSaveProtokol.

 

Перестановки чисел будем искать грубой силой, без поиска изящных алго­ритмов:

procedure TfrmMain.sbtSolveClick(Sender: TObject);

 

var

 

a1,a2,a3,a4,a5,a6,f: integer;

 

s: string;

 

begin

 

lstProtokol.Items.clear;

 

for a1:= 1 to 6 do begin

 

for a2:= 1 to 6 do begin

 

if a2=a1 then continue;

 

for a3:= 1 to 6 do begin

 

if (a3=a2) or (a3=a1) then continue;

 

for a4:= 1 to 6 do begin

 

if (a4=a3) or (a4=a2) or (a4=a1)then continue;

for a5:= 1 to 6 do begin

 

if (a5=a4) or (a5=a3) or (a5=a2) or (a5=

 

nue;

 

for a6:= 1 to 6 do begin

 

if (a6=a5) or (a6=a4) or (a6=a3)

 

(a6=a1)then continue;

 

f:= a1 + a6 + 5*(a2+a5) + 10*(a3+a4);

о . — f 1 

 

s:= ;

if f < 100 then s:= s + '0';

 

s:= s+ inttostr(f)+' = '+ inttostr

 

tostr(a2)+' '+ inttostr(a3)+' '+ inttostr(a4)+' '+

 

'+ inttostr(a6);

 

lstProtokol.Items.add(s);

 

end;

 

end;

 

end;

 

end;

 

end;

 

end;

 

end;

 

 

На деле это выглядит так. В основании стоят 6 чисел от единицы до ше­стёрки, причём числа не повторяются. Значит, выписываем 6 вложенных циклов forи в каждом проверяем это условие. Если параметр цикла равен уже вышедшему ранее числу, то проверяем следующее (вот и процедура continueпригодилась!). Как только мы нашли очередную расстановку (шесть разных чисел в основании), вычисляем по правилам задачи сумму в вершине пирамиды:

f:= a1 + a6 + 5*(a2+a5) + 10*(a3+a4);

Хотите верьте, хотите нет, но она именно такая (посчитайте сами!) 

Египетские пирамиды в Delphi

Осталось красиво записать найденный вариант расстановки чисел и сумму в окно протокола.

К сожалению, в этом списке очень неудобно отыскивать нужную нам сум­му в вершине. Но мы не будем утруждать себя сортировкой вариантов по возрастанию суммы, а просто запишем список в текстовый файл protokol.TXT:


//ЗАПИСАТЬ ПРОТОКОЛ НА ДИСК
procedureTfrmMain.sbtSaveProtokolClick(Sender: TObject);
var
s,fn: string; i: integer; f: textfile; begin
//savedialog1.DefaultExt:='txt'; savedialog1.Filter:=’Solutions (*.txt)|*.TXT’; savedialog1.FilterIndex:=1;
s:=extractfilepath(application.exename)+'solutions'; savedialog1.InitialDir:= s;
savedialog1.Title:=’Save the solution to the disk’;
//имя файла:
savedialog1.filename:=’protokol temp.txt’;
if not savedialog1.Execute then exit;
//имя конечного файла: fn:= savedialog1.filename; assignfile(f,fn);
if FileExists(savedialog1.filename) then
append(f)       //-  добавить информацию     в конец файла
else rewrite(f); //- перезаписать файл
//записать протокол:
for i:=0 to (lstProtokol.Items.Count - 1) do writeln (f,lstProtokol.Items.Strings);
Closefile(f);
Messagebeep(0) end;

 

А затем откроем его в текстовом редакторе MicrosoftWord, отсортируем его и получим список protokol.doc, в котором легко найти нужное нам число в вершине пирамиды:

095     = 4 2 1 5   3    6

095     = 4 2 5 1   3    6

095     = 4 3 1 5   2    6

095     = 4 3 5 1   2    6

095     = 6 2 1 5   3    4

095     = 6 2 5 1   3    4 

095     = 6 3 1 5   2    4

Всего можно насчитать 8 расстановок шести чисел, которые дают сумму 95, но нас интересуют только те, в которых двойка и пятёрка стоят на вто­ром и третьем местах. И что мы видим: годятся две расстановки:

095 = 4 2 5 1 3 6 095 = 6 2 5 1 3 4,

значит, и решений у задачи тоже два.

Смотрим в ответ - одно.

Не верьте толстым книгам!

В книге ещё много таких задач, но мы их решили все разом и даже под­кузьмили незадачливого немецкого автора, который не удосужился поис­кать и второе решение 

Египетские пирамиды в Delphi

 

И не надейтесь, что я написал всю программу с нуля! Компонент со спис­ком, кнопки, процедуру записи списка в файл я благополучно экспортиро­вал (легально!) из других своих программ. Добавить пришлось только не­замысловатую процедуру составления списка вариантов - по времени дольше объяснять, чем «соорудить» такую программу.

������� ������ ��� dle ������� ��������� ������

Помоги проекту! Расскажи друзьям об этом сайте: