import Foundation
// Extract alphabetic words (lowercased)
func extractWords(_ text: String) -> [String] {
let regex = try! NSRegularExpression(pattern: "[A-Za-z]+")
let range = NSRange(text.startIndex..., in: text)
return regex.matches(in: text, range: range).compactMap {
Range($0.range, in: text).map { String(text[$0]).lowercased() }
}
}
// Build prefix → list of words that share that prefix
func groupByPrefixes(_ words: [String]) -> [String: [String]] {
var groups: [String: [String]] = [:]
for w in words {
for i in 1...w.count {
let prefix = String(w.prefix(i))
groups[prefix, default: []].append(w)
}
}
return groups
}
// Find the longest prefix that appears in 2+ words
func longestSharedPrefix(_ groups: [String: [String]]) -> String? {
groups
.filter { $0.value.count >= 2 }
.keys
.max(by: { $0.count < $1.count })
}
// ------------------------------------------------------------
// Main
// ------------------------------------------------------------
let text = """
The Lowly inhabitants of the lowland were surprised to see
the lower branches of the trees.
"""
let words = extractWords(text)
let groups = groupByPrefixes(words)
let prefix = longestSharedPrefix(groups)
if let p = prefix, let group = groups[p] {
print("Longest shared prefix:")
print("\(p) | prefix_len=\(p.count) | group_count=\(group.count) | \(group)")
} else {
print("No shared prefix found.")
}
/*
run:
Longest shared prefix:
lowl | prefix_len=4 | group_count=2 | ["lowly", "lowland"]
*/