Day 21 Complete
Added String Permutation helper to helpers file
This commit is contained in:
		
							
								
								
									
										100
									
								
								2016/day21/input
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								2016/day21/input
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
				
			|||||||
 | 
					swap letter e with letter h
 | 
				
			||||||
 | 
					swap letter f with letter g
 | 
				
			||||||
 | 
					move position 6 to position 3
 | 
				
			||||||
 | 
					reverse positions 1 through 6
 | 
				
			||||||
 | 
					swap letter b with letter a
 | 
				
			||||||
 | 
					swap letter a with letter f
 | 
				
			||||||
 | 
					rotate based on position of letter e
 | 
				
			||||||
 | 
					swap position 7 with position 2
 | 
				
			||||||
 | 
					rotate based on position of letter e
 | 
				
			||||||
 | 
					swap letter c with letter e
 | 
				
			||||||
 | 
					rotate based on position of letter f
 | 
				
			||||||
 | 
					rotate right 6 steps
 | 
				
			||||||
 | 
					swap letter c with letter f
 | 
				
			||||||
 | 
					reverse positions 3 through 7
 | 
				
			||||||
 | 
					swap letter c with letter b
 | 
				
			||||||
 | 
					swap position 1 with position 2
 | 
				
			||||||
 | 
					reverse positions 3 through 6
 | 
				
			||||||
 | 
					swap letter c with letter a
 | 
				
			||||||
 | 
					rotate left 0 steps
 | 
				
			||||||
 | 
					swap position 3 with position 0
 | 
				
			||||||
 | 
					swap letter b with letter e
 | 
				
			||||||
 | 
					reverse positions 4 through 7
 | 
				
			||||||
 | 
					move position 1 to position 4
 | 
				
			||||||
 | 
					swap position 6 with position 3
 | 
				
			||||||
 | 
					rotate left 6 steps
 | 
				
			||||||
 | 
					rotate right 0 steps
 | 
				
			||||||
 | 
					move position 7 to position 3
 | 
				
			||||||
 | 
					move position 3 to position 4
 | 
				
			||||||
 | 
					swap position 3 with position 2
 | 
				
			||||||
 | 
					reverse positions 1 through 6
 | 
				
			||||||
 | 
					move position 7 to position 5
 | 
				
			||||||
 | 
					reverse positions 4 through 5
 | 
				
			||||||
 | 
					rotate based on position of letter g
 | 
				
			||||||
 | 
					swap position 4 with position 2
 | 
				
			||||||
 | 
					reverse positions 1 through 5
 | 
				
			||||||
 | 
					rotate based on position of letter h
 | 
				
			||||||
 | 
					rotate based on position of letter f
 | 
				
			||||||
 | 
					rotate based on position of letter b
 | 
				
			||||||
 | 
					swap position 1 with position 4
 | 
				
			||||||
 | 
					swap letter b with letter h
 | 
				
			||||||
 | 
					rotate based on position of letter e
 | 
				
			||||||
 | 
					swap letter a with letter c
 | 
				
			||||||
 | 
					swap position 3 with position 5
 | 
				
			||||||
 | 
					rotate right 6 steps
 | 
				
			||||||
 | 
					rotate based on position of letter c
 | 
				
			||||||
 | 
					move position 2 to position 0
 | 
				
			||||||
 | 
					swap letter b with letter e
 | 
				
			||||||
 | 
					swap letter g with letter e
 | 
				
			||||||
 | 
					rotate based on position of letter d
 | 
				
			||||||
 | 
					swap position 6 with position 5
 | 
				
			||||||
 | 
					swap letter b with letter c
 | 
				
			||||||
 | 
					rotate based on position of letter e
 | 
				
			||||||
 | 
					rotate based on position of letter f
 | 
				
			||||||
 | 
					rotate based on position of letter f
 | 
				
			||||||
 | 
					move position 7 to position 0
 | 
				
			||||||
 | 
					rotate right 1 step
 | 
				
			||||||
 | 
					rotate right 7 steps
 | 
				
			||||||
 | 
					swap position 5 with position 6
 | 
				
			||||||
 | 
					move position 6 to position 7
 | 
				
			||||||
 | 
					rotate based on position of letter e
 | 
				
			||||||
 | 
					swap position 3 with position 1
 | 
				
			||||||
 | 
					swap position 4 with position 3
 | 
				
			||||||
 | 
					swap letter f with letter a
 | 
				
			||||||
 | 
					swap position 5 with position 2
 | 
				
			||||||
 | 
					rotate based on position of letter e
 | 
				
			||||||
 | 
					rotate left 3 steps
 | 
				
			||||||
 | 
					rotate left 1 step
 | 
				
			||||||
 | 
					rotate based on position of letter b
 | 
				
			||||||
 | 
					rotate left 6 steps
 | 
				
			||||||
 | 
					rotate based on position of letter b
 | 
				
			||||||
 | 
					rotate right 7 steps
 | 
				
			||||||
 | 
					swap position 0 with position 2
 | 
				
			||||||
 | 
					swap position 7 with position 5
 | 
				
			||||||
 | 
					rotate left 3 steps
 | 
				
			||||||
 | 
					reverse positions 4 through 5
 | 
				
			||||||
 | 
					move position 2 to position 5
 | 
				
			||||||
 | 
					swap letter c with letter f
 | 
				
			||||||
 | 
					swap letter g with letter e
 | 
				
			||||||
 | 
					rotate left 6 steps
 | 
				
			||||||
 | 
					swap position 4 with position 6
 | 
				
			||||||
 | 
					rotate based on position of letter h
 | 
				
			||||||
 | 
					rotate left 2 steps
 | 
				
			||||||
 | 
					swap letter c with letter a
 | 
				
			||||||
 | 
					rotate right 3 steps
 | 
				
			||||||
 | 
					rotate left 6 steps
 | 
				
			||||||
 | 
					swap letter b with letter f
 | 
				
			||||||
 | 
					swap position 6 with position 5
 | 
				
			||||||
 | 
					reverse positions 3 through 4
 | 
				
			||||||
 | 
					reverse positions 2 through 7
 | 
				
			||||||
 | 
					swap position 7 with position 4
 | 
				
			||||||
 | 
					rotate based on position of letter d
 | 
				
			||||||
 | 
					swap position 5 with position 3
 | 
				
			||||||
 | 
					swap letter c with letter b
 | 
				
			||||||
 | 
					swap position 7 with position 6
 | 
				
			||||||
 | 
					rotate based on position of letter c
 | 
				
			||||||
 | 
					reverse positions 0 through 7
 | 
				
			||||||
 | 
					reverse positions 2 through 4
 | 
				
			||||||
 | 
					rotate based on position of letter f
 | 
				
			||||||
 | 
					reverse positions 1 through 4
 | 
				
			||||||
 | 
					rotate right 7 steps
 | 
				
			||||||
							
								
								
									
										110
									
								
								2016/day21/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								2016/day21/main.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"../../"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func main() {
 | 
				
			||||||
 | 
						pw := "fbgdceah" // Part 2 Puzzle input
 | 
				
			||||||
 | 
						input := aoc.StdinToStringSlice()
 | 
				
			||||||
 | 
						if aoc.ArgIsSet("-1") {
 | 
				
			||||||
 | 
							pw = "abcdefgh" // Part 1 Puzzle input
 | 
				
			||||||
 | 
							pw = scramblePassword(pw, input)
 | 
				
			||||||
 | 
							fmt.Println(scramblePassword(pw, input))
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fmt.Println(unscramblePassword(pw, input))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func unscramblePassword(pw string, inst []string) string {
 | 
				
			||||||
 | 
						// Brute force it.
 | 
				
			||||||
 | 
						// Just get all permutations of the runes and return the one
 | 
				
			||||||
 | 
						// for which the instructions return the input
 | 
				
			||||||
 | 
						tst := aoc.StringPermutations(pw)
 | 
				
			||||||
 | 
						for i := range tst {
 | 
				
			||||||
 | 
							if scramblePassword(tst[i], inst) == pw {
 | 
				
			||||||
 | 
								return tst[i]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func scramblePassword(pw string, inst []string) string {
 | 
				
			||||||
 | 
						for i := range inst {
 | 
				
			||||||
 | 
							pts := strings.Fields(inst[i])
 | 
				
			||||||
 | 
							switch pts[0] + " " + pts[1] {
 | 
				
			||||||
 | 
							case "swap position":
 | 
				
			||||||
 | 
								pw = swapPos(pw, aoc.Atoi(pts[2]), aoc.Atoi(pts[5]))
 | 
				
			||||||
 | 
							case "swap letter":
 | 
				
			||||||
 | 
								pw = swapLetter(pw, pts[2], pts[5])
 | 
				
			||||||
 | 
							case "reverse positions":
 | 
				
			||||||
 | 
								pw = reverse(pw, aoc.Atoi(pts[2]), aoc.Atoi(pts[4]))
 | 
				
			||||||
 | 
							case "rotate left":
 | 
				
			||||||
 | 
								pw = rotate(pw, aoc.Atoi(pts[2])*-1)
 | 
				
			||||||
 | 
							case "rotate right":
 | 
				
			||||||
 | 
								pw = rotate(pw, aoc.Atoi(pts[2]))
 | 
				
			||||||
 | 
							case "rotate based":
 | 
				
			||||||
 | 
								rotIdx := strings.Index(pw, pts[6])
 | 
				
			||||||
 | 
								if rotIdx >= 4 {
 | 
				
			||||||
 | 
									rotIdx++
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								rotIdx++
 | 
				
			||||||
 | 
								pw = rotate(pw, rotIdx)
 | 
				
			||||||
 | 
							case "move position":
 | 
				
			||||||
 | 
								pw = move(pw, aoc.Atoi(pts[2]), aoc.Atoi(pts[5]))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return pw
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func swapPos(pw string, x, y int) string {
 | 
				
			||||||
 | 
						r := []rune(pw)
 | 
				
			||||||
 | 
						r[x], r[y] = r[y], r[x]
 | 
				
			||||||
 | 
						return string(r)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func swapLetter(pw string, x, y string) string {
 | 
				
			||||||
 | 
						xPos := strings.Index(pw, x)
 | 
				
			||||||
 | 
						yPos := strings.Index(pw, y)
 | 
				
			||||||
 | 
						return swapPos(pw, xPos, yPos)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func rotate(pw string, steps int) string {
 | 
				
			||||||
 | 
						r := []rune(pw)
 | 
				
			||||||
 | 
						var x rune
 | 
				
			||||||
 | 
						for steps < 0 {
 | 
				
			||||||
 | 
							// Left rotate (shift & push)
 | 
				
			||||||
 | 
							x, r = r[0], r[1:]
 | 
				
			||||||
 | 
							r = append(r, x)
 | 
				
			||||||
 | 
							steps++
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for steps > 0 {
 | 
				
			||||||
 | 
							// Right rotate (pop & unshift)
 | 
				
			||||||
 | 
							x, r = r[len(r)-1], r[:len(r)-1]
 | 
				
			||||||
 | 
							r = append([]rune{x}, r...)
 | 
				
			||||||
 | 
							steps--
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return string(r)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func reverse(pw string, beg, end int) string {
 | 
				
			||||||
 | 
						revStr := pw[beg : end+1]
 | 
				
			||||||
 | 
						runes := []rune(revStr)
 | 
				
			||||||
 | 
						for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
 | 
				
			||||||
 | 
							runes[i], runes[j] = runes[j], runes[i]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return pw[:beg] + string(runes) + pw[end+1:]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func move(pw string, x, y int) string {
 | 
				
			||||||
 | 
						r := []rune(pw)
 | 
				
			||||||
 | 
						// Cut element at x
 | 
				
			||||||
 | 
						mov := r[x]
 | 
				
			||||||
 | 
						r = append(r[:x], r[x+1:]...)
 | 
				
			||||||
 | 
						// Insert at y
 | 
				
			||||||
 | 
						r = append(r[:y], append([]rune{mov}, r[y:]...)...)
 | 
				
			||||||
 | 
						return string(r)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										69
									
								
								2016/day21/problem
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								2016/day21/problem
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					Advent of Code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--- Day 21: Scrambled Letters and Hash ---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   The computer system you're breaking into uses a weird scrambling function to store its passwords. It shouldn't be much trouble to create
 | 
				
			||||||
 | 
					   your own scrambled password so you can add it to the system; you just have to implement the scrambler.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   The scrambling function is a series of operations (the exact list is provided in your puzzle input). Starting with the password to be
 | 
				
			||||||
 | 
					   scrambled, apply each operation in succession to the string. The individual operations behave as follows:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     • swap position X with position Y means that the letters at indexes X and Y (counting from 0) should be swapped.
 | 
				
			||||||
 | 
					     • swap letter X with letter Y means that the letters X and Y should be swapped (regardless of where they appear in the string).
 | 
				
			||||||
 | 
					     • rotate left/right X steps means that the whole string should be rotated; for example, one right rotation would turn abcd into dabc.
 | 
				
			||||||
 | 
					     • rotate based on position of letter X means that the whole string should be rotated to the right based on the index of letter X
 | 
				
			||||||
 | 
					       (counting from 0) as determined before this instruction does any rotations. Once the index is determined, rotate the string to the
 | 
				
			||||||
 | 
					       right one time, plus a number of times equal to that index, plus one additional time if the index was at least 4.
 | 
				
			||||||
 | 
					     • reverse positions X through Y means that the span of letters at indexes X through Y (including the letters at X and Y) should be
 | 
				
			||||||
 | 
					       reversed in order.
 | 
				
			||||||
 | 
					     • move position X to position Y means that the letter which is at index X should be removed from the string, then inserted such that
 | 
				
			||||||
 | 
					       it ends up at index Y.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   For example, suppose you start with abcde and perform the following operations:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     • swap position 4 with position 0 swaps the first and last letters, producing the input for the next step, ebcda.
 | 
				
			||||||
 | 
					     • swap letter d with letter b swaps the positions of d and b: edcba.
 | 
				
			||||||
 | 
					     • reverse positions 0 through 4 causes the entire string to be reversed, producing abcde.
 | 
				
			||||||
 | 
					     • rotate left 1 step shifts all letters left one position, causing the first letter to wrap to the end of the string: bcdea.
 | 
				
			||||||
 | 
					     • move position 1 to position 4 removes the letter at position 1 (c), then inserts it at position 4 (the end of the string): bdeac.
 | 
				
			||||||
 | 
					     • move position 3 to position 0 removes the letter at position 3 (a), then inserts it at position 0 (the front of the string): abdec.
 | 
				
			||||||
 | 
					     • rotate based on position of letter b finds the index of letter b (1), then rotates the string right once plus a number of times
 | 
				
			||||||
 | 
					       equal to that index (2): ecabd.
 | 
				
			||||||
 | 
					     • rotate based on position of letter d finds the index of letter d (4), then rotates the string right once, plus a number of times
 | 
				
			||||||
 | 
					       equal to that index, plus an additional time because the index was at least 4, for a total of 6 right rotations: decab.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   After these steps, the resulting scrambled password is decab.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Now, you just need to generate a new scrambled password and you can access the system. Given the list of scrambling operations in your
 | 
				
			||||||
 | 
					   puzzle input, what is the result of scrambling abcdefgh?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Your puzzle answer was ________.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--- Part Two ---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   You scrambled the password correctly, but you discover that you can't actually modify the password file on the system. You'll need to
 | 
				
			||||||
 | 
					   un-scramble one of the existing passwords by reversing the scrambling process.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   What is the un-scrambled version of the scrambled password fbgdceah?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Your puzzle answer was ________.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					References
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Visible links
 | 
				
			||||||
 | 
					   . http://adventofcode.com/
 | 
				
			||||||
 | 
					   . http://adventofcode.com/2016/about
 | 
				
			||||||
 | 
					   . http://adventofcode.com/2016/support
 | 
				
			||||||
 | 
					   . http://adventofcode.com/2016/events
 | 
				
			||||||
 | 
					   . http://adventofcode.com/2016/settings
 | 
				
			||||||
 | 
					   . http://adventofcode.com/2016/auth/logout
 | 
				
			||||||
 | 
					   . http://adventofcode.com/2016
 | 
				
			||||||
 | 
					   . http://adventofcode.com/2016
 | 
				
			||||||
 | 
					   . http://adventofcode.com/2016/leaderboard
 | 
				
			||||||
 | 
					   . http://adventofcode.com/2016/stats
 | 
				
			||||||
 | 
					   . http://adventofcode.com/2016/sponsors
 | 
				
			||||||
 | 
					   . http://adventofcode.com/2016/sponsors
 | 
				
			||||||
 | 
					   . https://en.wikipedia.org/wiki/File_system_permissions
 | 
				
			||||||
 | 
					   . https://en.wikipedia.org/wiki/Passwd
 | 
				
			||||||
 | 
					   . http://adventofcode.com/2016
 | 
				
			||||||
 | 
					   . http://adventofcode.com/2016/day/21/input
 | 
				
			||||||
							
								
								
									
										17
									
								
								helpers.go
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								helpers.go
									
									
									
									
									
								
							@@ -84,6 +84,23 @@ func PrintProgress(curr, total int) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func StringPermutations(str string) []string {
 | 
				
			||||||
 | 
						return stringPermHelper(str, 0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func stringPermHelper(str string, i int) []string {
 | 
				
			||||||
 | 
						ret := []string{str}
 | 
				
			||||||
 | 
						if i != len(str) {
 | 
				
			||||||
 | 
							r := []rune(str)
 | 
				
			||||||
 | 
							for j := i; j < len(r); j++ {
 | 
				
			||||||
 | 
								r[i], r[j] = r[j], r[i]
 | 
				
			||||||
 | 
								ret = append(ret, stringPermHelper(string(r), i+1)...)
 | 
				
			||||||
 | 
								r[i], r[j] = r[j], r[i]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ret
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Some character code stuff for prettier output
 | 
					// Some character code stuff for prettier output
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	BorderNS = "\u2502"
 | 
						BorderNS = "\u2502"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user