Он в этом режиме достаточно давно уже почти ничего не видит. Но со временем починят, думаю, это сейчас не самое главное.
А это кстати вообще не правда, я только сейчас понял - в паскале адрес это @
, а &
к адресам относится только в Си-подобных языках.
Вот и поговорили, вот и славно! )))
А, да, точно ))
Исправили
Предлагаю в стандартную библиотеку добавить кэш для мемоизации:
unit memoization;
type fCache<T,R> = class
private
cache: Dictionary<T,R>;
f: Func<T,R>;
procedure setValue(key:T;value:R) := cache[key] := value;
function getValue(key:T):R; begin
if not cache.TryGetValue(key, Result) then begin
Result := f(key);
cache[key] := Result;
end;
end;
public
constructor(f:Func<T,R>); begin
cache := new Dictionary<T,R>;
Self.f := f;
end;
property Values[key:T]:R read getValue write setValue; default;
end;
end.
вызывать можно так:
uses memoization;
function fib(n:integer):integer;forward; // OldPascal-костыль
var fibC := new fCache<integer,integer>(fib); // кэш
// ^^^^^^^ ^^^^^^^ нужен вывод типов
function fib(n:integer):integer :=
n=0 ? 0 :
n<=2 ? 1 :
fibC[n-1] + fibC[n-2]; // << вызов через кэш
begin
(0..46).Select(n->fib(n)).Print
end.
Обсуждение подходящего имени класса приветствуется
PS: я правильно понимаю, что этот код нужно писать из-за однопроходности компилятора, т.е. оптимизации под К580ВМ80?
function fib(n:integer):integer;forward; // OldPascal-костыль
var fibC := new fCache<integer,integer>(fib); // кэш
// ^^^^^^^ ^^^^^^^ нужен вывод типов
и чтобы написать так:
var fibC := new fCache(fib); // кэш
function fib(n:integer):integer := ...
нужно менять архитектуру компилятора?
Вообще в идеале - сделать так:
uses memoization;
begin
var c := new fCache<integer, integer>(n->
n=0 ? 0 :
n<=2 ? 1 :
c[n-2] + c[n-1]
);
end.
Но сейчас компилятор не видит объявляемую переменную в лямбде, хотя её и вполне реально захватить. Не помню, был ли уже про это разговор… @Admin?
Ну а следующий лучший вариант это:
uses memoization;
begin
var c: fCache<integer, integer>;
c := new fCache<integer, integer>(n->
n=0 ? 0 :
n<=2 ? 1 :
c[n-2] + c[n-1]
);
(0..46).Select(n->c[n]).Println;
end.
Да и, не могу не заметить, словарь из хеш-множества в данном случае совсем не подходит. Он эффективен когда хеш-коды ключей расположены не только равномерно, но и псевдо-случайно, иначе создание множества это лишняя работа.
Раз все числа (и равные им хеш-коды) идут последовательно - числа фибоначи это плохой пример для такого кэша. Их лучше сохранять в List<>
.
Более хорошим примером будет, к примеру, любая задача где ключи - строки.
Вот такой пример есть. Это солвер для 19-21 ЕГЭ (Теория Игр). Для него и делалось. В качестве ключа используется кортеж двух целых
uses memoization;
type int2=(integer,integer);int=integer;
function moves(a,b:int):=|(a+1,b),(2*a,b),(a,b+1),(a,2*b)|;
function moves(heap:int2):=moves(heap[0],heap[1]);
function f(heap:int2):int;forward;
var fc := new fCache<int2,int>(f);
function f(heap:int2):int; begin
if (heap[0]+heap[1]<100) then begin
var codes := moves(heap)
.Select(el->fc[el]);
Result := 1 + if codes.Any(el->el.IsEven)
then codes.Where(el->el.IsEven).Min
else codes.Max;
end;
end;
begin
Range(90,1,-1).PrintLines(s->$'{s} : {f((9,s))}');
end.
А можно, пожалуйста, текст задачи?
не нашел именно эту задачу, но похожа на https://kpolyakov.spb.ru/school/ege/gen.php?action=viewTopic&topicId=3188 и солвер не полный. Далее нужно еще код дописывать. Этот солвер находит за сколько ходов можно выиграть (четные) или проиграть (нечетны значения функции).
Это глюк IDE. Попробуйте Shift+F9 запускать. Не будет. Или нумерацию добавить в вывод и будет разрыв в разных местах.
Вот от этого меня уже разработчики отучили. Как только скажешь, что какая-то вещь нужна для конкретной задачи - сразу же следует возражение - и тут не могу ничего возразить в ответ - что неправильно решать частные проблемы посредством системных библиотек…
Механизм мемоизации фундаментальный. Его много где можно использовать. И предложенный класс достаточно универсальный и удобный.
Я отнюдь не утверждаю, что это все не нужно. Я лишь советую не напирать на то, что “Для него и делалось”, потому что это выглядит как частное решение.
Есть много фундаментальных вещей. Например, красно-чёрные деревья.
Для подобных вещей необходимо решить следующие вопросы:
- В каком модуле их описать
- Что ещё в этом модуле будет
Модуль ради одного класса делать - странно
У картинки гиперссылка неправильная.