Day 16 Complete
This commit is contained in:
parent
1e8357b160
commit
5977b28d73
BIN
day16/day16
Executable file
BIN
day16/day16
Executable file
Binary file not shown.
1
day16/input
Normal file
1
day16/input
Normal file
@ -0,0 +1 @@
|
|||||||
|
00111101111101000
|
89
day16/main.go
Normal file
89
day16/main.go
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Part 1 Disk Size: 272
|
||||||
|
// Part 2 Disk Size: 35651584
|
||||||
|
func main() {
|
||||||
|
diskSize := 272
|
||||||
|
if len(os.Args) > 1 {
|
||||||
|
switch os.Args[1] {
|
||||||
|
case "-2":
|
||||||
|
// Do part two
|
||||||
|
diskSize = 35651584
|
||||||
|
default:
|
||||||
|
// manually set disk size
|
||||||
|
diskSize = atoi(os.Args[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input := stdinToString()
|
||||||
|
for len(input) < diskSize {
|
||||||
|
input = dragonCurve(input)
|
||||||
|
}
|
||||||
|
input = input[:diskSize]
|
||||||
|
fmt.Println(checksum(input))
|
||||||
|
}
|
||||||
|
|
||||||
|
func dragonCurve(inp string) string {
|
||||||
|
return inp + "0" + invert(reverse(inp))
|
||||||
|
}
|
||||||
|
|
||||||
|
func invert(inp string) string {
|
||||||
|
var ret []rune
|
||||||
|
for i := range inp {
|
||||||
|
if inp[i] == '1' {
|
||||||
|
ret = append(ret, '0')
|
||||||
|
} else {
|
||||||
|
ret = append(ret, '1')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
func reverse(inp string) string {
|
||||||
|
var ret []byte
|
||||||
|
for i := len(inp) - 1; i >= 0; i-- {
|
||||||
|
ret = append(ret, inp[i])
|
||||||
|
}
|
||||||
|
return string(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checksum(inp string) string {
|
||||||
|
var chkSum []rune
|
||||||
|
for i := 0; i < len(inp); i += 2 {
|
||||||
|
if inp[i] == inp[i+1] {
|
||||||
|
chkSum = append(chkSum, '1')
|
||||||
|
} else {
|
||||||
|
chkSum = append(chkSum, '0')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(chkSum)%2 == 0 {
|
||||||
|
// Length is even, repeat
|
||||||
|
return checksum(string(chkSum))
|
||||||
|
}
|
||||||
|
return string(chkSum)
|
||||||
|
}
|
||||||
|
|
||||||
|
func stdinToString() string {
|
||||||
|
var input string
|
||||||
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
|
for scanner.Scan() {
|
||||||
|
input += scanner.Text()
|
||||||
|
}
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
95
day16/problem
Normal file
95
day16/problem
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
Advent of Code
|
||||||
|
|
||||||
|
--- Day 16: Dragon Checksum ---
|
||||||
|
|
||||||
|
You're done scanning this part of the network, but you've left traces of your presence. You need to
|
||||||
|
overwrite some disks with random-looking data to cover your tracks and update the local security system
|
||||||
|
with a new checksum for those disks.
|
||||||
|
|
||||||
|
For the data to not be suspiscious, it needs to have certain properties; purely random data will be
|
||||||
|
detected as tampering. To generate appropriate random data, you'll need to use a modified dragon curve.
|
||||||
|
|
||||||
|
Start with an appropriate initial state (your puzzle input). Then, so long as you don't have enough data
|
||||||
|
yet to fill the disk, repeat the following steps:
|
||||||
|
|
||||||
|
• Call the data you have at this point "a".
|
||||||
|
• Make a copy of "a"; call this copy "b".
|
||||||
|
• Reverse the order of the characters in "b".
|
||||||
|
• In "b", replace all instances of 0 with 1 and all 1s with 0.
|
||||||
|
• The resulting data is "a", then a single 0, then "b".
|
||||||
|
|
||||||
|
For example, after a single step of this process,
|
||||||
|
|
||||||
|
• 1 becomes 100.
|
||||||
|
• 0 becomes 001.
|
||||||
|
• 11111 becomes 11111000000.
|
||||||
|
• 111100001010 becomes 1111000010100101011110000.
|
||||||
|
|
||||||
|
Repeat these steps until you have enough data to fill the desired disk.
|
||||||
|
|
||||||
|
Once the data has been generated, you also need to create a checksum of that data. Calculate the checksum
|
||||||
|
only for the data that fits on the disk, even if you generated more data than that in the previous step.
|
||||||
|
|
||||||
|
The checksum for some given data is created by considering each non-overlapping pair of characters in the
|
||||||
|
input data. If the two characters match (00 or 11), the next checksum character is a 1. If the characters
|
||||||
|
do not match (01 or 10), the next checksum character is a 0. This should produce a new string which is
|
||||||
|
exactly half as long as the original. If the length of the checksum is even, repeat the process until you
|
||||||
|
end up with a checksum with an odd length.
|
||||||
|
|
||||||
|
For example, suppose we want to fill a disk of length 12, and when we finally generate a string of at
|
||||||
|
least length 12, the first 12 characters are 110010110100. To generate its checksum:
|
||||||
|
|
||||||
|
• Consider each pair: 11, 00, 10, 11, 01, 00.
|
||||||
|
• These are same, same, different, same, different, same, producing 110101.
|
||||||
|
• The resulting string has length 6, which is even, so we repeat the process.
|
||||||
|
• The pairs are 11 (same), 01 (different), 01 (different).
|
||||||
|
• This produces the checksum 100, which has an odd length, so we stop.
|
||||||
|
|
||||||
|
Therefore, the checksum for 110010110100 is 100.
|
||||||
|
|
||||||
|
Combining all of these steps together, suppose you want to fill a disk of length 20 using an initial state
|
||||||
|
of 10000:
|
||||||
|
|
||||||
|
• Because 10000 is too short, we first use the modified dragon curve to make it longer.
|
||||||
|
• After one round, it becomes 10000011110 (11 characters), still too short.
|
||||||
|
• After two rounds, it becomes 10000011110010000111110 (23 characters), which is enough.
|
||||||
|
• Since we only need 20, but we have 23, we get rid of all but the first 20 characters:
|
||||||
|
10000011110010000111.
|
||||||
|
• Next, we start calculating the checksum; after one round, we have 0111110101, which 10 characters long
|
||||||
|
(even), so we continue.
|
||||||
|
• After two rounds, we have 01100, which is 5 characters long (odd), so we are done.
|
||||||
|
|
||||||
|
In this example, the correct checksum would therefore be 01100.
|
||||||
|
|
||||||
|
The first disk you have to fill has length 272. Using the initial state in your puzzle input, what is the
|
||||||
|
correct checksum?
|
||||||
|
|
||||||
|
Your puzzle answer _____________________.
|
||||||
|
|
||||||
|
The first half of this puzzle is complete! It provides one gold star: *
|
||||||
|
|
||||||
|
--- Part Two ---
|
||||||
|
|
||||||
|
The second disk you have to fill has length 35651584. Again using the initial state in your puzzle input,
|
||||||
|
what is the correct checksum for this disk?
|
||||||
|
|
||||||
|
Your puzzle input is still 00111101111101000.
|
||||||
|
|
||||||
|
Answer: _____________________
|
||||||
|
|
||||||
|
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/Dragon_curve
|
Loading…
Reference in New Issue
Block a user