сумма всех целых чисел от a до b, что не так с моим кодом?

Цель состоит в том, чтобы создать код, который будет вычислять сумму всех целых чисел от a до b, и если a > b, то он должен равняться 0.

(define (sum-from-to a b)
  (if (> a b)
      0
      (+ a (sum-from-to (- a 1) b))))

Моя проблема в том, что когда я запускаю это, у меня заканчивается память. Что не так с моим кодом?


person seaweed    schedule 23.02.2019    source источник
comment
Подсказка: предположим, что ваш список целых чисел равен {1, 2, 3}, где a = 1 и b = 3. Подумайте о том, что производит (- a 1).   -  person assefamaru    schedule 23.02.2019
comment
Должен ли код быть рекурсивным?   -  person coredump    schedule 25.02.2019


Ответы (2)


Рекурсивный шаг неверен. Предполагая, что a <= b исправление так же просто, как это:

(define (sum-from-to a b)
  (if (> a b)
      0
      (+ a (sum-from-to (+ a 1) b)))) ; add 1, don't subtract

Подумайте об этом, мы хотим, чтобы a приближался к b на каждом шагу, пока не перепрыгнул через него. Если мы уменьшим a, то оно удалится от b, что является полной противоположностью тому, что мы хотим. Вот почему вашей процедуре не хватает памяти, a так и не достигла b.

person Óscar López    schedule 23.02.2019

Что ж, вот один ответ, который дал бы математик: сумма всех целых чисел от a до b равна половине суммы целых чисел от a до b плюс сумма всех целых чисел от b до a. А это a + b + a + 1 + b - 1 + ... + b + a, то есть a + b + a + b + ... + a + b. А это в свою очередь (a + b) * (b - a + 1). Таким образом, окончательная сумма равна (a + b) * (a - b + 1) / 2. Так что просто напишите это на Лиспе с дополнительным условием, указанным для b < a:

(define (sum-a-b a b)
  (if (> a b)
      0
      (/ (* (+ a b) (+ (- b a) 1)) 2)))

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

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

person Community    schedule 25.02.2019
comment
Люди, преподающие Лисп, должны прекратить активно пытаться учить людей плохо программировать. Я не вижу кнопки аплодисментов, так что придется проголосовать за. - person Kaz; 25.02.2019
comment
@Каз Спасибо. Было бы интересно подсчитать количество очевидно-студентов, спрашивающих решения задач, где есть известная закрытая-форма. Я полагаю, это разумно, что ученики недостаточно знают математику, чтобы ее знать, но их учителя должны. Алгоритмов, где нет закрытой формы, не так уж и много. - person ; 26.02.2019
comment
Кажется, проблема в том, что преподаватели Лиспа не просто учат людей плохо программировать, но особенно учат паршивому Лиспу, который оставляет у студентов плохое впечатление о языковой семье. - person Kaz; 26.02.2019
comment
@Kaz: Я думаю, что аргумент в том, что мы храним язык в секрете, известном только гуру. Или они просто не умеют программировать. - person ; 26.02.2019