102 lines
2.1 KiB
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)
|
||
|
}
|