Day 16 Complete

This commit is contained in:
Brian Buller 2016-12-16 07:49:52 -06:00
parent 1e8357b160
commit 5977b28d73
4 changed files with 185 additions and 0 deletions

BIN
day16/day16 Executable file

Binary file not shown.

1
day16/input Normal file
View File

@ -0,0 +1 @@
00111101111101000

89
day16/main.go Normal file
View 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
View 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