Created
September 8, 2022 19:49
-
-
Save leklund/2f0516014ea64551a07fe53dada74e75 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"fmt" | |
"math/rand" | |
"os" | |
"sort" | |
"strconv" | |
"strings" | |
"time" | |
) | |
type Hive struct { | |
chars []rune | |
words []string | |
panagrams []string | |
} | |
type Config struct { | |
sets int | |
minP int | |
maxP int | |
minW int | |
maxW int | |
words []string | |
} | |
var 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'} | |
func main() { | |
conf := &Config{} | |
reader := bufio.NewReader(os.Stdin) | |
fmt.Printf("How many letter sets to find: ") | |
res, err := reader.ReadString('\n') | |
if err != nil { | |
panic(err) | |
} | |
conf.sets, err = strconv.Atoi(strings.TrimRight(res, "\n")) | |
if err != nil { | |
panic(err) | |
} | |
fmt.Printf("Mininum number of panagrams: ") | |
res, err = reader.ReadString('\n') | |
if err != nil { | |
panic(err) | |
} | |
conf.minP, err = strconv.Atoi(strings.TrimRight(res, "\n")) | |
fmt.Printf("Maximum number of panagrams: ") | |
res, err = reader.ReadString('\n') | |
if err != nil { | |
panic(err) | |
} | |
conf.maxP, err = strconv.Atoi(strings.TrimRight(res, "\n")) | |
fmt.Printf("Mininum number of words: ") | |
res, err = reader.ReadString('\n') | |
if err != nil { | |
panic(err) | |
} | |
conf.minW, err = strconv.Atoi(strings.TrimRight(res, "\n")) | |
fmt.Printf("Maximum number of words: ") | |
res, err = reader.ReadString('\n') | |
if err != nil { | |
panic(err) | |
} | |
conf.maxW, err = strconv.Atoi(strings.TrimRight(res, "\n")) | |
conf.words = WordsFromFile("./2of12inf.txt") | |
hives := FindSets(conf) | |
for _, h := range hives { | |
fmt.Println("letters: ", sortLetters(h.chars)) | |
fmt.Println("panagrams: ", h.panagrams) | |
fmt.Println("words: ", len(h.words)) | |
} | |
} | |
func FindSets(c *Config) []Hive { | |
var hives []Hive | |
for { | |
chars := RandoLetters() | |
charMap := make(map[rune]interface{}) | |
for _, ch := range chars { | |
charMap[ch] = struct{}{} | |
} | |
requiredLetter := chars[0] | |
h := Hive{ | |
chars: chars, | |
} | |
for _, word := range c.words { | |
okay, panagram := checkWord(word, requiredLetter, charMap) | |
if okay { | |
if panagram { | |
h.panagrams = append(h.panagrams, word) | |
} else { | |
h.words = append(h.words, word) | |
} | |
} | |
if len(h.panagrams) > c.maxP || len(h.words) > c.maxW { | |
break | |
} | |
} | |
if len(h.panagrams) >= c.minP && len(h.panagrams) <= c.maxP && len(h.words) >= c.minW && len(h.words) <= c.maxW { | |
hives = append(hives, h) | |
} | |
if len(hives) == c.sets { | |
return hives | |
} | |
} | |
} | |
func WordsFromFile(path string) []string { | |
file, err := os.Open(path) | |
defer file.Close() | |
if err != nil { | |
panic(err) | |
} | |
var words []string | |
s := bufio.NewScanner(file) | |
s.Split(bufio.ScanLines) | |
for s.Scan() { | |
word := s.Text() | |
if len(word) < 4 { | |
continue | |
} | |
words = append(words, word) | |
} | |
return words | |
} | |
func RandoLetters() []rune { | |
for { | |
var ltrs []rune | |
var vc int | |
rand.Seed(time.Now().UnixNano()) | |
p := rand.Perm(26) | |
for _, r := range p[:7] { | |
if isVowel(Alphabet[r]) { | |
vc++ | |
} | |
ltrs = append(ltrs, Alphabet[r]) | |
} | |
if vc > 1 { | |
return ltrs | |
} | |
} | |
} | |
func checkWord(word string, req rune, charMap map[rune]interface{}) (bool, bool) { | |
hasReq := false | |
seen := make(map[rune]interface{}) | |
for _, ch := range word { | |
if ch == req { | |
hasReq = true | |
} | |
if _, ok := charMap[ch]; !ok { | |
return false, false | |
} else { | |
seen[ch] = struct{}{} | |
} | |
} | |
if len(seen) == 7 { | |
return hasReq, true | |
} else { | |
return hasReq, false | |
} | |
} | |
func isVowel(c rune) bool { | |
return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'y' | |
} | |
func sortLetters(ltrs []rune) string { | |
// pop | |
req, ltrs := ltrs[0], ltrs[1:] | |
sort.Slice(ltrs, func(i, j int) bool { | |
return ltrs[i] < ltrs[j] | |
}) | |
//unshift | |
ltrs = append([]rune{req}, ltrs...) | |
return string(ltrs) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment