AdventOfCode2020/23/main.go

138 lines
2.6 KiB
Go

package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
"time"
)
func main() {
start := time.Now()
partOne()
duration := time.Since(start)
partTwo()
duration2 := time.Since(start)
fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration)
}
func cupInList(cup int, cups []int) bool {
for _, c := range cups {
if c == cup {
return true
}
}
return false
}
func generateFullCupset(cups []int, totalCups int) []int {
for i := len(cups); i < totalCups; i = i + 1 {
cups = append(cups, i)
}
return cups
}
func findTargetCupIndex(cup int, cups []int) int {
for i, c := range cups {
if c == cup {
return i
}
}
return 0 // uh-oh
}
func step(cups []int) []int {
cupCount := len(cups)
currentCup := cups[0]
removedCups := cups[1:4]
newList := make([]int, 0, cupCount)
newList = append([]int{cups[0]}, cups[4:]...)
var targetCup int
if currentCup == 1 {
targetCup = cupCount
} else {
targetCup = currentCup - 1
}
for cupInList(targetCup, removedCups) {
targetCup = targetCup - 1
if targetCup == 0 {
targetCup = cupCount
}
}
tc := findTargetCupIndex(targetCup, newList)
result := make([]int, 0, cupCount)
result = append(result, newList[1:tc+1]...)
result = append(result, removedCups...)
result = append(result, newList[tc+1:]...)
result = append(result, newList[0])
return result
}
func runabout(cups []int) string {
oneIndex := findTargetCupIndex(1, cups)
result := ""
for i := oneIndex + 1; i < len(cups); i = i + 1 {
result = result + strconv.Itoa(cups[i])
}
for i := 0; i < len(cups[:oneIndex]); i = i + 1 {
result = result + strconv.Itoa(cups[i])
}
return result
}
func nextTwo(cups []int) (int, int) {
oneIndex := findTargetCupIndex(1, cups)
if oneIndex+1 > len(cups) {
return cups[0], cups[1]
}
if oneIndex+2 > len(cups) {
return cups[len(cups)], cups[0]
}
return cups[oneIndex+1], cups[oneIndex+2]
}
func partOne() {
f, _ := os.Open("testinput")
reader := bufio.NewReader(f)
scanner := bufio.NewScanner(reader)
cups := []int{}
scanner.Scan()
for _, s := range strings.Split(scanner.Text(), "") {
i, _ := strconv.Atoi(s)
cups = append(cups, i)
}
for i := 0; i < 100; i = i + 1 {
cups = step(cups)
}
fmt.Println(runabout(cups))
}
func partTwo() {
f, _ := os.Open("testinput")
reader := bufio.NewReader(f)
scanner := bufio.NewScanner(reader)
cups := []int{}
scanner.Scan()
for _, s := range strings.Split(scanner.Text(), "") {
i, _ := strconv.Atoi(s)
cups = append(cups, i)
}
allCups := generateFullCupset(cups, 10000000)
for i := 0; i < 10000000; i = i + 1 {
allCups = step(allCups)
fmt.Println(i)
}
fmt.Println(nextTwo(allCups))
}