package main

import (
	"bufio"
	"log"
	"math"
	"os"
	"regexp"
	"strconv"
)

type pos struct {
	x, y int
}

func main() {
	if err := myMain(); err != nil {
		log.Println(err)
	}
}

func myMain() error {
	t, err := parseInput("input.txt")
	if err != nil {
		return err
	}

	log.Printf("%+v", t)

	log.Println(solveFirst(t))

	return nil
}

func abs(num int) int {
	if num < 0 {
		return -num
	}
	return num
}

func solveFirst(trg target) int {
	var (
		TMAX = 10000

		VX0MIN = int(math.Sqrt(float64(trg.xmin)) + 1)
		VX0MAX = trg.xmax

		VY0MIN = trg.ymin
		VY0MAX = abs(trg.ymin)
	)
	log.Println(VX0MIN, VX0MAX, VY0MIN, VY0MAX)

	var YMAX int
	var count int

	for vx0 := VX0MIN; vx0 <= VX0MAX; vx0++ {
		for vy0 := VY0MIN; vy0 <= VY0MAX; vy0++ {
			var x, y int
			var ymax int
			for t := 0; t < TMAX; t++ {
				x += velX(vx0, t)
				y += velY(vy0, t)
				// log.Println(x, y)

				if y > ymax {
					ymax = y
				}

				if trg.hit(x, y) {
					// log.Printf("HIT: x: %d, y: %d, vx0: %d, vy0: %d", x, y, vx0, vy0)
					if ymax > YMAX {
						YMAX = ymax
					}
					count++
					break
				}

				if trg.noWay(x, y) {
					break
				}
			}
		}
	}
	log.Println(count)
	return YMAX
}

func (trg target) hit(x, y int) bool {
	if x >= trg.xmin && x <= trg.xmax &&
		y >= trg.ymin && y <= trg.ymax {
		return true
	}
	return false
}

func (trg target) noWay(x, y int) bool {
	if x > trg.xmax {
		return true
	}
	if y < trg.ymin {
		return true
	}
	return false
}

func velX(vx0 int, t int) int {
	vel := vx0 - t
	if vel > 0 {
		return vel
	}
	return 0
}

func velY(vy0 int, t int) int {
	return vy0 - t
}

type target struct {
	xmin, xmax, ymin, ymax int
}

func parseInput(fileName string) (target, error) {
	ret := target{}
	fd, err := os.Open(fileName)
	if err != nil {
		return ret, err
	}
	defer fd.Close()

	re := regexp.MustCompile(`[-]?\d+`)

	buf := bufio.NewScanner(fd)
	for buf.Scan() {
		tmp := re.FindAllString(buf.Text(), -1)
		ret.xmin, err = strconv.Atoi(tmp[0])
		if err != nil {
			return ret, err
		}
		ret.xmax, err = strconv.Atoi(tmp[1])
		if err != nil {
			return ret, err
		}
		ret.ymin, err = strconv.Atoi(tmp[2])
		if err != nil {
			return ret, err
		}
		ret.ymax, err = strconv.Atoi(tmp[3])
		if err != nil {
			return ret, err
		}
	}
	return ret, nil
}