package day14 import ( "crypto/md5" "fmt" "strconv" "tools" ) func generateHashes(hashmap map[int][]byte, salt string, start, end int, stretch bool) map[int][]byte { for i := start; i <= end; i++ { thisSalt := salt + strconv.Itoa(i) if _, ok := hashmap[i]; ok { continue } if !stretch { hashmap[i] = []byte(fmt.Sprintf("%x", md5.Sum([]byte(thisSalt)))) } else { hash := fmt.Sprintf("%x", md5.Sum([]byte(thisSalt))) for i := 0; i < 2016; i++ { hash = fmt.Sprintf("%x", md5.Sum([]byte(hash))) } hashmap[i] = []byte(hash) } } return hashmap } func getIndexForKeys(salt string, needKeys int, stretch bool) int { hashmap := make(map[int][]byte) keyCount := 0 index := -1 for keyCount < needKeys { index++ hashmap = generateHashes(hashmap, salt, index, index+1000, stretch) foundKey := false for i := 0; i < len(hashmap[index])-2; i++ { c := hashmap[index][i] if c == hashmap[index][i+1] && c == hashmap[index][i+2] { for j := 1; j <= 1000; j++ { hash := hashmap[index+j] for k := 1; k < len(hash)-5; k++ { if c != hash[k] { continue } if hash[k+1] == c && hash[k+2] == c && hash[k+3] == c && hash[k+4] == c { foundKey = true keyCount++ break } } } break } if foundKey { break } } } return index } func Part1(puzzle tools.AoCPuzzle) interface{} { salt := puzzle.GetInputArray()[0] return getIndexForKeys(salt, 64, false) } func Part2(puzzle tools.AoCPuzzle) interface{} { salt := puzzle.GetInputArray()[0] return getIndexForKeys(salt, 64, true) }