diff --git a/day14/day.go b/day14/day.go new file mode 100644 index 0000000..1595957 --- /dev/null +++ b/day14/day.go @@ -0,0 +1,77 @@ +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) +} diff --git a/day15/day.go b/day15/day.go new file mode 100644 index 0000000..5a81e5d --- /dev/null +++ b/day15/day.go @@ -0,0 +1,70 @@ +package day15 + +import ( + "regexp" + "strconv" + "tools" +) + +type Disc struct { + posCount int + initPos int +} + +func parseInput(inp []string, part2 bool) map[int]Disc { + discs := make(map[int]Disc) + parserRegex := regexp.MustCompile(".*has ([0-9]+) positions.*at position ([0-9]+).") + for i, s := range inp { + parts := parserRegex.FindStringSubmatch(s) + pc, _ := strconv.Atoi(parts[1]) + ip, _ := strconv.Atoi(parts[2]) + discs[i] = Disc{pc, ip} + if part2 { + discs[i+1] = Disc{11, 0} + } + } + + return discs +} + +func Part1(puzzle tools.AoCPuzzle) interface{} { + discs := parseInput(puzzle.GetInputArray(), false) + + tIndex := -1 + for { + tIndex++ + failed := false + for i, d := range discs { + if !((d.initPos+tIndex+i+1)%d.posCount == 0) { + failed = true + break + } + } + if !failed { + break + } + } + + return tIndex +} + +func Part2(puzzle tools.AoCPuzzle) interface{} { + discs := parseInput(puzzle.GetInputArray(), true) + + tIndex := -1 + for { + tIndex++ + failed := false + for i, d := range discs { + if !((d.initPos+tIndex+i+1)%d.posCount == 0) { + failed = true + break + } + } + if !failed { + break + } + } + + return tIndex +} diff --git a/inputs/14 b/inputs/14 new file mode 100644 index 0000000..67e5820 --- /dev/null +++ b/inputs/14 @@ -0,0 +1 @@ +ahsbgdzn \ No newline at end of file diff --git a/inputs/14_test b/inputs/14_test new file mode 100644 index 0000000..f2ba8f8 --- /dev/null +++ b/inputs/14_test @@ -0,0 +1 @@ +abc \ No newline at end of file diff --git a/inputs/15 b/inputs/15 new file mode 100644 index 0000000..3a43457 --- /dev/null +++ b/inputs/15 @@ -0,0 +1,6 @@ +Disc #1 has 13 positions; at time=0, it is at position 1. +Disc #2 has 19 positions; at time=0, it is at position 10. +Disc #3 has 3 positions; at time=0, it is at position 2. +Disc #4 has 7 positions; at time=0, it is at position 1. +Disc #5 has 5 positions; at time=0, it is at position 3. +Disc #6 has 17 positions; at time=0, it is at position 5. \ No newline at end of file diff --git a/inputs/15_test b/inputs/15_test new file mode 100644 index 0000000..b65eea1 --- /dev/null +++ b/inputs/15_test @@ -0,0 +1,2 @@ +Disc #1 has 5 positions; at time=0, it is at position 4. +Disc #2 has 2 positions; at time=0, it is at position 1. \ No newline at end of file diff --git a/main.go b/main.go index 3307921..0bc58cb 100644 --- a/main.go +++ b/main.go @@ -13,6 +13,8 @@ import ( "aoc2016/day10" "aoc2016/day12" "aoc2016/day13" + "aoc2016/day14" + "aoc2016/day15" "flag" "fmt" "os" @@ -43,8 +45,8 @@ func initDayFunctions() { // 11: {1: day11.Part1, 2: day11.Part2}, 12: {1: day12.Part1, 2: day12.Part2}, 13: {1: day13.Part1, 2: day13.Part2}, - // 14: {1: day14.Part1, 2: day14.Part2}, - // 15: {1: day15.Part1, 2: day15.Part2}, + 14: {1: day14.Part1, 2: day14.Part2}, + 15: {1: day15.Part1, 2: day15.Part2}, // 16: {1: day16.Part1, 2: day16.Part2}, // 17: {1: day17.Part1, 2: day17.Part2}, // 18: {1: day18.Part1, 2: day18.Part2},