LoginSignup
2
2

More than 5 years have passed since last update.

今更:1 時間以内に解けなければプログラマ失格問題 5 を elisp で解いてみた

Posted at

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 だとだいぶリラックスした雰囲気を感じるのは気のせいかしら。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2