day22 solutions, copied part 2 solution

This commit is contained in:
alexchao26
2020-08-11 20:52:24 -04:00
parent 0a3e7f8fab
commit 5d6f75ea0a
3 changed files with 188 additions and 1 deletions
+1
View File
@@ -28,3 +28,4 @@ Day | Name | Type of Algo & Notes
19 | Tractor Beam | - Another Intcode outputting to a 2D grid <br> - __THERE NEEDS TO BE A CONVENTION FOR X AND Y WHEN WORKING WITH 2D GRIDS__ This is awful, should it be mathematical? Should it represent rows and columns? Who knows?! <br> - Little geometry (drawing squares) for part2 but nothing crazy
20 | Donut Maze | __Breadth first search__ path finding algo. Dijkstra's Algorithm to find the shortest path given a maze with "portals." <br> Part 2 is kind of wild with the maze become 3D, but the solution is effectively the same, just more complex to implement <br> - I remapped this in my head to more of a 3D cube instead of a donut... <br> - That was really cool to get working... Dare I say fun...
21 | Springdroid Adventure | Another simple-ish Intcode based problem, this time using some weird __Assembly language__ that gets inputs via writing ASCII values to the Intcode computer.
22 | Slam Shuffle | - Seems fairly easy at first... But the part 2 has numbers somewhere in the 32-bit number to 64-bit number range... So the part 1 code is pretty much useless...
+96
View File
@@ -0,0 +1,96 @@
package main
import (
"adventofcode/util"
"fmt"
"strconv"
"strings"
)
type instruction struct {
name string // name of instruction
number int // number
}
func main() {
input := util.ReadFile("../input.txt")
lines := strings.Split(input, "\n")
// make slice of all instructions
instructions := make([]instruction, len(lines))
for i, line := range lines {
splitLine := strings.Split(line, " ")
if splitLine[len(splitLine)-1] == "stack" {
instructions[i] = instruction{name: "deal into new stack"}
} else {
name := strings.Join(splitLine[0:len(splitLine)-1], " ")
num, _ := strconv.Atoi(splitLine[len(splitLine)-1])
instructions[i] = instruction{
name,
num,
}
}
}
// make the deck
deck := make([]int, 10007)
for i := range deck {
deck[i] = i
}
// iterate through instructions and apply the correct function to the deck
for _, inst := range instructions {
switch inst.name {
case "deal into new stack":
deck = dealIntoNewStack(deck)
case "deal with increment":
deck = dealWithIncrement(deck, inst.number)
case "cut":
deck = cut(deck, inst.number)
}
}
// Find the 2019 card and print its index
for i, v := range deck {
if v == 2019 {
fmt.Println("position of card 2019 is", i)
}
}
}
// side effects to handle "deal into new stack" command
func dealIntoNewStack(deck []int) []int {
// effectively just reverses the entire deck..
for i := 0; i < len(deck)/2; i++ {
deck[i], deck[len(deck)-1-i] = deck[len(deck)-1-i], deck[i]
}
// technically changed by side effects but will keep syntax similar
return deck
}
// index could be negative
func cut(deck []int, index int) []int {
newDeck := make([]int, len(deck))
if index < 0 {
index = len(deck) + index
}
for i := 0; i < len(deck); i++ {
newDeck[i] = deck[(i+index)%len(deck)]
}
return newDeck
}
func dealWithIncrement(deck []int, jump int) []int {
newDeck := make([]int, len(deck))
for i := 0; i < len(deck); i++ {
newDeckIndex := jump * i % len(deck)
newDeck[newDeckIndex] = deck[i]
}
return newDeck
}
+90
View File
@@ -0,0 +1,90 @@
package main
import (
"fmt"
"io/ioutil"
"math/big"
"strconv"
"strings"
)
const CmdDeal string = "deal into new stack"
const CmdCutN string = "cut"
const CmdDealN string = "deal with increment"
func MatchCmd(cmd, cmdToMatch string) (bool, int) {
if len(cmd) < len(cmdToMatch) || cmd[:len(cmdToMatch)] != cmdToMatch {
return false, 0
}
if len(cmd) == len(cmdToMatch) {
return true, 0
}
i := strings.LastIndex(cmd, " ")
x := cmd[i+1:]
n, err := strconv.Atoi(x)
if err != nil {
panic(err)
}
return true, n
}
func ReadCommands(path string) []string {
dat, err := ioutil.ReadFile(path)
if err != nil {
panic(err)
}
dat = dat[:len(dat)]
txt := string(dat)
txt = strings.TrimRight(txt, "\n")
lines := strings.Split(txt, "\n")
return lines
}
func IndexShuffle(index int64, l int64, times int64, cmds []string) int64 {
v := big.NewInt(index)
m := big.NewInt(l)
t := big.NewInt(times)
i := big.NewInt(0)
d := big.NewInt(1)
for _, cmd := range cmds {
if cmd == CmdDeal {
d.Neg(d)
i.Add(i, d)
} else if ok, n := MatchCmd(cmd, CmdCutN); ok {
x := big.NewInt(int64(n))
i.Add(i, x.Mul(x, d))
} else if ok, n := MatchCmd(cmd, CmdDealN); ok {
x := big.NewInt(int64(n))
x.ModInverse(x, m)
d.Mul(d, x)
}
}
// (1-d)**(m-2) % m
a := big.NewInt(1)
a.Sub(a, d).ModInverse(a, m)
// d = d**t % m
d.Exp(d, t, m)
// it = (1-d) * a * i
it := big.NewInt(1)
it.Sub(it, d).Mul(it, a).Mul(it, i)
v.Mul(v, d).Add(v, it).Mod(v, m)
return v.Int64()
}
func main() {
cmds := ReadCommands("../input.txt")
l := int64(119315717514047)
times := int64(101741582076661)
index := IndexShuffle(2020, l, times, cmds)
fmt.Println(index)
}