UVa 10120 Подарок ?!в Common Lisp? - PullRequest
2 голосов
/ 02 февраля 2012

Я изучаю общий шут, мне выдали проблему из базы данных uVA (http://acm.uva.es/p/v101/10120.html) и функции расширенного поиска (которая берет начальную точку, цель и генератор легального движения), я у меня есть теория о том, как я должен получить ответ, но Лисп просто не согласен со мной. Могу ли я дать несколько советов о том, как действовать с этого момента? Ниже приведена ссылка на данную проблему и мои два из моих попыток решения с исходным кодом LISP. Любая помощь будет принята с благодарностью! Спасибо!

1

(defun gift (N G)
(setq CR 9)
(setq i 3)
(cond ((= N G) "N and G equal")
    ((< N G) "Gift it on a rock outside limits")
    ((> N 49) "number of rocks is bigger than 49 - it will work")
    ((< N 9) "number of rocks is less than 9, it wont work")
    ((= N 0) "number of rocks is 0, it wont work")
    ((= G 0) "gift isn't on a rock, it wont work"))
(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!"))
  ))

(defun lmg-moves (I)
(list (+ 9 I)
    (- 9 I)
    ))

2

(defvar *currentRock* 9)
(defvar *iterator* 3)

(defun gift (N G)
 (setq *iterator* (+ *iterator* 1))
 ;; (breadth-search *currentRock* G #'LMG)
)

(defun LMG (a)
(+ a (-(* *iterator* 2) 1))
   )

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

Ответы [ 2 ]

2 голосов
/ 05 февраля 2012

Есть несколько вещей, которые сразу очевидны:

  • У вас есть ровно два допустимых возвращаемых значения: «Позволь мне попробовать!» И «Не смейся надо мной!». Вы ошиблись в первом, перефразировали вторую и добавили множество строк, которые не используются для решения проблемы (они предназначены для комментариев?).
  • Описание вызывает переменные 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 всегда есть решение, с другой стороны, у вас должно быть защитное предложение и комментарий, в котором изложены доказательства.

2 голосов
/ 02 февраля 2012

Среди других потенциальных проблем:

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

SETF рекомендуется вместо SETQ, поскольку SETF более общий.

INCF увеличивает место на 1

Ваш отступ плохой;если вы исправите это, вы заметите, что падаете с конца COND в LOOP.Я бы порекомендовал редактор с автоматическим отступом для использования Lisp здесь.(Emacs находится в режиме ожидания).

(defun gift (N G)
    (setq CR 9)
    (setq i 3)
    (cond ((= N G) "N and G equal")
          ((< N G) "Gift it on a rock outside limits")
          ((> N 49) "number of rocks is bigger than 49 - it will work")
          ((< N 9) "number of rocks is less than 9, it wont work")
          ((= N 0) "number of rocks is 0, it wont work")
          ((= G 0) "gift isn't on a rock, it wont work")) )
    (loop 
      while t
      do
       (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!"))))
...