package main
import (
"fmt"
"sort"
)
/*
Efficient algorithm using Go maps:
----------------------------------
Each word is converted into a map[rune]bool representing its unique letters.
Example:
"algebraic" -> map[rune]bool{
'a': true, 'l': true, 'g': true, 'e': true,
'b': true, 'r': true, 'i': true, 'c': true,
}
Then:
- Start with the letter-set of the first word.
- Intersect with each subsequent word's letter-set.
- The final map contains letters common to all words.
This uses Go's built-in:
- map[rune]bool for sets
- range loops
- slices for sorting output
*/
// Convert a word into a set of its unique letters
func lettersOf(word string) map[rune]bool {
set := make(map[rune]bool)
for _, ch := range word {
if ch >= 'a' && ch <= 'z' {
set[ch] = true
}
}
return set
}
// Compute letters common to all words
func commonLetters(words []string) map[rune]bool {
if len(words) == 0 {
return map[rune]bool{}
}
// Start with letters of the first word
common := lettersOf(words[0])
// Intersect with each subsequent word
for _, word := range words[1:] {
current := lettersOf(word)
// Remove letters not present in the current word
for ch := range common {
if !current[ch] {
delete(common, ch)
}
}
}
return common
}
// Print letters in sorted order
func printLetters(letters map[rune]bool) {
var list []rune
for ch := range letters {
list = append(list, ch)
}
sort.Slice(list, func(i, j int) bool { return list[i] < list[j] })
for _, ch := range list {
fmt.Printf("%c ", ch)
}
fmt.Println()
}
func main() {
words := []string{
"algebraic",
"alphabetic",
"ambiance",
"abacus",
"metabolic",
"parabolic",
"playback",
"drawback",
"fabricate",
"flashback",
"syllabic",
}
result := commonLetters(words)
fmt.Println("Common letters across all words:")
printLetters(result)
}
/*
run:
Common letters across all words:
a b c
*/