138 lines
2.6 KiB
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))
|
||
|
}
|