Немного изменен вопрос на основе последовательности Фибоначчи

Недавно мне задали этот вопрос в одном из моих интервью, которое я, конечно же, провалил.

Я просто хочу знать, как это будет решено. Код, который я пытался использовать, был следующим:

def gibonacci(n, x, y):
    # Base case
    if n == 0:
        return x
    elif n == 1:
        return y
    else:
        sequence = [x, y]
        for i in range(2, n):
            next_term = sequence[i-1] - sequence[i-2]
            sequence.append(next_term)
        return sequence[-1]

Любая помощь, даже просто логическая помощь будет достаточно. Спасибо!

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

chrslg 30.12.2022 14:35

Вы ошиблись на единицу: for i in range(2, n+1):

Paul Hankin 30.12.2022 14:47

Иначе говоря: "небольшое" изменение Фибоначчи (точнее, - вместо +) вовсе не "небольшое". Это меняет все в динамике последовательности. И я почти уверен, что тест предназначен для того, чтобы увидеть, кто может его обнаружить, и утверждение, что gibonnaci является «похожей» последовательностью, было здесь ловушкой. Это может быть похоже по письму, но совсем не по поведению.

chrslg 30.12.2022 14:51
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
130
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Ваш вопрос был для меня немного расплывчатым, но попробуйте следующий код, он может вам помочь.

Попробуй это:

def gibonacci(n,x,y):   
    if n == 0:
        return x

    elif n == 1:
        return y

    else:
        for i in range(1, n):
            c = y - x
            x = y
            y = c

        return y

print(gibonacci(2,0,1))

Это слишком экспансивный способ вычисления. Я имею в виду, что мое собственное первое решение, вероятно, было бы таким. Но потом я бы проследил результат на некоторых примерах и увидел бы, что возможна оптимизация. Я почти уверен, что весь смысл интервью заключался в том, чтобы проверить, кто может определить закономерность.

chrslg 30.12.2022 14:34

Как я сказал в комментариях, я почти уверен, что интервью было сделано, чтобы проверить, кто может подумать о проблеме, прежде чем думать о решении.

Посмотрите, какая у вас последовательность
г₀ = х
г₁ = у
г₂ = у-х
г₃ = у-х - у = -х
г₄ = -х - (ух) = -у
г₅ = -у - (-х) = х-у
г₆ = х-у - (-у) = х
г₇ = х - (х-у) = у
...

Как только вы получили 2 повторяющихся элемента в последовательности, вы не можете ничего сделать, кроме как повторить остальные. Другими словами, gₙ₊₆=gₙ навсегда. Таким образом, шаблон всегда имеет одинаковую длину - 6 циклов: x, y, y-x, -x, -y, x-y.

Следовательно, более быстрое решение без какой-либо итерации

def gibonacci(n, x, y):
   if n%3==0:
       r=x
   elif n%3==1:
       r=y
   else:
       r=y-x
   if (n//3)%2:
       return -r
   else: 
       return r

Работает за O(1) (в отличие от итерационных методов за O(n)).

Более «сырой» (быстрее, но менее явный с логикой. В любом случае, все варианты O (1)) могут существовать. Например, этот однострочный:

def gibonacci(n, x, y):
    return [x,y,y-x,-x,-y,x-y][n%6]

Я не интервьюер. Так что я не могу предположить, что они искали. Но мое чутье подсказывает, что принятый ответ провалил бы собеседование, даже если бы он сработал, и что ожидаемый ответ был похож на этот.

Обновлено: рассмотрение времени

Извините, что возвращаюсь к этому; но из-за недавнего уведомления - благодаря голосующему: D - я снова увидел этот вопрос и заметил то, на что я не обратил достаточно внимания в первую очередь. Вопрос содержит заманчивое утверждение о том, что вы можете предположить, что n<10⁹. Я сказал «trappy» (я имею в виду, что это сделано, чтобы обмануть), потому что это выглядит так, как будто это означает «не волнуйтесь, n не слишком велико». Но 10⁹ велико, и на самом деле это означает «осторожно, n может быть до 10⁹».

Итак, из любопытства, на моем (довольно старом, конечно, но все же, современная машина не будет в 10 раз быстрее, и даже тогда я все еще понимаю свою точку зрения) я замерил принятый ответ с n = 10⁹. На моем компьютере это занимает 78 секунд.

Мой, конечно (без итерации), занимает 370 нс. Это в 200 миллионов раз быстрее. Мы не говорим здесь о простой оптимизации. Такая разница есть разница между "быстро" и "практически невозможно".

Таким образом, это замечание (n<10⁹) в утверждении является еще одним доказательством того, что вы никогда не должны были использовать итеративные вычисления.

Другие вопросы по теме