File: longest-common.go

package info (click to toggle)
kitty 0.42.1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 28,564 kB
  • sloc: ansic: 82,787; python: 55,191; objc: 5,122; sh: 1,295; xml: 364; makefile: 143; javascript: 78
file content (79 lines) | stat: -rw-r--r-- 1,356 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>

package utils

import (
	"fmt"
	"math"
)

var _ = fmt.Print

func slice_iter(strs []string) func() (string, bool) {
	i := 0
	limit := len(strs)
	return func() (string, bool) {
		if i < limit {
			i++
			return strs[i-1], false
		}
		return "", true
	}
}

// Prefix returns the longest common prefix of the provided strings
func Prefix(strs []string) string {
	return LongestCommon(slice_iter(strs), true)
}

// Suffix returns the longest common suffix of the provided strings
func Suffix(strs []string) string {
	return LongestCommon(slice_iter(strs), false)
}

func min(a ...int) int {
	ans := math.MaxInt
	for _, x := range a {
		if x < ans {
			ans = x
		}
	}
	return ans
}

func LongestCommon(next func() (string, bool), prefix bool) string {
	xfix, done := next()
	if xfix == "" || done {
		return ""
	}
	for {
		q, done := next()
		if done {
			break
		}
		q_len := len(q)
		xfix_len := len(xfix)
		max_len := min(q_len, xfix_len)
		if max_len == 0 {
			return ""
		}
		if prefix {
			for i := 0; i < max_len; i++ {
				if xfix[i] != q[i] {
					xfix = xfix[:i]
					break
				}
			}
		} else {
			for i := 0; i < max_len; i++ {
				xi := xfix_len - i - 1
				si := q_len - i - 1
				if xfix[xi] != q[si] {
					xfix = xfix[xi+1:]
					break
				}
			}
		}
	}
	return xfix
}