Вывод числа Фибоначчи меньше заданного

      Комментарии к записи Вывод числа Фибоначчи меньше заданного отключены

Главная Форумы Программирование Помощь с решением задач на Prolog Общие вопросы Вывод числа Фибоначчи меньше заданного

В этой теме 1 ответ, 2 участника, последнее обновление  Васильев Владимир Сергеевич 2 года/лет, 2 мес. назад.

  • Автор
    Сообщения
  • #1814

    questioner
    Участник

    predicates
      fib(integer, integer, integer, integer)
      fibless(integer)
    clauses
      fib(0,1,1,1). /* pervoe chislo Fibonacchy ravno 1*/
      fib(0,2,1,1). /* vtoroe chislo Fibonacchy ravno 1*/
      fib(_,F1,_,Max) :- F1>=Max, !.
      fib(N,F1,F2,Max) :- write(F1), nl, NN = N+1, F3 = F1+F2, fib(NN,F2,F3,Max).
      fibless(Max) :- fib(1,1,1,Max).
    goal
      fibless(30).

    При запуске, рекурсия честно выдает все числа Фибоначчи, которые меньше указанного (30). А как сделать вывод только последнего числа, который максимально близко к введенному? Я думаю, надо предикат write вынести за пределы рекурсии. Но куда его вынести? Пытался писать его в разных частях программы, но не получилось. В данном случает, результатом программы должно быть «21».

  • #1815

    Долго не мог понять как вообще работает Ваша функция. Заметил, что первые 2 строки:

    fib(0,1,1,1). /* pervoe chislo Fibonacchy ravno 1*/
    fib(0,2,1,1). /* vtoroe chislo Fibonacchy ravno 1*/

    вообще не нужны (и в них явно ошибка, потому что номер числа — это первый аргумент, что не соответствует комментариям).

    Ваша функция ничего не возвращала, а лишь выводила на экран. Поэтому нельзя просто так взять и получить с ее помощью нужно число.

    Кроме того, в функции есть неиспользуемый первый аргумент (который номер числа).

    Если переписать ее так:

    fib(Fib, _, Max, Fib):-
        Fib >= Max, !.
    fib(Fib1, Fib2, Max, Res):-
        Fib3 is Fib1 + Fib2,
        fib(Fib2, Fib3, Max, Res).
     
    fibless(Max):-
        fib(1, 1, Max, Res), write(Res).

    Первые 2 аргумента функции — предыдущие числа Фибоначчи, с их помощью можно рассчитать следующее число.
    Первый аргумент больше предела — возвращаем его в качестве результата (записываем в четвертый аргумент).
    Так мы получим число, следующее за Max. Если нужно предыдущее — то можно сделать так:

    fib(F1, F2, Max, Res):-
        F3 is F1 + F2,
        (F3 >= Max, !, Res = F2;fib(F2, F3, Max, Res)).
    fibless(Max):-
        fib(1, 1, Max, Res), write(Res).

    Тут проверка того, что достигнут предел выполняется сразу после того, как рассчитано новое число Фибоначчи.

    Для Turbo Prolog и Visual Prolog (на котором вы пишите) выглядеть должно примерно так:

    fib(F1, F2, Max, F2):-
        F3 = F1 + F2,
        F3 >= Max, !.
    fib(F1, F2, Max, Res):-
        F3 = F1 + F2,
        fib(F2, F3, Max, Res).
     
    fibless(Max):-
        fib(1, 1, Max, Res), write(Res).

Для ответа в этой теме необходимо авторизоваться.