package main import ( "bufio" "fmt" "log" "os" "strconv" ) const ( locChecksum = iota locSector locName ) func main() { input := stdinToStringSlice() var sectorTotal int for _, h := range input { var chksum, sector, name string var loc int freq := make(map[rune]int) for i := len(h) - 1; i >= 0; i-- { switch h[i] { case ']': // start reading checksum loc = locChecksum case '[': // start reading sector loc = locSector case '-': if loc == locSector { // done with sector loc = locName } default: switch loc { case locChecksum: chksum = string(h[i]) + chksum case locSector: sector = string(h[i]) + sector case locName: name = string(h[i]) + name freq[rune(h[i])]++ } } } fmt.Println(decryptName(name, atoi(sector)), " :: ", sector) var top rune var realChecksum string for i := 0; i < 5; i++ { top, freq = findTop(freq) realChecksum = realChecksum + string(top) } if realChecksum == chksum { sectorTotal += atoi(sector) } } fmt.Println("Sector Total: " + itoa(sectorTotal)) } func decryptName(name string, rot int) string { var decName string for _, v := range name { for k := 0; k < rot; k++ { v++ if v == ('z' + 1) { v = 'a' } } decName = decName + string(v) } return decName } func findTop(inp map[rune]int) (rune, map[rune]int) { var topCnt int var topVal rune for k, v := range inp { if v > topCnt || (v == topCnt && k < topVal) { topCnt = v topVal = k } } delete(inp, topVal) return topVal, inp } func stdinToStringSlice() []string { var input []string scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { input = append(input, scanner.Text()) } return input } func itoa(i int) string { return strconv.Itoa(i) } func atoi(i string) int { var ret int var err error if ret, err = strconv.Atoi(i); err != nil { log.Fatal("Invalid Atoi") } return ret }