From 9077b5189bc570724f3c9a10cf740bb070008c41 Mon Sep 17 00:00:00 2001 From: Jeremy Kaplan Date: Sun, 12 Dec 2021 21:33:04 -0800 Subject: [PATCH] 2021 Day 13 --- 2021/day13/main.go | 124 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 2021/day13/main.go diff --git a/2021/day13/main.go b/2021/day13/main.go new file mode 100644 index 0000000..491511e --- /dev/null +++ b/2021/day13/main.go @@ -0,0 +1,124 @@ +package main + +import ( + "fmt" + "strings" + + "github.com/jdkaplan/advent-of-code/aoc" +) + +func main() { + text := aoc.Input().ReadFile("day13.txt") + fmt.Println(part1(text)) + fmt.Println(part2(text)) +} + +func part1(text string) int { + g, folds := parse(text) + g = g.Fold(folds[0]) + return len(g) +} + +func part2(text string) string { + g, folds := parse(text) + for _, f := range folds { + g = g.Fold(f) + } + return g.String() +} + +func parse(text string) (Grid, []Fold) { + dots, folds := aoc.Cut(text, "\n\n") + var points []Point + for _, line := range strings.Split(dots, "\n") { + x, y := aoc.Cut(line, ",") + points = append(points, Point{ + x: aoc.MustInt(x), + y: aoc.MustInt(y), + }) + } + + var fs []Fold + for _, line := range strings.Split(folds, "\n") { + axis, val := aoc.Cut(line[len("fold along "):], "=") + fs = append(fs, Fold{ + axis: axis, + val: aoc.MustInt(val), + }) + } + return NewGrid(points), fs +} + +type Point struct{ x, y int } + +type Grid map[Point]int + +type Fold struct { + axis string + val int +} + +func NewGrid(points []Point) Grid { + g := make(Grid) + for _, p := range points { + g[p] = 1 + } + return g +} + +func (g Grid) Fold(f Fold) Grid { + g2 := make(Grid) + for p, count := range g { + var p2 Point + switch axis := f.axis; axis { + case "x": + p2 = p.foldX(f.val) + case "y": + p2 = p.foldY(f.val) + default: + panic(axis) + } + g2[p2] += count + } + return g2 +} + +func (p Point) foldX(x int) Point { + if p.x > x { + return Point{x - (p.x - x), p.y} + } + return p +} + +func (p Point) foldY(y int) Point { + if p.y > y { + return Point{p.x, y - (p.y - y)} + } + return p +} + +func (g Grid) String() string { + xmax, ymax := 0, 0 + for p := range g { + if p.x > xmax { + xmax = p.x + } + if p.y > ymax { + ymax = p.y + } + } + + var sb strings.Builder + for y := 0; y <= ymax; y++ { + for x := 0; x <= xmax; x++ { + _, ok := g[Point{x, y}] + if ok { + sb.WriteString("█") + } else { + sb.WriteString(" ") + } + } + sb.WriteString("\n") + } + return sb.String() +}