(declare (optimize speed))
(let ((map (make-hash-table :test #'equal))
- (max 0))
+ (max 0) (winners nil))
(loop
(let ((line (read-line stream nil)))
(gethash (subseq word 0 (1- len))
map))))
(nlen (node-len node)))
- (setf (node-up node) parent)
- (loop
- (unless parent (return))
- (incf nlen)
- (let ((plen (node-len parent)))
- ;;(format t ";; node `~A' ~D parent `~A' ~D~%"
- ;; (node-word node) (1- nlen)
- ;; (node-word parent) plen)
- (cond ((> plen nlen)
- ;;(format t ";; longer chain through `~A'~%"
- ;; (node-word (node-down parent)))
- (return))
- ((= plen nlen)
- (setf (node-right node) (node-down parent)
- (node-down parent) node)
- (return))
- (t
- ;;(format t ";; new longest chain ~A > ~A~%"
- ;; nlen plen)
- (setf (node-down parent) node
- (node-right node) nil
- (node-len parent) nlen
- node parent
- parent (node-up node))))))
- (when (> nlen max) (setf max nlen))))
+ (when parent
+ (setf (node-up node) parent)
+ (loop
+ (unless parent
+ (when (>= nlen max)
+ (when (> nlen max)
+ (setf max nlen
+ winners nil))
+ (push node winners))
+ (return))
+ (incf nlen)
+ (let ((plen (node-len parent)))
+ ;;(format t ";; node `~A' ~D parent `~A' ~D~%"
+ ;; (node-word node) (1- nlen)
+ ;; (node-word parent) plen)
+ (cond ((> plen nlen)
+ ;;(format t ";; longer chain through `~A'~%"
+ ;; (node-word (node-down parent)))
+ (return))
+ ((= plen nlen)
+ (setf (node-right node) (node-down parent)
+ (node-down parent) node)
+ (return))
+ (t
+ ;;(format t ";; new longest chain ~A > ~A~%"
+ ;; nlen plen)
+ (setf (node-down parent) node
+ (node-right node) nil
+ (node-len parent) nlen
+ node parent
+ parent (node-up node)))))))))
map)
- (maphash (lambda (word node)
- (declare (ignore word)
- (type node node))
-
- (when (= (node-len node) max)
- (labels ((print-chain (node)
- (cond ((null (node-right node))
- (write-string (node-word node))
- (let ((down (node-down node)))
- (when down
- (write-char #\space)
- (print-chain down))))
- (t
- (write-string "{ ")
- (loop
- (write-string (node-word node))
- (let ((down (node-down node)))
- (when down
- (write-char #\space)
- (print-chain down)))
- (let ((right (node-right node)))
- (unless right (return))
- (write-string " | ")
- (setf node right)))
- (write-string " }")))))
- (print-chain node)
- (terpri))))
- map)))
+ (labels ((print-chain (node)
+ (cond ((null (node-right node))
+ (write-string (node-word node))
+ (let ((down (node-down node)))
+ (when down
+ (write-char #\space)
+ (print-chain down))))
+ (t
+ (write-string "{ ")
+ (loop
+ (write-string (node-word node))
+ (let ((down (node-down node)))
+ (when down
+ (write-char #\space)
+ (print-chain down)))
+ (let ((right (node-right node)))
+ (unless right (return))
+ (write-string " | ")
+ (setf node right)))
+ (write-string " }")))))
+ (dolist (node winners)
+ (print-chain node)
+ (terpri)))))
#+runlisp-script
(let ((args (uiop:command-line-arguments))