adventofcode/2016/day04/main.go

109 lines
1.9 KiB
Go

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
}