С точки зрения функционального программирования 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 полноценной реализации лямбда-функций.
26.11.24. Вышла версия PascalABC.NET 3.10.1. Основное: новая эффективная реализация встроенных множеств set of T.
27.08.24. Вышла версия PascalABC.NET 3.10.0. Список изменений - здесь.
01.02.24. На ресурсе Stepik в ознакомительном режиме открыт курс "PascalАВС.NЕТ: продвинутый уровень".
10.07.23. Вышел релиз версии PascalABC.NET 3.9.0. Нововведения описаны здесь.
20.05.23. На странице https://pascalabc.net/stepikcourse опубликованы новые курсы по PascalABC.NET от центра олимпиадного программирования DL Club.