Advent of Code 2016, Day 16: Dragon Checksum

#ruby #advent of code 2016

Part A and B

On Day 16 we need to calculate checksum of large strings.

First we need to construct this string using modified dragon curve. You can check puzzle description for details.

Once the string has desired length we can calculate the checksum. For that we take a pair of bits and replace it with 1 if both bits match (00, 11) or with 0 if bits do not match (01, 10). We continue this process until we have output string of half size. If the size is even we repeat the process until the size will be odd. That will be our checksum.

Here is my solution:

def dragon(input)
  a = input
  b ="01", "10")
  [a, "0", b].join

def divisions(number)
  count = 0
  while number.even?
    number /= 2
    count += 1

def checksum_chunk(input)
  while input.size.even?
    puts "Current size = #{input.size}"
    checksum = ""
    (input.size / 2).times do |i|
      puts "Current index = #{i}" if i % 100_000 == 0
      if input[2 * i] == input[2 * i + 1]
        checksum += "1"
        checksum += "0"
    input = checksum


def checksum(input)
  divisions = divisions(input.size)
  chunk_size = 2 ** divisions
  chunks = input.size / chunk_size

  (0...chunks) do |chunk_index|
    puts "Calculating chunk #{chunk_index}"
    checksum_chunk(input[chunk_index * chunk_size, chunk_size])

# length = 35651584
length = 272
input = "10010000000110000"

while input.size < length
  input = dragon(input)

input = input[0, length]
puts checksum(input)

I didn’t implement any efficient solution for this task. For length 272 it is fine, but for Part B (35651584) it takes a while.

How it works. We first calculate how many times we can divide given string. For 272 we can divide it 4 times. The goal is to figure out how many even chunks we can split our string. In this case we can split 272 string into 17 chunks each of size 16 bits.

Then for each chunk we can calculate its checksum until we reach just one bit. Then we join everything together.

But as I said it is not efficient.