Как работает тест Кнута «Мужчина или мальчик»? - PullRequest
5 голосов
/ 17 ноября 2009

Может кто-нибудь объяснить, как Тест на мужчину или мальчика возвращает значение -67?
Я тщетно пытался записать результат или отследить его с помощью отладчика. Любая помощь будет оценена.
Список различных реализаций можно найти здесь .

1 Ответ

3 голосов
/ 30 июля 2011

Это хорошая страница об этом тесте для мужчины или мальчика. Здесь показаны следующие интересные факты:

k = 10: A = -67 и A вызывается 722 раза, B вызывается (A - 1) раз.

Запись полной calltrace в этом случае немного бесполезна, так как функция рекурсивная по своей природе, с добавлением, что функции не pure (как вы можете видеть в в переводе на Haskell требуется использование монад STate, обернутых вокруг k, для предотвращения загрязнения: область действия каждой функции (в данном случае переменная k: она уменьшается на единицу) модифицируется при каждом вызове или рекурсии и эти модификации необходимы для расчета правильного ответа.

Я считаю перевод JavaScript более читабельным, чем оригинальная реализация ALGOL60:

function A(k, x1, x2, x3, x4, x5) { 
    function B() {
        return A(--k, B, x1, x2, x3, x4);
    }
    return k <= 0 ? x4() + x5() : B();
} 
function K(n) { return function() {return n}; }
alert(A(10, K(1), K(-1), K(-1), K(1), K(0)));

Хитрость заключается в бухгалтерском учете: какие ссылки на функции вызывают, какие побочные эффекты (изменение переменных) и в терминах вызывают правильную оценку функции. Однако эта бухгалтерия утомительна, как я объяснил ранее.

Современные языки, такие как этот пример JavaScript, имеют правильные интерпретаторы / компиляторы для обработки этих дел учета. В то время, когда были созданы компиляторы ALGOL60, некоторые реализации были неправильными. Тест был сделан, чтобы отделить неверные реализации от правильных.

...