You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
3.5 KiB
Go
139 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"AOC2021/src/helper"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
type checkHitFunc func(int, [2]int) (bool, int)
|
|
|
|
type targetArea struct {
|
|
xValues [2]int
|
|
yValues [2]int
|
|
}
|
|
|
|
func main() {
|
|
args := os.Args[1:]
|
|
input, err := helper.GetInput(args[0])
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
coordinateString := strings.Split(input[0], ": ")[1]
|
|
coordinateString = helper.RemoveCharactersFromString(coordinateString, "yx=")
|
|
coordinateStringSplit := strings.Split(coordinateString, ", ")
|
|
xValues, _ := helper.MapToNumber(strings.Split(coordinateStringSplit[0], ".."))
|
|
yValues, _ := helper.MapToNumber(strings.Split(coordinateStringSplit[1], ".."))
|
|
area := targetArea{xValues: [2]int{xValues[0], xValues[1]}, yValues: [2]int{yValues[0], yValues[1]}}
|
|
fmt.Println(area)
|
|
hitFunctionUpward := getcheckHitFunction(changeVelocityUpward, true)
|
|
hitFunctionForward := getcheckHitFunction(changeVelocityForward, false)
|
|
|
|
//Part 1
|
|
highestY, maxHeight := getHighestPossibleVelocityWhichStillHits(area.yValues, hitFunctionUpward)
|
|
fmt.Printf("Highest Y: %d Max Height: %d \n", highestY, maxHeight)
|
|
|
|
testPointsString, err := helper.GetInput("day17TestPart2Points.txt")
|
|
var testPoints [][2]int
|
|
for _, pointString := range testPointsString {
|
|
testPointIntArray, _ := helper.MapToNumber(strings.Split(pointString,","))
|
|
testPoints = append(testPoints, [2]int{testPointIntArray[0],testPointIntArray[1]})
|
|
}
|
|
//Part 2
|
|
possibleYs := getAllPossibleVelocitiesWhichStillHits(area.yValues, hitFunctionUpward, highestY, yValues[0])
|
|
possibleXs := getAllPossibleVelocitiesWhichStillHits(area.xValues, hitFunctionForward, xValues[1], 1)
|
|
fmt.Println(possibleXs)
|
|
fmt.Println(possibleYs)
|
|
sum := 0
|
|
for _, possibleY := range possibleYs {
|
|
for _, possibleX := range possibleXs {
|
|
if checkHitXAndY(possibleX,possibleY, &area){
|
|
sum +=1
|
|
}
|
|
}
|
|
}
|
|
fmt.Println(sum)
|
|
|
|
}
|
|
|
|
func getHighestPossibleVelocityWhichStillHits(target [2]int, checkHitFunc checkHitFunc) (int, int) {
|
|
hit := true
|
|
max := 0
|
|
n := 1000
|
|
for {
|
|
hit, max = checkHitFunc(n, target)
|
|
if hit {
|
|
return n, max
|
|
}
|
|
n--
|
|
}
|
|
}
|
|
|
|
func getAllPossibleVelocitiesWhichStillHits(target [2]int, checkHitFunc checkHitFunc, highestVelocity int, lowestVelocity int) (hits []int) {
|
|
n := highestVelocity
|
|
for n >= lowestVelocity {
|
|
hit, _ := checkHitFunc(n, target)
|
|
if hit {
|
|
hits = append(hits, n)
|
|
}
|
|
n--
|
|
}
|
|
return hits
|
|
}
|
|
|
|
func getcheckHitFunction(velocityChangeFunction func(*int), lowBorder bool) checkHitFunc {
|
|
var whileFunc func(int, [2]int, int) bool
|
|
if lowBorder {
|
|
whileFunc = func(n int,target [2]int, velcoity int) bool{
|
|
return n > target[0]
|
|
}
|
|
}else {
|
|
whileFunc = func(n int,target [2]int, velocity int) bool{
|
|
return n < target[1] && velocity != 0
|
|
}
|
|
}
|
|
return func(velocity int, target [2]int) (bool, int) {
|
|
n := 0
|
|
max := 0
|
|
for whileFunc(n,target,velocity) {
|
|
n += velocity
|
|
if n > max {
|
|
max = n
|
|
}
|
|
velocityChangeFunction(&velocity)
|
|
if n >= target[0] && n <= target[1] {
|
|
return true, max
|
|
}
|
|
}
|
|
return false, max
|
|
}
|
|
}
|
|
|
|
func changeVelocityUpward(velocity *int) {
|
|
*velocity -= 1
|
|
}
|
|
|
|
func changeVelocityForward(velocity *int) {
|
|
if *velocity > 0 {
|
|
*velocity -= 1
|
|
}
|
|
if *velocity < 0 {
|
|
*velocity += 1
|
|
}
|
|
}
|
|
|
|
func checkHitXAndY(forward int, upward int, area *targetArea) bool {
|
|
x := 0
|
|
y := 0
|
|
for x <= area.xValues[1] && y >= area.yValues[0] {
|
|
x += forward
|
|
y += upward
|
|
changeVelocityUpward(&upward)
|
|
changeVelocityForward(&forward)
|
|
if x <= area.xValues[1] && y >= area.yValues[0] && x >= area.xValues[0] && y <= area.yValues[1] {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
} |