package bastion_init import ( "fmt" "sort" "strings" ) type WordC struct { Word string Rank int } func normalize(s string) string { // Convert to lowercase and replace hyphens with underscores for consistent comparison. return strings.Map(func(r rune) rune { if 'a' <= r && r <= 'z' || 'A' <= r && r <= 'Z' { return r } return '_' }, s) } func levDpDist(s1, s2 string) int { m, n := len(s1), len(s2) if m == 0 { return n } if n == 0 { return m } dp := make([][]int, m+1) for i := range dp { dp[i] = make([]int, n+1) } for i := 1; i <= m; i++ { for j := 1; j <= n; j++ { cost := 0 if s1[i-1] != s2[j-1] { cost = 1 } dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + cost } } return dp[m][n] } func min(a, b, c int) int { minVal := a if b < minVal { minVal = b } if c < minVal { minVal = c } return minVal } func FindClosestWordDp(words []string, prefix string) (string, error) { normalizedPrefix := normalize(prefix) normalizedWords := make([]string, len(words)) for i, word := range words { normalizedWords[i] = normalize(word) } sort.Slice(normalizedWords, func(i, j int) bool { return normalizedWords[i] < normalizedWords[j] }) minDistance := levDpDist(normalizedPrefix, normalizedWords[0]) closestWord := normalizedWords[0] for _, word := range normalizedWords { distance := levDpDist(normalizedPrefix, word) if distance < minDistance { minDistance = distance closestWord = word } } // Replace underscores with hyphens and convert back to original case. closestWord = strings.ReplaceAll(strings.ReplaceAll(strings.ToUpper(closestWord), "_", "-"), "\"", "") return closestWord, nil } func main() { words := []string{"Apple", "Apricot", "Apprentice", "Application"} prefix := "AP" closest, err := FindClosestWordDp(words, prefix) if err != nil { fmt.Println(err) } else { fmt.Printf("The closest word to '%s' is '%s'\n", prefix, closest) } }