2017 Day 16 & Day 17 Complete
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -50,3 +50,6 @@ _testmain.go
 | 
			
		||||
*/day23/day23
 | 
			
		||||
*/day24/day24
 | 
			
		||||
*/day25/day25
 | 
			
		||||
 | 
			
		||||
# And my "You got it wrong" timer
 | 
			
		||||
timer
 | 
			
		||||
 
 | 
			
		||||
@@ -15,24 +15,33 @@ func main() {
 | 
			
		||||
	iters := 1000000000
 | 
			
		||||
	if len(os.Args) > 1 {
 | 
			
		||||
		length = Atoi(os.Args[1])
 | 
			
		||||
		if len(os.Args) > 2 {
 | 
			
		||||
			iters = Atoi(os.Args[2])
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Create a starting string
 | 
			
		||||
	for i := 0; i < length; i++ {
 | 
			
		||||
		progs += string('a' + i)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inp := StdinToString()
 | 
			
		||||
	moves := strings.Split(inp, ",")
 | 
			
		||||
	for i := 0; i < iters; i++ {
 | 
			
		||||
		if i%(iters/100) == 0 {
 | 
			
		||||
			// Clear the screen
 | 
			
		||||
			fmt.Print("\033[H\033[2J")
 | 
			
		||||
			// Percent Complete
 | 
			
		||||
			fResult := ((float64(i) / float64(iters)) * 100)
 | 
			
		||||
			sResult2 := strconv.FormatFloat(fResult, 'f', 2, 64)
 | 
			
		||||
			fmt.Println(sResult2)
 | 
			
		||||
 | 
			
		||||
	var loopEnd int
 | 
			
		||||
	var state []string
 | 
			
		||||
	doneProgs := progs
 | 
			
		||||
	state = append(state, progs)
 | 
			
		||||
	for loopEnd = 1; loopEnd < (iters / 2); loopEnd++ {
 | 
			
		||||
		doneProgs = doDance(doneProgs, moves)
 | 
			
		||||
		state = append(state, doneProgs)
 | 
			
		||||
		if doneProgs == progs {
 | 
			
		||||
			fmt.Println("Loops at", loopEnd)
 | 
			
		||||
			pos := (iters / loopEnd) * loopEnd
 | 
			
		||||
			fmt.Println("Final State", state[iters-pos])
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		progs = doDance(progs, moves)
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Println(progs)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func doDance(progs string, moves []string) string {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										78
									
								
								2017/day16/problem
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								2017/day16/problem
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
Advent of Code
 | 
			
		||||
 | 
			
		||||
--- Day 16: Permutation Promenade ---
 | 
			
		||||
 | 
			
		||||
   You come upon a very unusual sight; a group of programs here appear to be
 | 
			
		||||
   dancing.
 | 
			
		||||
 | 
			
		||||
   There are sixteen programs in total, named a through p. They start by
 | 
			
		||||
   standing in a line: a stands in position 0, b stands in position 1, and so on
 | 
			
		||||
   until p, which stands in position 15.
 | 
			
		||||
 | 
			
		||||
   The programs' dance consists of a sequence of dance moves:
 | 
			
		||||
 | 
			
		||||
     * Spin, written sX, makes X programs move from the end to the front, but
 | 
			
		||||
       maintain their order otherwise. (For example, s3 on abcde produces
 | 
			
		||||
       cdeab).
 | 
			
		||||
     * Exchange, written xA/B, makes the programs at positions A and B swap
 | 
			
		||||
       places.
 | 
			
		||||
     * Partner, written pA/B, makes the programs named A and B swap places.
 | 
			
		||||
 | 
			
		||||
   For example, with only five programs standing in a line (abcde), they could
 | 
			
		||||
   do the following dance:
 | 
			
		||||
 | 
			
		||||
     * s1, a spin of size 1: eabcd.
 | 
			
		||||
     * x3/4, swapping the last two programs: eabdc.
 | 
			
		||||
     * pe/b, swapping programs e and b: baedc.
 | 
			
		||||
 | 
			
		||||
   After finishing their dance, the programs end up in order baedc.
 | 
			
		||||
 | 
			
		||||
   You watch the dance for a while and record their dance moves (your puzzle
 | 
			
		||||
   input). In what order are the programs standing after their dance?
 | 
			
		||||
 | 
			
		||||
   Your puzzle answer was ________________.
 | 
			
		||||
 | 
			
		||||
--- Part Two ---
 | 
			
		||||
 | 
			
		||||
   Now that you're starting to get a feel for the dance moves, you turn your
 | 
			
		||||
   attention to the dance as a whole.
 | 
			
		||||
 | 
			
		||||
   Keeping the positions they ended up in from their previous dance, the
 | 
			
		||||
   programs perform it again and again: including the first dance, a total of
 | 
			
		||||
   one billion (1000000000) times.
 | 
			
		||||
 | 
			
		||||
   In the example above, their second dance would begin with the order baedc,
 | 
			
		||||
   and use the same dance moves:
 | 
			
		||||
 | 
			
		||||
     * s1, a spin of size 1: cbaed.
 | 
			
		||||
     * x3/4, swapping the last two programs: cbade.
 | 
			
		||||
     * pe/b, swapping programs e and b: ceadb.
 | 
			
		||||
 | 
			
		||||
   In what order are the programs standing after their billion dances?
 | 
			
		||||
 | 
			
		||||
   Your puzzle answer was ________________.
 | 
			
		||||
 | 
			
		||||
   Both parts of this puzzle are complete! They provide two gold stars: **
 | 
			
		||||
 | 
			
		||||
   At this point, you should return to your advent calendar and try another
 | 
			
		||||
   puzzle.
 | 
			
		||||
 | 
			
		||||
   If you still want to see it, you can get your puzzle input.
 | 
			
		||||
 | 
			
		||||
References
 | 
			
		||||
 | 
			
		||||
   Visible links
 | 
			
		||||
   . http://adventofcode.com/
 | 
			
		||||
   . http://adventofcode.com/2017/about
 | 
			
		||||
   . http://adventofcode.com/2017/support
 | 
			
		||||
   . http://adventofcode.com/2017/events
 | 
			
		||||
   . http://adventofcode.com/2017/settings
 | 
			
		||||
   . http://adventofcode.com/2017/auth/logout
 | 
			
		||||
   . http://adventofcode.com/2017
 | 
			
		||||
   . http://adventofcode.com/2017
 | 
			
		||||
   . http://adventofcode.com/2017/leaderboard
 | 
			
		||||
   . http://adventofcode.com/2017/stats
 | 
			
		||||
   . http://adventofcode.com/2017/sponsors
 | 
			
		||||
   . http://adventofcode.com/2017/sponsors
 | 
			
		||||
   . http://adventofcode.com/2017
 | 
			
		||||
   . http://adventofcode.com/2017/day/16/input
 | 
			
		||||
							
								
								
									
										57
									
								
								2017/day17/day17.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								2017/day17/day17.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	inp := 301
 | 
			
		||||
	tgt := 50000000
 | 
			
		||||
	if len(os.Args) > 2 {
 | 
			
		||||
		inp = Atoi(os.Args[1])
 | 
			
		||||
		tgt = Atoi(os.Args[2])
 | 
			
		||||
	} else if len(os.Args) > 1 {
 | 
			
		||||
		fmt.Println("Usage: day17 [skip] [target]")
 | 
			
		||||
		fmt.Println("If you provide one argument, you must provide both")
 | 
			
		||||
	}
 | 
			
		||||
	spinLock := []int{0}
 | 
			
		||||
	var addPos int
 | 
			
		||||
	for i := 1; i <= tgt; i++ {
 | 
			
		||||
		addPos = (addPos + inp) % len(spinLock)
 | 
			
		||||
		// Unless we're adding it after the 0, we don't care, just append it.
 | 
			
		||||
		if addPos == 0 {
 | 
			
		||||
			addPos++
 | 
			
		||||
			spinLock = Insert(spinLock, i, addPos)
 | 
			
		||||
		} else {
 | 
			
		||||
			addPos++
 | 
			
		||||
			spinLock = append(spinLock, i)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Println(spinLock[0:0+5], "...")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Insert(slice []int, val, at int) []int {
 | 
			
		||||
	var ret []int
 | 
			
		||||
	pt1 := slice[:at]
 | 
			
		||||
	pt2 := slice[at:]
 | 
			
		||||
	for i := 0; i < len(pt1); i++ {
 | 
			
		||||
		ret = append(ret, pt1[i])
 | 
			
		||||
	}
 | 
			
		||||
	ret = append(ret, val)
 | 
			
		||||
	for i := 0; i < len(pt2); i++ {
 | 
			
		||||
		ret = append(ret, pt2[i])
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Atoi(i string) int {
 | 
			
		||||
	var ret int
 | 
			
		||||
	var err error
 | 
			
		||||
	if ret, err = strconv.Atoi(i); err != nil {
 | 
			
		||||
		log.Fatal("Invalid Atoi")
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										103
									
								
								2017/day17/problem
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								2017/day17/problem
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
Advent of Code
 | 
			
		||||
 | 
			
		||||
--- Day 17: Spinlock ---
 | 
			
		||||
 | 
			
		||||
   Suddenly, whirling in the distance, you notice what looks like a massive,
 | 
			
		||||
   pixelated hurricane: a deadly spinlock. This spinlock isn't just consuming
 | 
			
		||||
   computing power, but memory, too; vast, digital mountains are being ripped
 | 
			
		||||
   from the ground and consumed by the vortex.
 | 
			
		||||
 | 
			
		||||
   If you don't move quickly, fixing that printer will be the least of your
 | 
			
		||||
   problems.
 | 
			
		||||
 | 
			
		||||
   This spinlock's algorithm is simple but efficient, quickly consuming
 | 
			
		||||
   everything in its path. It starts with a circular buffer containing only the
 | 
			
		||||
   value 0, which it marks as the current position. It then steps forward
 | 
			
		||||
   through the circular buffer some number of steps (your puzzle input) before
 | 
			
		||||
   inserting the first new value, 1, after the value it stopped on. The inserted
 | 
			
		||||
   value becomes the current position. Then, it steps forward from there the
 | 
			
		||||
   same number of steps, and wherever it stops, inserts after it the second new
 | 
			
		||||
   value, 2, and uses that as the new current position again.
 | 
			
		||||
 | 
			
		||||
   It repeats this process of stepping forward, inserting a new value, and using
 | 
			
		||||
   the location of the inserted value as the new current position a total of
 | 
			
		||||
   2017 times, inserting 2017 as its final operation, and ending with a total of
 | 
			
		||||
   2018 values (including 0) in the circular buffer.
 | 
			
		||||
 | 
			
		||||
   For example, if the spinlock were to step 3 times per insert, the circular
 | 
			
		||||
   buffer would begin to evolve like this (using parentheses to mark the current
 | 
			
		||||
   position after each iteration of the algorithm):
 | 
			
		||||
 | 
			
		||||
     * (0), the initial state before any insertions.
 | 
			
		||||
     * 0 (1): the spinlock steps forward three times (0, 0, 0), and then inserts
 | 
			
		||||
       the first value, 1, after it. 1 becomes the current position.
 | 
			
		||||
     * 0 (2) 1: the spinlock steps forward three times (0, 1, 0), and then
 | 
			
		||||
       inserts the second value, 2, after it. 2 becomes the current position.
 | 
			
		||||
     * 0  2 (3) 1: the spinlock steps forward three times (1, 0, 2), and then
 | 
			
		||||
       inserts the third value, 3, after it. 3 becomes the current position.
 | 
			
		||||
 | 
			
		||||
   And so on:
 | 
			
		||||
 | 
			
		||||
     * 0  2 (4) 3  1
 | 
			
		||||
     * 0 (5) 2  4  3  1
 | 
			
		||||
     * 0  5  2  4  3 (6) 1
 | 
			
		||||
     * 0  5 (7) 2  4  3  6  1
 | 
			
		||||
     * 0  5  7  2  4  3 (8) 6  1
 | 
			
		||||
     * 0 (9) 5  7  2  4  3  8  6  1
 | 
			
		||||
 | 
			
		||||
   Eventually, after 2017 insertions, the section of the circular buffer near
 | 
			
		||||
   the last insertion looks like this:
 | 
			
		||||
 | 
			
		||||
 1512  1134  151 (2017) 638  1513  851
 | 
			
		||||
 | 
			
		||||
   Perhaps, if you can identify the value that will ultimately be after the last
 | 
			
		||||
   value written (2017), you can short-circuit the spinlock. In this example,
 | 
			
		||||
   that would be 638.
 | 
			
		||||
 | 
			
		||||
   What is the value after 2017 in your completed circular buffer?
 | 
			
		||||
 | 
			
		||||
   Your puzzle answer was ________.
 | 
			
		||||
 | 
			
		||||
--- Part Two ---
 | 
			
		||||
 | 
			
		||||
   The spinlock does not short-circuit. Instead, it gets more angry. At least,
 | 
			
		||||
   you assume that's what happened; it's spinning significantly faster than it
 | 
			
		||||
   was a moment ago.
 | 
			
		||||
 | 
			
		||||
   You have good news and bad news.
 | 
			
		||||
 | 
			
		||||
   The good news is that you have improved calculations for how to stop the
 | 
			
		||||
   spinlock. They indicate that you actually need to identify the value after 0
 | 
			
		||||
   in the current state of the circular buffer.
 | 
			
		||||
 | 
			
		||||
   The bad news is that while you were determining this, the spinlock has just
 | 
			
		||||
   finished inserting its fifty millionth value (50000000).
 | 
			
		||||
 | 
			
		||||
   What is the value after 0 the moment 50000000 is inserted?
 | 
			
		||||
 | 
			
		||||
   Your puzzle answer was _____________.
 | 
			
		||||
 | 
			
		||||
   Both parts of this puzzle are complete! They provide two gold stars: **
 | 
			
		||||
 | 
			
		||||
   At this point, you should return to your advent calendar and try another
 | 
			
		||||
   puzzle.
 | 
			
		||||
 | 
			
		||||
   Your puzzle input was 301.
 | 
			
		||||
 | 
			
		||||
References
 | 
			
		||||
 | 
			
		||||
   Visible links
 | 
			
		||||
   . http://adventofcode.com/
 | 
			
		||||
   . http://adventofcode.com/2017/about
 | 
			
		||||
   . http://adventofcode.com/2017/support
 | 
			
		||||
   . http://adventofcode.com/2017/events
 | 
			
		||||
   . http://adventofcode.com/2017/settings
 | 
			
		||||
   . http://adventofcode.com/2017/auth/logout
 | 
			
		||||
   . http://adventofcode.com/2017
 | 
			
		||||
   . http://adventofcode.com/2017
 | 
			
		||||
   . http://adventofcode.com/2017/leaderboard
 | 
			
		||||
   . http://adventofcode.com/2017/stats
 | 
			
		||||
   . http://adventofcode.com/2017/sponsors
 | 
			
		||||
   . http://adventofcode.com/2017/sponsors
 | 
			
		||||
   . https://en.wikipedia.org/wiki/Spinlock
 | 
			
		||||
   . http://adventofcode.com/2017
 | 
			
		||||
							
								
								
									
										27
									
								
								timer.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								timer.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	wait := 1
 | 
			
		||||
	if len(os.Args) > 1 {
 | 
			
		||||
		wait = Atoi(os.Args[1])
 | 
			
		||||
	}
 | 
			
		||||
	time.Sleep(time.Minute * time.Duration(wait))
 | 
			
		||||
	fmt.Println("Done waiting")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Atoi(i string) int {
 | 
			
		||||
	var ret int
 | 
			
		||||
	var err error
 | 
			
		||||
	if ret, err = strconv.Atoi(i); err != nil {
 | 
			
		||||
		log.Fatal("Invalid Atoi")
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user