package main import "strings" import "strconv" import "bufio" import "sort" import "fmt" import "os" type KeyValue struct { Key rune Value int } type KeyValues []KeyValue func (this KeyValues) Len() int { return len(this) } func (this KeyValues) Swap(i, j int) { tmp := this[i] this[i] = this[j] this[j] = tmp } func (this KeyValues) Less(i, j int) bool { if this[i].Value == this[j].Value { return this[i].Key > this[j].Key } return this[i].Value < this[j].Value } type Room struct { EncryptedName string DecryptedName string Checksum string RoomId int } func shiftRune(r rune, shift int) string { if r == '-' { return " " } res := int(r) +shift if res > 'z' { res = res - 'z' + 'a' -1 } return string(res) } func NewRoom(roomName string, sectorId int) Room { var result Room letters := make(map[rune]int) letterShift := sectorId %26 result.EncryptedName = roomName for _, l := range(roomName) { if (l != '-') { letters[l] ++ } result.DecryptedName += shiftRune(l, letterShift) } sortedLetters := make(KeyValues, len(letters)) i := 0 for k, v := range letters { sortedLetters[i] = KeyValue{k, v} i++ } sort.Sort(sort.Reverse(sortedLetters)) for i =0; i < 5; i++ { result.Checksum += string(sortedLetters[i].Key) } result.RoomId = sectorId return result } func (this Room) isValid(checksum string) bool { return this.Checksum == checksum } func parseLine(line string) (Room, string) { words := strings.FieldsFunc(line, func(r rune) bool { return (r == '-' || r == '[' || r == ']') }) checkSum := words[len(words) -1] sectorId, _ := strconv.Atoi(words[len(words) -2]) words = words[:len(words) -2] var roomName string first := true for word := range(words) { if (first) { first = false } else { roomName += "-" } roomName += words[word] } return NewRoom(roomName, sectorId), checkSum } func main() { reader := bufio.NewReader(os.Stdin) valid := 0 for true { line, _, err := reader.ReadLine() if string(line) != "" { room, checkSum := parseLine(string(line)) if room.isValid(checkSum) { valid += room.RoomId if strings.Contains(room.DecryptedName, "northpole") { fmt.Println("Found `North Pole objects` secret room: " +strconv.Itoa(room.RoomId)) } } } if err != nil { break } } fmt.Println(valid) }