С точки зрения функционального программирования PascalABC.NET - плохой язык. Однако, некоторые идеи, тем не менее, могут быть реализованы в функциональном стиле. На них и остановимся.
В качестве объекта изложения возьмем алгоритм получения следующего числа в цепочке в задаче 74 из проекта Эйлера.
Каждый следующий член цепочки получается из предыдущего как сумма факториалов его цифр:
1!+6!+9! =363601
169 363601
1454
169
Вначале разобьём целое на массив цифр. Сделаем это с помощью метода расширения для integer. Алгоритм - безобразно неоптимальный:
type IntArray = array of integer; function integer.ToDigits(): IntArray; begin var s := Self.ToString(); SetLength(Result,s.Length); for var i := 1 to s.Length do Result[i-1] := OrdUnicode(s[i])-OrdUnicode('0'); end;
Для массива целых составим метод расширения, вычисляющий сумму элементов:
function IntArray.Sum(): integer; begin Result := 0; for var i := 0 to Self.Length-1 do Result += Self[i]; end;
Для вывода массива целых на экран расширим его тип методом Print:
procedure IntArray.Print; begin for var i := 0 to Self.Length-1 do write(Self[i],' '); end;
Наконец, напишем метод расширения для преобразования массива целых в массив целых, воздействуя на каждый элемент функцией, передаваемой в качестве параметра:
type IntFun = function (i: integer): integer; function IntArray.Map(f: IntFun): IntArray; begin SetLength(Result,Self.Length); for var i := 0 to Self.Length-1 do Result[i] := f(Self[i]); end;
Проверяем:
function fact(n: integer): integer; begin Result := 1; for var i:=1 to n do Result *= i; end; begin var i := 145; writeln(i.ToDigits().Map(fact).Sum()); end.
Выводится 145 (145=1!+4!+5!)
Выведем 4 члена цепочки, начинающейся со 169. Для этого реализуем функцию перехода к следующему элементу:
function Next(i: integer): integer; begin Result := i.ToDigits().Map(fact).Sum(); end;
Наконец, реализуем для данного целого функцию получения цепочки целых с указанной функцией перехода к следующему элементу:
function integer.Take(f: IntFun; n: integer): IntArray; begin SetLength(Result,n); Result[0] := Self; for var i:=1 to n-1 do Result[i] := f(Result[i-1]); end;
Пробуем:
begin var i := 169; i.Take(Next,4).Print(); end.
Получаем цепочку из 4 элементов:
169 363601 1454 169
К сожалению, код не столь красив ввиду отсутствия в PascalABC.NET полноценной реализации лямбда-функций.
20.02.25. 28 – 29 марта 2025 г. Институт математики механики и компьютерных наук ЮФУ проводит пятую онлайн Всероссийскую научно-методическую конференцию «Использование системы программирования PascalABC.NET в обучении программированию». Зарегистрироваться на конференцию можно здесь.
16.02.25 состоялась первая олимпиада на языке программирования PascalABC.NET среди учеников компьютерной школы мехмата ЮФУ. Опубликованы разбор задач 1 ступени и разбор задач 2 ступени.
07.01.25. Опубликован обзор языка Learn PascalABC.NET in Y minutes.
02.01.25. Вышла версия PascalABC.NET 3.10.2. Основное: константы [1,2,3] по умолчанию считаются массивами.
26.11.24. Вышла версия PascalABC.NET 3.10.1. Основное: новая эффективная реализация встроенных множеств set of T.