{+--------------------------------------------------------------------------+}
{| The Textbook in Data Structure, Algorithms and Programming |}
{| http://w...content-available-to-author-only...c.jp/~hoangle/DSAPTextbook/ |}
{| |}
{| Program: Finding_the_Minimum_Spanning_Tree_using_Kruskal_Algorithm |}
{| Written by Le Minh Hoang |}
{| Email: dsaptextbook@gmail.com |}
{+--------------------------------------------------------------------------+}
program KursovayaPOA_Variant28; // (объявляет имя консольной программы по варианту 28)
{$APPTYPE CONSOLE} // (указывает компилятору Delphi, что приложение является консольным)
uses // (начинает раздел подключения стандартных модулей)
SysUtils, Math; // (подключает служебные средства и математические функции, включая ArcTan2)
const // (начинает раздел постоянных величин)
PiGrad = 180 / Pi; // (задает коэффициент перевода радиан в градусы)
procedure PrintLine; // (объявляет процедуру вывода разделительной линии)
begin // (начинает тело процедуры PrintLine)
Writeln('------------------------------------------------------------'); // (выводит на экран строку-разделитель)
end; // (завершает процедуру PrintLine)
procedure PrintMenu; // (объявляет процедуру вывода главного меню)
begin // (начинает тело процедуры PrintMenu)
PrintLine; // (вызывает вывод разделительной линии перед меню)
Writeln('КУРСОВАЯ РАБОТА. Вариант 28'); // (выводит название работы и номер варианта)
Writeln('1 - Задача 1: сумма цифр введенного числа'); // (выводит пункт меню для запуска первой задачи)
Writeln('2 - Задача 2: сравнение углов AO и BO с осью OX'); // (выводит пункт меню для запуска второй задачи)
Writeln('0 - Выход'); // (выводит пункт меню для завершения программы)
PrintLine; // (выводит разделительную линию после списка пунктов)
Write('Выберите пункт меню: '); // (приглашает пользователя ввести номер пункта меню)
end; // (завершает процедуру PrintMenu)
procedure Task1; // (объявляет процедуру решения первой задачи)
var // (начинает раздел локальных переменных первой задачи)
N, Temp, Sum, Digit: Integer; // (объявляет исходное число, рабочую копию, сумму цифр и текущую цифру)
begin // (начинает тело процедуры Task1)
Writeln; // (выводит пустую строку для отделения результата от меню)
Writeln('Задача 1. Нахождение суммы цифр введенного числа.'); // (выводит пояснение о выполняемой задаче)
Write('Введите целое число N: '); // (просит пользователя ввести целое число)
Readln(N); // (считывает введенное число в переменную N)
Temp := Abs(N); // (получает модуль числа, чтобы корректно обработать отрицательный ввод)
Sum := 0; // (обнуляет накопитель суммы цифр)
while Temp > 0 do // (организует цикл обработки цифр, пока рабочее число больше нуля)
begin // (начинает тело цикла while)
Digit := Temp mod 10; // (получает последнюю цифру числа)
Sum := Sum + Digit; // (добавляет найденную цифру к общей сумме)
Temp := Temp div 10; // (удаляет последнюю цифру из рабочего числа)
end; // (завершает тело цикла while)
Writeln('Сумма цифр числа ', N, ' = ', Sum); // (выводит исходное число и найденную сумму цифр)
Writeln; // (выводит пустую строку после результата)
end; // (завершает процедуру Task1)
procedure CalculateAngle(X, Y: Real; var AngleRad, AngleDeg: Real); // (объявляет вспомогательную процедуру вычисления угла точки с осью OX)
begin // (начинает тело процедуры CalculateAngle)
if (X = 0) and (Y = 0) then // (проверяет, совпадает ли точка с началом координат)
AngleRad := 0 // (при совпадении с началом координат принимает угол равным нулю)
else // (задает ветвь для обычной точки, не совпадающей с началом координат)
AngleRad := ArcTan2(Abs(Y), Abs(X)); // (вычисляет острый угол отрезка с осью OX в радианах)
AngleDeg := AngleRad * PiGrad; // (переводит угол из радиан в градусы)
end; // (завершает процедуру CalculateAngle)
procedure Task2; // (объявляет процедуру решения второй задачи)
var // (начинает раздел локальных переменных второй задачи)
X1, Y1, X2, Y2: Real; // (объявляет координаты точек A и B)
AngleA, AngleB, DegA, DegB: Real; // (объявляет углы в радианах и градусах для отрезков AO и BO)
begin // (начинает тело процедуры Task2)
Writeln; // (выводит пустую строку для отделения задачи от меню)
Writeln('Задача 2. Сравнение углов отрезков AO и BO с осью OX.'); // (выводит пояснение о выполняемой задаче)
Write('Введите x1 для точки A: '); // (просит ввести координату x1 точки A)
Readln(X1); // (считывает координату x1)
Write('Введите y1 для точки A: '); // (просит ввести координату y1 точки A)
Readln(Y1); // (считывает координату y1)
Write('Введите x2 для точки B: '); // (просит ввести координату x2 точки B)
Readln(X2); // (считывает координату x2)
Write('Введите y2 для точки B: '); // (просит ввести координату y2 точки B)
Readln(Y2); // (считывает координату y2)
CalculateAngle(X1, Y1, AngleA, DegA); // (вычисляет угол отрезка AO с осью OX)
CalculateAngle(X2, Y2, AngleB, DegB); // (вычисляет угол отрезка BO с осью OX)
Writeln('Угол AO с осью OX = ', DegA:0:2, ' град.'); // (выводит угол отрезка AO в градусах)
Writeln('Угол BO с осью OX = ', DegB:0:2, ' град.'); // (выводит угол отрезка BO в градусах)
if Abs(AngleA - AngleB) < 1E-10 then // (проверяет равенство углов с учетом погрешности вещественных вычислений)
Writeln('Отрезки AO и BO образуют равные углы с осью OX.') // (выводит сообщение, если углы равны)
else // (задает ветвь для случая, когда углы различаются)
if AngleA > AngleB then // (проверяет, больше ли угол отрезка AO)
Writeln('Больший угол с осью OX образует отрезок AO.') // (выводит результат, если больше угол AO)
else // (задает ветвь для случая, когда больше угол BO)
Writeln('Больший угол с осью OX образует отрезок BO.'); // (выводит результат, если больше угол BO)
Writeln; // (выводит пустую строку после результата)
end; // (завершает процедуру Task2)
var // (начинает раздел глобальных переменных главной программы)
Choice: Integer; // (объявляет переменную для хранения выбранного пункта меню)
begin // (начинает главную часть программы)
repeat // (начинает цикл повторного показа меню)
PrintMenu; // (выводит главное меню)
Readln(Choice); // (считывает выбранный пользователем пункт меню)
case Choice of // (начинает оператор выбора действия по введенному пункту)
1: Task1; // (запускает первую задачу при выборе пункта 1)
2: Task2; // (запускает вторую задачу при выборе пункта 2)
0: Writeln('Работа программы завершена.'); // (выводит сообщение о завершении при выборе пункта 0)
else // (задает действие при неверном пункте меню)
Writeln('Ошибка: выбран неверный пункт меню. Повторите ввод.'); // (сообщает пользователю об ошибочном выборе)
end; // (завершает оператор case)
until Choice = 0; // (повторяет меню до тех пор, пока пользователь не выберет выход)
Writeln('Нажмите Enter для выхода...'); // (выводит финальное приглашение перед закрытием окна)
Readln; // (ожидает нажатия Enter)
end. // (завершает исходный текст программы)