Probrem 18

(defun read-txt-numbers (file-name)
  (let (num-lst)
    (with-temp-buffer
      (insert-file-contents-literally file-name)
      (goto-char (point-min))
      (while (re-search-forward "[0-9]+" nil t)
	(setq num-lst (cons (string-to-number (match-string 0)) num-lst)) ))
    (nreverse num-lst) ))

(defun make-triangle (lst)
  (let (rst (n 1))
    (while lst
      (let ((i 0) (tmp (make-vector n 0)))
	(while (< i n)
	  (aset tmp i (car lst))
	  (setq i (1+ i))
	  (setq lst (cdr lst)) )
	(setq rst (cons tmp rst)) )
      (setq n (1+ n)))
    (nreverse rst) ))

(defun next-step (previous-sum-vec current-vec)
  (let* ((len (length current-vec))
	 (current-sum-vec (make-vector len 0))
	 (larger-sum 0))
    (dotimes (i len current-sum-vec)
      (setq larger-sum
	    (cond
	      ((eq i 0) (aref previous-sum-vec i))
	      ((eq i (1- len)) (aref previous-sum-vec (1- i)))
	      (t (max (aref previous-sum-vec i) (aref previous-sum-vec (1- i)))) ))
      (aset current-sum-vec i (+ (aref current-vec i) larger-sum)) )))

(let* ((triangle (make-triangle (read-txt-numbers (car argv))))
       (previous-sum-vec (car triangle))
       (current-vec))
  (princ triangle)
  (setq triangle (cdr triangle))
  (while triangle
    (setq current-vec (car triangle))
    (setq previous-sum-vec (next-step previous-sum-vec current-vec))
    (setq triangle (cdr triangle)) )
  (princ (apply #'max (append previous-sum-vec nil)))
  (princ "\n") )
メモ
  • triangle.txt を用意して, 次のコマンドを実行.
emacs -script 18.el triangle.txt
  • ベクトルを list に変換するときは, append で nil をくっつければOK.
 (append [1 2 3] nil) ;=> (1 2 3)