package main import ( "fmt" "log" "math/rand" "os" "sort" "time" ) var SPELLINGS = map[rune]string{ 'A': "AY", 'B': "BEE", 'C': "SEE", 'D': "DEE", 'E': "EE", 'F': "EFF", 'G': "GEE", 'H': "AITCH", 'I': "EYE", 'J': "JAY", 'K': "KAY", 'L': "ELL", 'M': "EMM", 'N': "ENN", 'O': "OH", 'P': "PEE", 'Q': "CUE", 'R': "ARR", 'S': "ESS", 'T': "TEE", 'U': "EWE", 'V': "VEE", 'W': "DOUBLE EWE", 'X': "ECKS", 'Y': "WHY", 'Z': "ZEE", } var modeRandom = false var modeInfinite = false var modeStats = false func main() { rand.Seed(time.Now().UnixNano()) for i := 1; i < len(os.Args); i++ { if os.Args[i] == "--random" { modeRandom = true } if os.Args[i] == "--infinite" { modeInfinite = true } if os.Args[i] == "--stats" { modeStats = true } } totalAlphabets := 0 // a count of how many alphabets stabilize in various quantities stats := make(map[int]int) for { var alphabet []rune if modeRandom { alphabet = randomAlphabet() } else { alphabet = []rune{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'} } prev := string(alphabet) fmt.Println(string(prev)) i := 0 for { if i > 100 { fmt.Println("Alphabet seems infinite.") break } alphabet = sortAlphabet(alphabet) if string(alphabet) == prev { if modeInfinite { fmt.Println(prev) } break } prev = string(alphabet) if !modeInfinite { fmt.Println(prev) } i++ } fmt.Println("Iterations:", i) stats[i]++ totalAlphabets++ if modeStats { printStats(stats, totalAlphabets) } if !modeInfinite { return } } } // sort the provided alphabet (a slice of runes) by spelling, using the alphabet itself // as the lexicographic ordering. Return the new alphabet. func sortAlphabet(alphabet []rune) []rune { new_alphabet := make([]rune, len(alphabet)) copy(new_alphabet, alphabet) sort.Slice(new_alphabet, func(i, j int) bool { i_spelling := SPELLINGS[new_alphabet[i]] j_spelling := SPELLINGS[new_alphabet[j]] i_index := -1 j_index := -1 k := 0 for k = 0; k < len(i_spelling) && k < len(j_spelling); k++ { i_index = findIndex(alphabet, rune(i_spelling[k])) j_index = findIndex(alphabet, rune(j_spelling[k])) if i_index != j_index { break } } return i_index < j_index }) return new_alphabet } func findIndex(alphabet []rune, target rune) int { for i, letter := range alphabet { if letter == target { return i } } log.Panicf("Tried to find a letter that doesn't exist") return -1 } func randomAlphabet() []rune { a := []rune{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'} rand.Shuffle(len(a), func(i, j int) { a[i], a[j] = a[j], a[i] }) return a } func printStats(counts map[int]int, total int) { keys := make([]int, 0, len(counts)) for k, _ := range counts { keys = append(keys, k) } sort.Ints(keys) for _, k := range keys { if k == 101 { fmt.Printf("Infinite Loops: %.2f\n", float64(counts[k])/float64(total)) continue } fmt.Printf("%d: %.2f\n", k, float64(counts[k])/float64(total)) } fmt.Println(counts) }