awkrs 0.4.13

Awk implementation in Rust with broad CLI compatibility, parallel records, and experimental Cranelift JIT
Documentation
# Suffix array — list every suffix of the input string sorted lex.
# O(n^2 log n) trivial sort (build all suffixes, sort) — plenty fast for the
# demo inputs and easy to read. Output:
#   "<input>: SA=[i1 i2 ...]"   1-based starting positions of suffixes in sort order
#   "      LCP=[l1 l2 ...]"     longest-common-prefix between consecutive suffixes
#
# For each input line that's non-empty.

function suffix_at(s, i) { return substr(s, i) }

function lcp(a, b,   k, n) {
  n = (length(a) < length(b)) ? length(a) : length(b)
  k = 0
  while (k < n && substr(a, k + 1, 1) == substr(b, k + 1, 1)) k++
  return k
}

NF == 0 { next }

{
  s = $0
  n = length(s)
  delete suf
  for (i = 1; i <= n; i++) suf[i] = sprintf("%s\t%d", suffix_at(s, i), i)
  asort(suf)

  sa = ""; lp = ""
  for (i = 1; i <= n; i++) {
    split(suf[i], parts, "\t")
    sa = sa (i == 1 ? "" : " ") parts[2]
    if (i >= 2) {
      split(suf[i - 1], prev, "\t")
      split(suf[i],     cur,  "\t")
      lp = lp (i == 2 ? "" : " ") lcp(prev[1], cur[1])
    }
  }
  printf "%s: SA=[%s]\n", s, sa
  printf "      LCP=[%s]\n", lp
}