87 lines
1.8 KiB
Go
87 lines
1.8 KiB
Go
package day04
|
|
|
|
import (
|
|
"regexp"
|
|
"sort"
|
|
"strconv"
|
|
"tools"
|
|
)
|
|
|
|
var roomRegexp = regexp.MustCompile(`^(.*)-([[:digit:]]+)\[(.*)]$`)
|
|
|
|
func validateChecksum(roomname, checksum string) bool {
|
|
charcount := make(map[int32]int)
|
|
for _, c := range roomname {
|
|
if c != '-' {
|
|
charcount[c]++
|
|
}
|
|
}
|
|
|
|
charcountReverse := make(map[int]tools.ByteSlice)
|
|
counts := tools.NewSetInt()
|
|
for c, v := range charcount {
|
|
counts.Add(v)
|
|
charcountReverse[v] = append(charcountReverse[v], byte(c))
|
|
}
|
|
|
|
countList := counts.Keys()
|
|
sort.Sort(sort.Reverse(countList))
|
|
|
|
calcChecksum := ""
|
|
for _, v := range countList {
|
|
charList := charcountReverse[v]
|
|
sort.Sort(charList)
|
|
for _, c := range charList {
|
|
calcChecksum += string(c)
|
|
}
|
|
}
|
|
|
|
return checksum == calcChecksum[:5]
|
|
}
|
|
|
|
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
|
sectorSum := 0
|
|
for _, line := range puzzle.GetInputArray() {
|
|
roomMatches := roomRegexp.FindStringSubmatch(line)
|
|
roomName := roomMatches[1]
|
|
roomSectorId, _ := strconv.Atoi(roomMatches[2])
|
|
roomChecksum := roomMatches[3]
|
|
|
|
if validateChecksum(roomName, roomChecksum) {
|
|
sectorSum += roomSectorId
|
|
}
|
|
}
|
|
|
|
return sectorSum
|
|
}
|
|
|
|
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
|
for _, line := range puzzle.GetInputArray() {
|
|
roomMatches := roomRegexp.FindStringSubmatch(line)
|
|
roomName := roomMatches[1]
|
|
roomSectorId, _ := strconv.Atoi(roomMatches[2])
|
|
roomChecksum := roomMatches[3]
|
|
|
|
if validateChecksum(roomName, roomChecksum) {
|
|
addNum := int32(roomSectorId) % 26
|
|
realName := ""
|
|
for _, c := range roomName {
|
|
switch c {
|
|
case '-':
|
|
realName += " "
|
|
default:
|
|
for c+addNum > 122 {
|
|
c -= 26
|
|
}
|
|
realName += string(c + addNum)
|
|
}
|
|
}
|
|
if realName == "northpole object storage" {
|
|
return roomSectorId
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1
|
|
}
|