package main import ( "fmt" "github.com/dariubs/percent" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/plotutil" "gonum.org/v1/plot/vg" "io/ioutil" "log" "sort" "strings" ) type letter struct { upperCase string lowerCase string count int frequency float64 } type letterList []letter func (l letterList) Len() int { return len(l) } func (l letterList) Less(i, j int) bool { return l[i].frequency > l[j].frequency } func (l letterList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } const LettersInTheAlphabet = 26 var alphabet = [LettersInTheAlphabet]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', } var letters = make([]letter, LettersInTheAlphabet) func initLetterStruct() { for index := range alphabet { letters[index].upperCase = string(alphabet[index]) letters[index].lowerCase = string(alphabet[index] + 32) } } func readFile(relativePath string) string { content, err := ioutil.ReadFile(relativePath) if err != nil { log.Fatalln(err) } return string(content) } func countLetters(inputText string) int { totalCount := 0 for index := range alphabet { letters[index].count += strings.Count(inputText, letters[index].lowerCase) + strings.Count(inputText, letters[index].upperCase) totalCount += letters[index].count } return totalCount } func calculateFrequency(totalCount int) { for index := range alphabet { letters[index].frequency = percent.PercentOf(letters[index].count, totalCount) } } func printResult() { for index := range alphabet { l := letters[index] fmt.Printf( "The letter %s (%s) occurs %d times in the text and the frequencyArray in percent is %0.2f\n", l.upperCase, l.lowerCase, l.count, l.frequency, ) } } func plotResult() { var count plotter.Values for index := range alphabet { count = append(count, float64(letters[index].count)) } p := plot.New() p.Title.Text = "Letter count" p.X.Label.Text = "letter" p.Y.Label.Text = "count" countBars, err := plotter.NewBarChart(count, vg.Points(LettersInTheAlphabet/2)) countBars.Color = plotutil.Color(2) if err != nil { log.Fatalln(err) } p.Add(countBars) var xAxisNaming []string for index := range letters { xAxisNaming = append(xAxisNaming, letters[index].upperCase) } p.NominalX(xAxisNaming...) if err := p.Save(25*vg.Centimeter, 15*vg.Centimeter, "barChart.png"); err != nil { log.Fatalln(err) } } func main() { initLetterStruct() //totalCount := countLetters(readFile("plaintext.txt")) totalCount := countLetters(readFile("../part01-encrypt/output.txt")) calculateFrequency(totalCount) plotResult() sort.Sort(letterList(letters)) printResult() }