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
}
