Skip to content

Commit

Permalink
adds 2021\17
Browse files Browse the repository at this point in the history
  • Loading branch information
jdrst committed Dec 17, 2021
1 parent c3ae7db commit 55b864f
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 4 deletions.
1 change: 1 addition & 0 deletions 2021/17/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target area: x=287..309, y=-76..-48
166 changes: 166 additions & 0 deletions 2021/17/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package main

import (
"fmt"
"math"

"github.com/jdrst/adventofgo/util"
)

func main() {
fmt.Printf("First part: %v\n", partOne(util.ReadFile("input.txt")))
fmt.Printf("Second part: %v\n", partTwo(util.ReadFile("input.txt")))
}

type foo struct {
initVelocity, t int
}

type bar struct {
xVel, yVel, t int
}

func partOne(file util.File) int {
lines := file.AsLines()
var xmin, xmax, ymin, ymax int
fmt.Sscanf(string(lines[0]), "target area: x=%d..%d, y=%d..%d", &xmin, &xmax, &ymin, &ymax)
xsize := util.Delta(xmax, xmin)
ysize := util.Delta(ymax, ymin)

target := make([][]util.Point, xsize+1)
for i := 0; i <= xsize; i++ {
target[i] = make([]util.Point, ysize+1)
for j := 0; j <= ysize; j++ {
target[i][j] = util.Point{X: xmin + i, Y: ymin + j}
}
}

possibleYs := []foo{}
next:
for traj := ymin; traj < util.Abs(ymin); traj++ {
curr := traj
if curr <= ymax && curr >= ymin {
possibleYs = append(possibleYs, foo{initVelocity: traj, t: 0})
}
for t := 1; ; t++ {
dy := yy(traj, t)
curr += dy
if curr < ymin {
continue next
}
if curr <= ymax && curr >= ymin {
possibleYs = append(possibleYs, foo{initVelocity: traj, t: t})
}
}
}

possibleXYs := []bar{}
for _, t := range possibleYs {
for traj := 0; traj <= xmax; traj++ {
curr := traj
for i := 0; i < t.t; i++ {
dx := xx(traj, i)
if dx == 0 {
break
}
curr += dx
}
if curr <= xmax && curr >= xmin {
possibleXYs = append(possibleXYs, bar{xVel: traj, yVel: t.initVelocity, t: t.t})
}
}
}

maxY := math.MinInt
for _, xy := range possibleXYs {
curr := getHighestPointOfTrajectory(xy.yVel)
if curr > maxY {
maxY = curr
}
}
return maxY
}

func partTwo(file util.File) int {
lines := file.AsLines()
var xmin, xmax, ymin, ymax int
fmt.Sscanf(string(lines[0]), "target area: x=%d..%d, y=%d..%d", &xmin, &xmax, &ymin, &ymax)
xsize := util.Delta(xmax, xmin)
ysize := util.Delta(ymax, ymin)

target := make([][]util.Point, xsize+1)
for i := 0; i <= xsize; i++ {
target[i] = make([]util.Point, ysize+1)
for j := 0; j <= ysize; j++ {
target[i][j] = util.Point{X: xmin + i, Y: ymin + j}
}
}

possibleYs := []foo{}
next:
for traj := ymin; traj < util.Abs(ymin); traj++ {
curr := traj
if curr <= ymax && curr >= ymin {
possibleYs = append(possibleYs, foo{initVelocity: traj, t: 0})
}
for t := 1; ; t++ {
dy := yy(traj, t)
curr += dy
if curr < ymin {
continue next
}
if curr <= ymax && curr >= ymin {
possibleYs = append(possibleYs, foo{initVelocity: traj, t: t})
}
}

}

possibleXYs := []bar{}
for _, t := range possibleYs {
for traj := 0; traj <= xmax; traj++ {
curr := traj
for i := 1; i <= t.t; i++ {
dx := xx(traj, i)
if dx == 0 {
break
}
curr += dx
}
if curr <= xmax && curr >= xmin {
possibleXYs = append(possibleXYs, bar{xVel: traj, yVel: t.initVelocity, t: t.t})
}
}
}

unique := map[util.Point]bool{}
for _, xy := range possibleXYs {
if _, exists := unique[util.Point{X: xy.xVel, Y: xy.yVel}]; exists {
continue
}
unique[util.Point{X: xy.xVel, Y: xy.yVel}] = true
}
return len(unique)
}

func getHighestPointOfTrajectory(y int) int {
return (y * (y + 1)) / 2
}

func yy(y, t int) int {
return y - t
}

func xx(x, t int) int {
for i := 0; i < t; i++ {
switch {
case x == 0:
return x
case x > 0:
x--
case x < 0:
x++
}
}
return x
}
39 changes: 39 additions & 0 deletions 2021/17/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

import (
"testing"

"github.com/jdrst/adventofgo/util"
)

var testInput = `target area: x=20..30, y=-10..-5`

func TestPartOne(t *testing.T) {
expected := 45
actual := partOne(util.File(testInput).WithOSLinebreaks())
if actual != expected {
t.Errorf("expected was: %v \n actual is: %v", expected, actual)
}
}

func TestPartTwo(t *testing.T) {
expected := 112
actual := partTwo(util.File(testInput).WithOSLinebreaks())
if actual != expected {
t.Errorf("\nexpected was: %v\nactual is: %v", expected, actual)
}
}

func BenchmarkPartOne(b *testing.B) {
input := util.ReadFile("input.txt")
for n := 0; n < b.N; n++ {
partOne(input)
}
}

func BenchmarkPartTwo(b *testing.B) {
input := util.ReadFile("input.txt")
for n := 0; n < b.N; n++ {
partTwo(input)
}
}
8 changes: 4 additions & 4 deletions util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,15 @@ func (n *Point) NeighboursWithDiagonal(maxX, maxY int) []Point {

//ManhattanDistance returns the manhattan distance between two points (delta between x's plus delta between y's)
func ManhattanDistance(a, b Point) int {
return delta(a.X, b.X) + delta(a.Y, b.Y)
return Delta(a.X, b.X) + Delta(a.Y, b.Y)
}

func abs(x int) int {
func Abs(x int) int {
if x < 0 {
return x * -1
}
return x
}
func delta(x, y int) int {
return abs(x - y)
func Delta(x, y int) int {
return Abs(x - y)
}

0 comments on commit 55b864f

Please sign in to comment.