adventofcode/2019/day22/main.go

102 lines
2.1 KiB
Go

package main
import (
"fmt"
"math/big"
"strconv"
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
)
func main() {
pt := helpers.GetArgNumber(1)
inp := helpers.StdinToStringSlice()
if pt == "1" {
part1(inp)
} else {
part2(inp)
}
}
func NewDeck(n int) []int {
s := make([]int, n)
for i := 0; i < n; i++ {
s[i] = i
}
return s
}
func deal(s []int) []int {
s2 := make([]int, len(s))
for i := range s {
s2[len(s)-1-i] = s[i]
}
return s2
}
func cut(s []int, n int) []int {
if n >= 0 {
return append(s[n:], s[:n]...)
}
n = -n
return append(s[len(s)-n:], s[:len(s)-n]...)
}
func dealn(s []int, n int) []int {
s2 := make([]int, len(s))
for i := range s {
s2[(i*n)%len(s)] = s[i]
}
return s2
}
func part1(inp []string) {
s := NewDeck(10007)
for _, line := range inp {
if line == "deal into new stack" {
s = deal(s)
} else if line[:3] == "cut" {
i, _ := strconv.Atoi(line[4:])
s = cut(s, i)
} else if line[:19] == "deal with increment" {
i, _ := strconv.Atoi(line[20:])
s = dealn(s, i)
}
}
for i, v := range s {
if v == 2019 {
fmt.Println(i)
return
}
}
}
func part2(inp []string) {
deckSize := big.NewInt(119315717514047)
shuffles := big.NewInt(101741582076661)
off, inc := big.NewInt(0), big.NewInt(1)
for _, line := range inp {
if line == "deal into new stack" {
inc.Mul(inc, big.NewInt(-1))
off.Add(off, inc)
} else if line[:3] == "cut" {
i, _ := strconv.Atoi(line[4:])
off.Add(off, big.NewInt(0).Mul(big.NewInt(int64(i)), inc))
} else if line[:19] == "deal with increment" {
i, _ := strconv.Atoi(line[20:])
inc.Mul(inc, big.NewInt(0).Exp(big.NewInt(int64(i)), big.NewInt(0).Sub(deckSize, big.NewInt(2)), deckSize))
}
}
lastInc := big.NewInt(0).Exp(inc, shuffles, deckSize)
lastOff := big.NewInt(0).Exp(inc, shuffles, deckSize)
lastOff.Sub(big.NewInt(1), lastOff)
mod := big.NewInt(0).Exp(big.NewInt(0).Sub(big.NewInt(1), inc), big.NewInt(0).Sub(deckSize, big.NewInt(2)), deckSize)
lastOff.Mul(lastOff, mod)
lastOff.Mul(lastOff, off)
res := big.NewInt(0).Mul(big.NewInt(2020), lastInc)
res.Add(res, lastOff)
res.Mod(res, deckSize)
fmt.Println("Result:", res)
}