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
|
||||
const (
|
||||
BorderNS = "\u2502"
|
||||
|
Loading…
Reference in New Issue
Block a user