Day 4: Printing Department

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

you are viewing a single comment's thread
view the rest of the comments
[โ€“] 1 point 10 months ago

Go

package main

import (
	"aoc/utils"
	"fmt"
)

type rollMap [][]bool

func (rm *rollMap) addRow(line string) {
	runes := []rune(line)
	row := make([]bool, len(runes))

	for idx, r := range runes {
		row[idx] = r == '@'
	}

	*rm = append(*rm, row)
}

func (rm rollMap) getAdjacentContents(row, col int) []bool {
	contents := []bool{}
	lenrow := len(rm[0])
	lenrm := len(rm)

	for _, i := range []int{-1, 0, 1} {
		for _, j := range []int{-1, 0, 1} {
			if i == 0 && j == 0 {
				continue
			}

			r := row + i
			c := col + j
			if r >= 0 && r < lenrm && c >= 0 && c < lenrow {
				contents = append(contents, rm[r][c])
			}
		}
	}

	return contents
}

func countTrue(array []bool) int {
	count := 0
	for _, val := range array {
		if val {
			count++
		}
	}
	return count
}

func createMap(input chan string) rollMap {
	rm := rollMap{}

	for line := range input {
		rm.addRow(line)
	}

	return rm
}

func stepOne(input chan string) (int, error) {
	rm := createMap(input)
	lenrow := len(rm[0])
	accessibleRolls := 0

	for row := range rm {
		for col := range lenrow {
			if rm[row][col] {
				adj := rm.getAdjacentContents(row, col)
				numRolls := countTrue(adj)
				if numRolls < 4 {
					accessibleRolls++
				}
			}
		}
	}

	return accessibleRolls, nil
}

type position struct {
	row, col int
}

func stepTwo(input chan string) (int, error) {
	rm := createMap(input)
	lenrow := len(rm[0])
	accessibleRolls := 0

	for true {
		accessedRolls := []position{}
		for row := range rm {
			for col := range lenrow {
				if rm[row][col] {
					adj := rm.getAdjacentContents(row, col)
					numRolls := countTrue(adj)
					if numRolls < 4 {
						accessibleRolls++
						accessedRolls = append(accessedRolls, position{
							row: row,
							col: col,
						})
					}
				}
			}
		}
		if len(accessedRolls) == 0 {
			break
		} else {
			for _, pos := range accessedRolls {
				rm[pos.row][pos.col] = false
			}
		}
	}

	return accessibleRolls, nil
}

func main() {
	input := utils.FilePath("day04.txt")
	ch1, err1 := input.GetLineChannel()
	if err1 != nil {
		fmt.Errorf("step one error: %s\n", err1)
		return
	}

	val1, errStep1 := stepOne(ch1)
	if errStep1 != nil {
		fmt.Errorf("step one error: %s\n", errStep1)
		return
	}

	fmt.Printf("Step one result: %d\n", val1)

	ch2, err2 := input.GetLineChannel()
	if err2 != nil {
		fmt.Errorf("step two error: %s\n", err2)
		return
	}

	val2, errStep2 := stepTwo(ch2)
	if errStep2 != nil {
		fmt.Errorf("step two error: %s\n", errStep2)
		return
	}

	fmt.Printf("Step two result: %d\n", val2)
}
  • source