(in-package "XWORD") (defun array-position-of (array string) "Return INDEX of STRING if it is present in ARRAY." (position string array :test #'equal)) (defun array-remove-at-index (array index) "Internal." (let ((length (decf (fill-pointer array)))) (rotatef (aref array index) (aref array length)))) (defun copy-dict (array) (make-array (length array) :fill-pointer t :initial-contents array)) (defun dict-length (array) (fill-pointer array)) (defun read-ordered-dictionaries (words-path &key (hint 10)) "WORDS-PATH is a pathname to a file containing a wordlist, one word per line. Return an array of arrays of strings. The array at position N represents a dictionary of all words of length N." (let ((ordered-dicts (make-array hint :initial-element nil :adjustable t))) (with-open-file (stream words-path :direction :input) (loop for word = (read-line stream nil) while word do (let ((length (length word))) (when (> (length word) 0) (unless (< (length word) (length ordered-dicts)) (setq ordered-dicts (adjust-array ordered-dicts (1+ length) :initial-element nil))) (let ((dict (or (aref ordered-dicts length) (setf (aref ordered-dicts length) (make-array 0 :adjustable t :fill-pointer t :element-type 'string))))) (vector-push-extend word dict)))))) ordered-dicts))