JavaScript バージョンと、C++ バージョンができたので、elisp でも書いてみた。
(defun calc-inner (exp tmp sum)
(if (null exp)
(+ sum tmp)
(let ((op (nth 0 exp))
(val (nth 1 exp))
(rest (nthcdr 2 exp)))
(pcase op
((or `+ `-)
(calc-inner rest (funcall op val) (+ sum tmp)))
(t (let ((sign (if (> tmp 0) 1 -1)))
(calc-inner rest (+ (* tmp 10)
(* sign val)) sum)))))))
(defun calc (exp)
(calc-inner (cdr exp) (car exp) 0))
(defun dump (exp)
(mapconcat (lambda (term)
(pcase term
((or `+ `-)
(format " %s " term))
(`nil "")
(t (number-to-string term)))) exp ""))
(defun gen (src &optional acc)
(if (eq (length src) 1)
(princ (reverse (cons (car src) acc)))
(dolist (op '(+ - nil))
(gen (cdr src)
(cons op (cons (car src) acc))))))
(with-temp-buffer
(let ((print-length nil)
(standard-output (current-buffer))
(standard-input (current-buffer))
(numbers (number-sequence 1 9))
result)
(gen numbers)
(goto-char (point-min))
(while (not (eobp))
(let ((exp (read)))
(when (eq (calc exp) 100)
(push (dump exp) result))))
result))
Emacs ならやっぱりバッファだよなーということで、安直に一時バッファを使って式の生成と評価を行っている。基本的なロジックはどれも一緒だけど、elisp だとだいぶリラックスした雰囲気を感じるのは気のせいかしら。