LINUX.ORG.RU

История изменений

Исправление Gentooshnik, (текущая версия) :

Без обфускацииминификации, но без eval.

(defun concat-digit (number digit)
  (if (plusp number)
      (+ (* number 10) digit)
      (- (* number 10) digit)))

(defun solve (first-digit target)
  (labels ((iter (last-number next-digit expr current-value)
             (if (= next-digit -1)
                 (when (= current-value target)
                   (format t "~A = ~A~%" expr target))
                 (let ((next-number (concat-digit last-number next-digit)))
                   ;; +
                   (iter next-digit
                         (1- next-digit)
                         (format nil "~A+~A" expr next-digit)
                         (+ current-value next-digit))
                   ;; -
                   (iter (- next-digit)
                         (1- next-digit)
                         (format nil "~A-~A" expr next-digit)
                         (- current-value next-digit))
                   ;; ничего
                   (iter next-number
                         (1- next-digit)
                         (format nil "~A~A" expr next-digit)
                         (+ current-value (- last-number) next-number))))))
    (iter first-digit (1- first-digit) (format nil "~A" first-digit) first-digit)))

(solve 9 200)
9-8+7-6-5-4-3+210 = 200
9-8-7-6-5+4+3+210 = 200
98+76-5+43-2-10 = 200
98-7+65+43+2-1+0 = 200
98-7+65+43+2-1-0 = 200

@Lrrr Стек не порвёт, тут всего O(N) нужно, при N не превышающем 9. В твоём варианте вроде бы тоже, но не берусь точно сказать что там будет с yield.

Исходная версия Gentooshnik, :

Без обфускацииминификации, но без eval.

(defun concat-digit (number digit)
  (if (plusp number)
      (+ (* number 10) digit)
      (- (* number 10) digit)))

(defun solve (first-digit target)
  (labels ((iter (last-number next-digit expr current-value)
             (if (= next-digit -1)
                 (when (= current-value target)
                   (format t "~A = ~A~%" expr target))
                 (let ((next-number (concat-digit last-number next-digit)))
                   ;; +
                   (iter next-digit
                         (1- next-digit)
                         (format nil "~A+~A" expr next-digit)
                         (+ current-value next-digit))
                   ;; -
                   (iter (- next-digit)
                         (1- next-digit)
                         (format nil "~A-~A" expr next-digit)
                         (- current-value next-digit))
                   ;; ничего
                   (iter next-number
                         (1- next-digit)
                         (format nil "~A~A" expr next-digit)
                         (+ current-value (- last-number) next-number))))))
    (iter first-digit (1- first-digit) (format nil "~A" first-digit) first-digit)))

(solve 9 200)
9-8+7-6-5-4-3+210 = 200
9-8-7-6-5+4+3+210 = 200
98+76-5+43-2-10 = 200
98-7+65+43+2-1+0 = 200
98-7+65+43+2-1-0 = 200

@Lrrr Стек не порвёт, тут всего O(N) нужно. В твоём варианте вроде бы тоже, но не берусь точно сказать что там будет с yield.