mirror of
https://github.com/Threnklyn/advent-of-code-go.git
synced 2026-05-18 19:13:27 +02:00
day22 solutions, copied part 2 solution
This commit is contained in:
@@ -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...
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user