~lh2/adventofcode18

da6f58903b1865d1d936ca1f1cae46e2c70fd433 — Lukas Henkel 5 years ago 294649d master
Day 22 Task 1

Now that was a nice and easy one again.
1 files changed, 89 insertions(+), 0 deletions(-)

A d22/main.go
A d22/main.go => d22/main.go +89 -0
@@ 0,0 1,89 @@
package main

import (
	"strconv"
	"strings"
)

type Point struct {
	X int
	Y int
}

type RegionType int

const (
	RegionTypeRocky RegionType = iota
	RegionTypeWet
	RegionTypeNarrow
)

type Cave struct {
	Depth  int
	Target Point

	gidxCache map[Point]int
	elvlCache map[Point]int
}

func (c Cave) GeoIndex(p Point) (idx int) {
	if idx, ok := c.gidxCache[p]; ok {
		return idx
	}
	switch {
	case p == Point{} || p == c.Target:
		idx = 0
	case p.Y == 0:
		idx = p.X * 16807
	case p.X == 0:
		idx = p.Y * 48271
	default:
		idx = c.ErosionLevel(pt(p.X-1, p.Y)) *
			c.ErosionLevel(pt(p.X, p.Y-1))
	}
	c.gidxCache[p] = idx
	return
}

func (c Cave) ErosionLevel(p Point) (lvl int) {
	if lvl, ok := c.elvlCache[p]; ok {
		return lvl
	}
	lvl = (c.GeoIndex(p) + c.Depth) % 20183
	c.elvlCache[p] = lvl
	return
}

func (c Cave) RegionType(p Point) RegionType {
	return RegionType(c.ErosionLevel(p) % 3)
}

func pt(x, y int) Point {
	return Point{X: x, Y: y}
}

func parseInput(in chan string) (cave Cave, target Point) {
	cave = Cave{
		Depth:     mustAtoi((<-in)[7:]),
		gidxCache: make(map[Point]int),
		elvlCache: make(map[Point]int),
	}
	tc := strings.Split((<-in)[8:], ",")
	target = Point{
		X: mustAtoi(tc[0]),
		Y: mustAtoi(tc[1]),
	}
	cave.Target = target
	return
}

func task1(in chan string) string {
	c, target := parseInput(in)
	riskLevel := 0
	for x := 0; x <= target.X; x++ {
		for y := 0; y <= target.Y; y++ {
			riskLevel += int(c.RegionType(pt(x, y)))
		}
	}
	return strconv.Itoa(riskLevel)
}