diff --git a/challenges/2021/05-hydrothermalVenture/go/challenge.go b/challenges/2021/05-hydrothermalVenture/go/challenge.go new file mode 100644 index 0000000..0c81aed --- /dev/null +++ b/challenges/2021/05-hydrothermalVenture/go/challenge.go @@ -0,0 +1,136 @@ +package challenge + +import ( + "strconv" + "strings" + + "github.com/codemicro/adventOfCode/lib/aocgo" +) + +type Point struct { + x int + y int +} + +func pointFromString(input string) (*Point, error) { + sp := strings.Split(input, ",") + x, err := strconv.Atoi(sp[0]) + if err != nil { + return nil, err + } + y, err := strconv.Atoi(sp[1]) + if err != nil { + return nil, err + } + return &Point{x: x, y: y}, nil +} + +type Line [2]*Point + +func parse(instr string) ([]Line, error) { + var o []Line + for _, line := range strings.Split(strings.TrimSpace(instr), "\n") { + sp := strings.Split(line, " -> ") + p1, err := pointFromString(sp[0]) + if err != nil { + return nil, err + } + p2, err := pointFromString(sp[1]) + if err != nil { + return nil, err + } + o = append(o, Line{p1, p2}) + } + return o, nil +} + +func removeDiagonalLines(lines []Line) []Line { + var n int + for _, line := range lines { + if line[0].x == line[1].x || line[0].y == line[1].y { + lines[n] = line + n += 1 + } + } + return lines[:n] +} + +func iteratePoints(line Line) chan *Point { + + p1 := line[0] + p2 := line[1] + + delta_x := p2.x - p1.x + delta_y := p2.y - p1.y + + var xStep, yStep int + + if delta_x > 0 { + xStep = 1 + } else if delta_x < 0 { + xStep = -1 + } + + if delta_y > 0 { + yStep = 1 + } else if delta_y < 0 { + yStep = -1 + } + + c := make(chan *Point) + + go func() { + c <- p1 + lastPoint := *p1 + for lastPoint != *p2 { + np := &Point{ + x: lastPoint.x + xStep, + y: lastPoint.y + yStep, + } + c <- np + lastPoint = *np + } + close(c) + }() + + return c +} + +func countOverlappingPoints(lines []Line) int { + areas := make(map[Point]int) + for _, line := range lines { + for point := range iteratePoints(line) { + t := *point + areas[t] = areas[t] + 1 + } + } + + var numberOverlaps int + for _, n := range areas { + if n > 1 { + numberOverlaps += 1 + } + } + return numberOverlaps +} + +type Challenge struct { + aocgo.BaseChallenge +} + +func (c Challenge) One(instr string) (interface{}, error) { + lines, err := parse(instr) + if err != nil { + return nil, err + } + lines = removeDiagonalLines(lines) + return countOverlappingPoints(lines), nil +} + +func (c Challenge) Two(instr string) (interface{}, error) { + lines, err := parse(instr) + if err != nil { + return nil, err + } + return countOverlappingPoints(lines), nil +} diff --git a/challenges/2021/README.md b/challenges/2021/README.md index f085bd5..0ac74d0 100644 --- a/challenges/2021/README.md +++ b/challenges/2021/README.md @@ -14,7 +14,7 @@ Solutions to the [2021 Advent of Code](https://adventofcode.com/2021). | 02 - Dive! | Complete | [Python](02-dive/py), [Go](02-dive/go) | Have this set of instructions and do something sensible with it. | | 03 - Binary Diagnostic | Complete | [Python](03-binaryDiagnostic/py), [Nim](03-binaryDiagnostic/nim) | Bit twiddling aplenty! | | 04 - Giant Squid | Complete | [Python](04-giantSquid/py) | B-I-N-G-O, B-I-N-G-O, B-I-N-G-O and Bingo was his name-o! | -| 05 - Hydrothermal Venture | Complete | [Python](05-hydrothermalVenture/py) | Pointy. | +| 05 - Hydrothermal Venture | Complete | [Python](05-hydrothermalVenture/py), [Go](05-hydrothermalVenture/go) | Pointy. |