Compare commits
5 Commits
60d463a546
...
main
Author | SHA1 | Date | |
---|---|---|---|
599734c17a | |||
aef8baee0a | |||
ffb9d1a09f | |||
5fbec89c4e | |||
48d1a97acd |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
alphabetter
|
147
alphabetter.go
147
alphabetter.go
@ -3,55 +3,107 @@ 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",
|
||||
'A': "A",
|
||||
'B': "BEE",
|
||||
'C': "CEE",
|
||||
'D': "DEE",
|
||||
'E': "E",
|
||||
'F': "EF",
|
||||
'G': "GEE",
|
||||
'H': "AITCH",
|
||||
'I': "I",
|
||||
'J': "JAY",
|
||||
'K': "KAY",
|
||||
'L': "EL",
|
||||
'M': "EM",
|
||||
'N': "EN",
|
||||
'O': "O",
|
||||
'P': "PEE",
|
||||
'Q': "CUE",
|
||||
'R': "AR",
|
||||
'S': "ESS",
|
||||
'T': "TEE",
|
||||
'U': "U",
|
||||
'V': "VEE",
|
||||
'W': "DOUBLE U",
|
||||
'X': "EX",
|
||||
'Y': "WYE",
|
||||
'Z': "ZEE",
|
||||
}
|
||||
|
||||
var modeRandom = false
|
||||
var modeInfinite = false
|
||||
var modeStats = false
|
||||
|
||||
func main() {
|
||||
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'}
|
||||
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 {
|
||||
alphabet = sort_alphabet(alphabet)
|
||||
if i > 100 {
|
||||
fmt.Println("Alphabet seems infinite.")
|
||||
break
|
||||
}
|
||||
alphabet = sortAlphabet(alphabet)
|
||||
if string(alphabet) == prev {
|
||||
return
|
||||
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 sort_alphabet(alphabet []rune) []rune {
|
||||
func sortAlphabet(alphabet []rune) []rune {
|
||||
new_alphabet := make([]rune, len(alphabet))
|
||||
copy(new_alphabet, alphabet)
|
||||
sort.Slice(new_alphabet, func(i, j int) bool {
|
||||
@ -62,9 +114,13 @@ func sort_alphabet(alphabet []rune) []rune {
|
||||
j_index := -1
|
||||
|
||||
k := 0
|
||||
for k = 0; k < len(i_spelling) && k < len(j_spelling); k++ {
|
||||
i_index = find_index(alphabet, rune(i_spelling[k]))
|
||||
j_index = find_index(alphabet, rune(j_spelling[k]))
|
||||
for k = 0; ; k++ {
|
||||
if k >= len(i_spelling) || k >= len(j_spelling) {
|
||||
return len(i_spelling) < len(j_spelling)
|
||||
}
|
||||
|
||||
i_index = findIndex(alphabet, rune(i_spelling[k]))
|
||||
j_index = findIndex(alphabet, rune(j_spelling[k]))
|
||||
|
||||
if i_index != j_index {
|
||||
break
|
||||
@ -75,7 +131,7 @@ func sort_alphabet(alphabet []rune) []rune {
|
||||
return new_alphabet
|
||||
}
|
||||
|
||||
func find_index(alphabet []rune, target rune) int {
|
||||
func findIndex(alphabet []rune, target rune) int {
|
||||
for i, letter := range alphabet {
|
||||
if letter == target {
|
||||
return i
|
||||
@ -84,3 +140,26 @@ func find_index(alphabet []rune, target rune) int {
|
||||
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)
|
||||
}
|
||||
|
@ -26,3 +26,7 @@ with nearly any version of golang installed. Then execute it with
|
||||
```
|
||||
./alphabetter
|
||||
```
|
||||
|
||||
To loop forever, run with `--infinite`. While in infinite mode, only the starting alphabet and final alphabet are printed.
|
||||
|
||||
To start with a random alphabet (on each iteration), run with `--random`.
|
||||
|
Reference in New Issue
Block a user