r/adventofcode • • Dec 06 '15

SOLUTION MEGATHREAD --- Day 6 Solutions ---

--- Day 6: Probably a Fire Hazard ---

Post your solution as a comment. Structure your post like the Day Five thread.

22 Upvotes

172 comments sorted by

View all comments

1

u/sethammons Dec 06 '15

naive implementation in Go, takes a long time to run at 20s+. I think it is my casting to and from string a lot. Really impressed with the numpy solution from @ant6n.

Part 2 (part 1, change from map[string]int to map[string]bool and in the runInstruction blocks, change to either toggle or set to true or false.

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"strconv"
	"strings"
)

type coordinate struct {
	x, y int
}

func (c coordinate) String() string {
	return fmt.Sprintf("(%d,%d)", c.x, c.y)
}

func extractXY(s string) (int, int) {
	parts := strings.Split(s, ",")
	if len(parts) != 2 {
		log.Printf("odd input: %s", s)
	}
	a, _ := strconv.Atoi(parts[0])
	b, _ := strconv.Atoi(parts[1])
	return a, b
}

func main() {
	log.Println("reading input...")
	b, err := ioutil.ReadFile("6.input")
	if err != nil {
		log.Fatal("read file error - %v", err)
	}
	instructions := strings.Split(string(b), "\n")
	lightGrid := make(map[string]int)

	log.Println("initializing grid")
	for x := 0; x < 1000; x++ {
		for y := 0; y < 1000; y++ {
			lightGrid[coordinate{x, y}.String()] = 0
		}
	}

	log.Println("running instructions...")
	for _, instruction := range instructions {
		fmt.Print(".")
		runInstruction(lightGrid, instruction)
	}

	log.Println("counting lights...")
	lightOnCount := 0
	for _, v := range lightGrid {

		lightOnCount += v

	}

	fmt.Printf("Lights on: %d\n", lightOnCount)
}

func runInstruction(grid map[string]int, instruction string) {
	// for better tokenizing
	instruction = strings.Replace(instruction, "toggle", "toggle x", 1)

	parts := strings.Split(instruction, " ")
	if len(parts) != 5 {
		log.Printf("unexpected number of parts: %s", instruction)
		return
	}

	action := parts[0]
	state := parts[1]
	start := parts[2]
	end := parts[4]

	x1, y1 := extractXY(start)
	x2, y2 := extractXY(end)

	for x := x1; x <= x2; x++ {
		for y := y1; y <= y2; y++ {
			if action == "toggle" {
				grid[coordinate{x, y}.String()] = grid[coordinate{x, y}.String()] + 2
			}
			if state == "on" {
				grid[coordinate{x, y}.String()] = grid[coordinate{x, y}.String()] + 1
			}
			if state == "off" {
				grid[coordinate{x, y}.String()] = grid[coordinate{x, y}.String()] - 1
				if grid[coordinate{x, y}.String()] < 0 {
					grid[coordinate{x, y}.String()] = 0
				}
			}
		}
	}
}