記事の最後に載せたプログラムのコメントにも書きましたが、ポイントは2つあります。
- 基準日の年と生年の差
- 基準日がその年の誕生日よりも前のときは1を減算する
2015/8/31
NARITA Shoさんから「Excel 界隈では「基準日」という語が使われているみたいですね。」とのコメントを頂きました。ありがとうございました。
以下、xyzzy lispとC#での実装を記載します。
2015/9/2
C#での実装例を追加しました。
(defun backet-sort (v backet-count) "バケツソート" (let ((backet (array-to-backet v backet-count))) (backet-to-array backet (length v)))) (defun array-to-backet (arr backet-count) "配列からバケツを構成する" (let ((backet (make-array backet-count :initial-element 0))) (dotimes (i (length arr) backet) (let ((n (aref arr i))) (setf (aref backet n) (1+ (aref backet n))))))) (defun backet-to-array (backet array-length) "バケツからソート済みの配列を構成する" (let ((arr (make-array array-length))) (loop with arr-index = 0 for i below (length backet) when (< 0 (aref backet i)) do (loop repeat (aref backet i) do (setf (aref arr arr-index) i) (setq arr-index (1+ arr-index)))) arr)) (defun main () "動作確認のための関数" (let ((l (loop with state = (make-random-state t) repeat 10 collect (random 10 state)))) (print (sort (make-array (length l) :initial-contents l) #'<)) (print (backet-sort (make-array (length l) :initial-contents l) 10)))) (main)
[Section1] Key1=Value1 Key2=Value2 [Section2] Key1=Value1 [Section3]
;; inifile.l (defun read-lines (input) (loop as line = (read-line input nil nil) while line collect line)) (defun sectionp (line) (and (stringp line) (<= 2 (length line)) (eq #\[ (char line 0)) (eq #\] (char line (1- (length line)))))) (defun keyvaluep (line) (and (stringp line) (<= 3 (length line)) (find #\= line) (< 0 (position #\= line)))) (defun strip-section (line) (if (not (sectionp line)) line (subseq line 1 (1- (length line))))) (defun split-keyvalue (line) (if (not (keyvaluep line)) line (list (subseq line 0 (position #\= line)) (subseq line (1+ (position #\= line)))))) (defun convert-to-alist (alist line) (cond ((sectionp line) (cons (list (strip-section line)) alist)) ((keyvaluep line) (cons (append (car alist) (list (split-keyvalue line))) (cdr alist))) (t alist))) (defun ini-assoc (section key alist) (car (last (assoc key (cdr (assoc section alist :test 'string-equal)) :test 'string-equal)))) ;; 以下実行部 (setf ini-alist (reduce 'convert-to-alist (read-lines *standard-input*) :initial-value '())) (format t "~A~%" ini-alist) (format t "~A ~A = ~A~%" "Section2" "Key1" (ini-assoc "Section2" "Key1" ini-alist)) (format t "~A ~A = ~A~%" "SECTION1" "KEY2" (ini-assoc "SECTION1" "KEY2" ini-alist))
$ cat sample.ini | clisp inifile.l ((Section3) (Section2 (Key1 Value1)) (Section1 (Key1 Value1) (Key2 Value2))) Section2 Key1 = Value1 SECTION1 KEY2 = Value2
; convert-xml (defparameter *conversion-alist* '((#\< . "<") (#\> . ">") (#\& . "&") (#\" . """) (#\' . "'"))) (defun convert-xml () (interactive "*") (let ((input-buffer (window-buffer (selected-window)))) (with-output-to-temp-buffer ("*Converted*") (with-open-stream (s (make-buffer-stream input-buffer)) (loop (let ((c (read-char s nil))) (if c (format t "~A" (convert-char c *conversion-alist*)) (return nil)))))))) (defun convert-char (c alist) (let ((conversion (assoc c alist))) (if conversion (cdr conversion) c)))