adventofcode/2016/day14/main.go

83 lines
1.6 KiB
Go

package main
import (
"crypto/md5"
"fmt"
"log"
"os"
"strconv"
"strings"
)
var hashStore []string
var salt string
func main() {
if len(os.Args) < 3 {
fmt.Println("Usage: ./day14 <salt> <key-num>")
fmt.Println(" My input: ./day14 cuanljph 64")
os.Exit(1)
}
salt = os.Args[1]
keyNum := atoi(os.Args[2])
var foundKeys []string
tryIdx := 0
for len(foundKeys) < keyNum {
tst := getHash(tryIdx)
for i := range tst {
if len(tst) > i+3 {
if tst[i:i+3] == strings.Repeat(string(tst[i]), 3) {
// Found a triple, search the next 1000 for a quintuple
if searchForQuint(salt, tryIdx+1, string(tst[i])) {
foundKeys = append(foundKeys, tst)
}
// Once we test the first triplet, we're done with this one
break
}
}
}
tryIdx++
}
fmt.Println("Key:", getHash(tryIdx-1), "Idx:", tryIdx)
}
func getHash(idx int) string {
for len(hashStore)-1 < idx {
hashStore = append(
hashStore,
getStretchedHash(fmt.Sprintf("%x", md5.Sum([]byte(salt+itoa(len(hashStore)+1))))),
)
}
return hashStore[idx]
}
func getStretchedHash(s string) string {
for i := 0; i < 2016; i++ {
s = fmt.Sprintf("%x", md5.Sum([]byte(s)))
}
return s
}
func searchForQuint(salt string, startIdx int, srch string) bool {
for i := startIdx; i <= startIdx+1000; i++ {
tst := getHash(i)
if strings.Contains(tst, strings.Repeat(srch, 5)) {
return true
}
}
return false
}
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
}
func itoa(i int) string {
return strconv.Itoa(i)
}