/extra/z-algorithm/z-algorithm.factor

http://github.com/abeaumont/factor · Factor · 38 lines · 28 code · 8 blank · 2 comment · 5 complexity · ce8bb7357b1d69cbfdef67ef66b2b610 MD5 · raw file

  1. ! Copyright (C) 2010 Dmitry Shubin.
  2. ! See http://factorcode.org/license.txt for BSD license.
  3. USING: arrays combinators.smart kernel locals math math.ranges
  4. sequences sequences.private ;
  5. IN: z-algorithm
  6. : lcp ( seq1 seq2 -- n )
  7. [ min-length ] 2keep mismatch [ nip ] when* ;
  8. <PRIVATE
  9. :: out-of-zbox ( seq Z l r k -- seq Z l r )
  10. seq k tail-slice seq lcp :> Zk
  11. Zk Z push seq Z
  12. Zk 0 > [ k Zk k + 1 - ] [ l r ] if ; inline
  13. :: inside-zbox ( seq Z l r k -- seq Z l r )
  14. k l - Z nth :> Zk'
  15. r k - 1 + :> b
  16. seq Z Zk' b <
  17. [ Zk' Z push l r ] ! still inside
  18. [
  19. seq r 1 + seq b [ tail-slice ] 2bi@ lcp :> q
  20. q b + Z push k q r +
  21. ] if ; inline
  22. : (z-value) ( seq Z l r k -- seq Z l r )
  23. 2dup < [ out-of-zbox ] [ inside-zbox ] if ; inline
  24. :: (z-values) ( seq -- Z )
  25. V{ } clone 0 0 seq length :> ( Z l r len )
  26. len Z push [ seq Z l r 1 len [a,b) [ (z-value) ] each ]
  27. drop-outputs Z ; inline
  28. PRIVATE>
  29. : z-values ( seq -- Z )
  30. dup length 0 > [ (z-values) ] when >array ;