Есть несколько вещей, которые сразу очевидны:
- У вас есть ровно два допустимых возвращаемых значения: «Позволь мне попробовать!» И «Не смейся надо мной!». Вы ошиблись в первом, перефразировали вторую и добавили множество строк, которые не используются для решения проблемы (они предназначены для комментариев?).
- Описание вызывает переменные
N
и M
, но ваши попытки принимают параметры N
и G
. Зачем путать себя? Либо называйте их N
и M
, либо (лучше) используйте значимые имена, такие как rock-number
и gift-place
.
Теперь давайте посмотрим на структуру вашей программы.
(defun gift (N G)
(setq CR 9)
(setq i 3))
Эти setq
инструкции имеют неопределенное поведение на данный момент, потому что CR
и I
еще не определены. Многие реализации Lisp неявно создают глобально специальные переменные этих имен, но это плохой стиль, чтобы зависеть от этого. У меня сложилось впечатление, что вы хотите использовать let
здесь, например:
(defun gift (rock-number gift-place)
(let ((current-rock 0)
(jump-number 0))
;; ...
))
Обратите внимание, что вы действительно должны начать с самого начала, потому что вы упустили бы решение, когда подарок на скале 1 или 4.
Далее, эта форма cond
: это мертвый код, потому что он не имеет побочных эффектов, и вы немедленно отбрасываете его возвращаемое значение. Таким образом, в лучшем случае это комментарий, и вы должны использовать для этого комментарий.
Наконец, у нас есть этот забавный цикл:
(loop
(setq I (+ I 1))
(setq I (-(* I 2) 1))
(setq CR 9)
(breadth-search CR G #'lmg-moves)
(when (= CR G) (return "Let me Try!"))
(when (> CR N) (return "Don't laugh at me!"))))
Я не знаю, что делает breadth-search
, но кажется, что вы действительно зависите от манипулирования глобально специальными переменными. Я не могу сказать, что здесь может произойти. Тем не менее, я вижу несколько проблем:
- Вы можете иметь до двух мест при прыжке на определенное расстояние от данного камня. Неправильно проверять только одну переменную после каждого прыжка.
- Вы, кажется, путаете число прыжка с его расстоянием прыжка.
I
идет в последовательности 1, 3, 7, 15 & hellip ;, но последовательность чисел перехода будет 1, 2, 3, 4 & hellip; в то время как последовательность прыжков будет 1, 3, 5, 7 & hellip ;. Даже камни, которые посещают, когда они прыгают вправо, имеют другую последовательность (1, 4, 9, 16 & hellip;).
- Вы сбрасываете
CR
на 9 каждый раз через цикл. Я не понимаю, как это может быть правильно.
Стилистически вы должны сохранять свои переменные настолько локальными, насколько это возможно, используя, например, let
, do
или расширенные loop
ключевые слова :for
и :with
, а затем передавать их в функции, которые в них нуждаются в качестве аргументов. Это значительно упрощает рассуждения о том, что происходит.
Я думаю, что ваша ментальная модель алгоритма решения немного запутана. Я бы структурировал это так, чтобы вы перебирали прыжки и сохраняли набор камней, на которые вы, возможно, попадете точно после такого количества прыжков. Специальная обработка для маленьких N
, похоже, не дает большого прироста эффективности. Если у вас есть доказательство того, что у N
> 49 всегда есть решение, с другой стороны, у вас должно быть защитное предложение и комментарий, в котором изложены доказательства.