diff --git a/23input.txt b/23input.txt index 88666bb..bbac7bc 100644 --- a/23input.txt +++ b/23input.txt @@ -1 +1 @@ -538914762 \ No newline at end of file +538914762 \ No newline at end of file diff --git a/days/day16.go b/days/day16.go index c2e80da..aad5cad 100644 --- a/days/day16.go +++ b/days/day16.go @@ -37,21 +37,21 @@ func atol(val string) int64 { return iVal } -func msDuration(startTime time.Time) float64 { - return float64(time.Since(startTime)) / 1000000 +func msDuration(startTime time.Time) time.Duration { + return time.Since(startTime) } // Day16 runs day 16 func Day16() { start := time.Now() makeList() - log.Printf("Q16MakeList took %fms\n", msDuration(start)) + log.Printf("Q16MakeList took %s\n", msDuration(start)) start = time.Now() part1() - log.Printf("Q16Part1 took %fms\n", msDuration(start)) + log.Printf("Q16Part1 took %s\n", msDuration(start)) start = time.Now() part2() - log.Printf("Q16Part2 took %fms\n", msDuration(start)) + log.Printf("Q16Part2 took %s\n", msDuration(start)) } func makeList() { diff --git a/days/day23.go b/days/day23.go new file mode 100644 index 0000000..dbd6b18 --- /dev/null +++ b/days/day23.go @@ -0,0 +1,133 @@ +package days + +import ( + "fmt" + "io/ioutil" + "log" + "time" +) + +var ( + d23List []int +) + +// Day23 runs day 23 +func Day23() { + start := time.Now() + d23MakeList() + log.Printf("Q23MakeList took %s\n", msDuration(start)) + start = time.Now() + d23Part1() + log.Printf("Q23Part1 took %s\n", msDuration(start)) + start = time.Now() + d23Part2() + log.Printf("Q23Part2 took %s\n", msDuration(start)) +} + +func d23MakeList() { + bytes, err := ioutil.ReadFile("23input.txt") + if err != nil { + panic(err) + } + for _, ch := range string(bytes) { + d23List = append(d23List, int(ch-'0')) + } +} + +func d23Part1() { + + cupList := make([]int, len(d23List)+1) + currIdx := 0 + for i := 0; i < len(d23List); i++ { + cupList[currIdx] = d23List[i] + currIdx = d23List[i] + } + + d23Solve(cupList, 100) + + cup := cupList[1] + scoreStr := "" + for cup != 1 { + scoreStr += fmt.Sprintf("%d", cup) + cup = getNextCup(cupList, cup) + } + + log.Printf("Q23Part1: labels=%s\n", scoreStr) +} + +func d23Part2() { + cupList := make([]int, 1_000_001) + currIdx := 0 + for _, cup := range d23List { + cupList[currIdx] = cup + currIdx = cup + } + highest := 0 + for idx := range d23List { + if cupList[idx] == 0 { + highest = idx + break + } + } + cupList[highest] = len(d23List) + 1 + for i := cupList[highest]; i < len(cupList); i++ { + if i == len(cupList)-1 { + cupList[i] = 0 + } else { + cupList[i] = i + 1 + } + } + + d23Solve(cupList, 10_000_000) + + first := cupList[1] + second := cupList[first] + log.Printf("Q23Part2: first=%d, second=%d, mult=%d", first, second, first*second) +} + +func getNextCup(cupList []int, currCup int) int { + next := cupList[currCup] + if next == 0 { + return getNextCup(cupList, next) + } + + return next +} + +func hasPickedUp(pickedUpCups []int, find int) bool { + for _, val := range pickedUpCups { + if val == find { + return true + } + } + + return false +} + +func d23Solve(cupList []int, iterations int) { + currentCup := cupList[0] + pickedUpCups := make([]int, 3) + for move := 0; move < iterations; move++ { + pickedUp := getNextCup(cupList, currentCup) + nextCup := pickedUp + for i := 0; i < len(pickedUpCups); i++ { + pickedUpCups[i] = nextCup + nextCup = getNextCup(cupList, nextCup) + } + + cupList[currentCup] = nextCup + + destinationCup := currentCup - 1 + for hasPickedUp(pickedUpCups, destinationCup) || destinationCup == 0 { + destinationCup-- + if destinationCup <= 0 { + destinationCup = len(cupList) - 1 + } + } + + oldDestinationNext := getNextCup(cupList, destinationCup) + cupList[destinationCup] = pickedUp + cupList[pickedUpCups[len(pickedUpCups)-1]] = oldDestinationNext + currentCup = getNextCup(cupList, currentCup) + } +} diff --git a/main.go b/main.go index 7f230d9..3486d45 100644 --- a/main.go +++ b/main.go @@ -4,4 +4,5 @@ import "aoc2020/days" func main() { days.Day16() + days.Day23() }