Sean McLemon | Advent of Code

Home | Czech | Blog | GitHub | Advent Of Code | Notes


2019-12-08 - Space Image Format

(original .ipynb)

Day 8 puzzle input is a stream of digits that supposedly represent an image in layers (mine is here). Part 1 involves finding the layer with the fewers "0" digits and multiplying the number of "1" occurrences by the number of "2" occurrences. Part 2 involves interpreting and decoding the image.

from pprint import pprint

## # take a string and return an array of array of string, like 
#   [
#     [ "1", "2"],
#     [ "3", "4"]
#   ]
def parse_image_layers(raw_image, width, height):
    layer_size = width * height
    pixels = [ pixel for pixel in raw_image ]
    layers = []
    
    current_layer = []
    
    for i, pixel in enumerate(pixels):
        current_layer.append(pixel)
        
        if (1+i) % layer_size == 0:
            layers.append(current_layer)
            current_layer = []
    
    if len(current_layer) > 0:
        layers.append(current_layer)
    
    return layers


def count_zeros(layer):
    return len([ digit for digit in layer if digit == "0"])

def fewest_zero_digits(layers):
    layers_and_zeros = [ (layer, count_zeros(layer)) for layer in layers ]
    
    print([zero for (layer, zero) in layers_and_zeros])
    sorted_layers_and_zeros = sorted(layers_and_zeros, key=lambda l: l[1])
    print([zero for (layer, zero) in sorted_layers_and_zeros])
    
    layer, count = sorted_layers_and_zeros[0]
    print(layer, count)
    return layer
    
def num_digits(layer, digit):
    return len([ d for d in layer if d == digit])
    

def solution(raw_image, width, height):
    layers = parse_image_layers(raw_image, width, height)
    layer = fewest_zero_digits(layers)
    
    return num_digits(layer, "1") * num_digits(layer, "2")
    
# puzzle_input = "123456789012"
# width = 3
# height = 2
puzzle_input = open("puzzle_input/day8.txt", "r").read().strip()
width = 25
height = 6
print(solution(puzzle_input, width, height))
[16, 11, 9, 10, 14, 8, 17, 14, 15, 18, 12, 7, 14, 11, 15, 9, 16, 11, 6, 11, 11, 19, 18, 18, 13, 14, 22, 9, 22, 19, 18, 21, 18, 17, 21, 26, 14, 24, 22, 26, 21, 18, 25, 20, 19, 24, 31, 29, 24, 26, 23, 23, 25, 30, 33, 24, 27, 26, 26, 30, 29, 36, 30, 32, 30, 24, 32, 35, 32, 27, 29, 32, 37, 39, 35, 36, 27, 34, 31, 29, 32, 26, 26, 37, 42, 39, 33, 40, 37, 32, 38, 39, 37, 46, 44, 43, 39, 39, 42, 57]
[6, 7, 8, 9, 9, 9, 10, 11, 11, 11, 11, 11, 12, 13, 14, 14, 14, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18, 18, 19, 19, 19, 20, 21, 21, 21, 22, 22, 22, 23, 23, 24, 24, 24, 24, 24, 25, 25, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 32, 32, 32, 32, 32, 32, 33, 33, 34, 35, 35, 36, 36, 37, 37, 37, 37, 38, 39, 39, 39, 39, 39, 40, 42, 42, 43, 44, 46, 57]
['2', '0', '2', '2', '2', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '0', '2', '2', '2', '2', '2', '2', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '1', '2', '2', '2', '2', '0', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '1', '2', '2', '2', '1', '2', '2', '2', '2', '2', '2', '2', '1', '2', '2', '2', '1', '2', '2', '1', '2', '0', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '1', '0', '2', '1', '1', '2', '2', '2', '1', '1', '1', '2', '2', '0', '2', '2', '2', '2', '2', '2', '1', '1', '2', '2', '2', '2', '1', '1', '2', '1', '2', '1', '2', '2', '2', '2', '2', '2', '2', '2'] 6
2480
def render_pixel(pixel):
    if pixel == "0":
        return "  "
    return "##"

def is_transparent(pixel):
    return pixel == "2"


def render_layer(layer, flattened_layers):
    for i, val in enumerate(layer):
        if is_transparent(val):
            continue
        
        flattened_layers[i] = render_pixel(val)


def render(layers, width, height):
    flattened_layers = [ render_pixel(0) for i in range(width * height) ]
    
    for layer in layers[::-1]:
        render_layer(layer, flattened_layers)

    rows = []
    current_row = []
    layer_size = width * height
    for i, pixel in enumerate(flattened_layers):
        current_row.append(pixel)
        
        if (1+i) % width == 0:
            rows.append("".join(current_row)) 
            current_row = []
        
    return "\n".join(rows)
    

layers = parse_image_layers(puzzle_input, width, height)
print(render(layers, width, height))
########  ##      ########    ##        ##    ##  
      ##  ##      ####    ##  ##        ##    ##  
    ##      ##  ##  ######    ##        ########  
  ##          ##    ##    ##  ##        ##    ##  
##            ##    ##    ##  ##        ##    ##  
########      ##    ######    ########  ##    ##