package main import ( "bufio" "fmt" "os" "strconv" "time" ) func mustAtoi(line string) int { i, _ := strconv.Atoi(line) return i } func main() { start := time.Now() partOne() duration := time.Since(start) partTwo() duration2 := time.Since(start) fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration) } func makeScanner(test bool) *bufio.Scanner { var f *os.File if test { f, _ = os.Open("inputs/testinput") } else { f, _ = os.Open("inputs/input") } reader := bufio.NewReader(f) return bufio.NewScanner(reader) } type targetArea struct { startx int endx int starty int endy int } func ParseInput(line string) targetArea { target := targetArea{} acc := "" for i := 0; i < len(line); i++ { switch line[i] { case '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-': acc += string(line[i]) case '.': i++ // skip the second . if target.startx == 0 { target.startx = mustAtoi(acc) } else { target.starty = mustAtoi(acc) } acc = "" case ',': target.endx = mustAtoi(acc) acc = "" default: // all other characters do nothing } target.endy = mustAtoi(acc) } return target } func InTarget(x, y int, target targetArea) bool { return x >= target.startx && x <= target.endx && y <= target.endy && y >= target.starty } func BeyondTarget(x, y int, target targetArea) bool { return x > target.endx || y < target.starty } type probe struct { xvelocity int yvelocity int x int y int maxy int } func (p *probe) Step() { p.x += p.xvelocity p.y += p.yvelocity if p.xvelocity > 0 { p.xvelocity-- } else if p.xvelocity < 0 { p.xvelocity++ } p.yvelocity-- if p.y > p.maxy { p.maxy = p.y } } func partOne() { scanner := makeScanner(false) // read line scanner.Scan() line := scanner.Text() target := ParseInput(line) highestArc := 0 for j := 1; j < 50; j++ { for k := 1; k < 100; k++ { initx := j inity := k p := &probe{ xvelocity: initx, yvelocity: inity, } for { p.Step() if InTarget(p.x, p.y, target) { if p.maxy > highestArc { highestArc = p.maxy } } if BeyondTarget(p.x, p.y, target) { break } } } } fmt.Println(highestArc) } func partTwo() { scanner := makeScanner(false) // read line scanner.Scan() line := scanner.Text() target := ParseInput(line) hits := 0 for j := 0; j < 1000; j++ { for k := -200; k < 1000; k++ { initx := j inity := k p := &probe{ xvelocity: initx, yvelocity: inity, } for { p.Step() if InTarget(p.x, p.y, target) { hits++ break } if BeyondTarget(p.x, p.y, target) { break } } } } fmt.Println(hits) }