Day 21 Complete
Added String Permutation helper to helpers file
This commit is contained in:
parent
204f1d2a15
commit
f06d8a6c07
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"
|
||||||
|
Loading…
Reference in New Issue
Block a user