package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Println("Usage: day14 <seconds>")
		os.Exit(1)
	}
	raceTime := os.Args[1]
	var input []string
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		input = append(input, scanner.Text())
	}

	var allDeer []deer
	for i := range input {
		parts := strings.Split(input[i], " ")
		allDeer = append(allDeer, *createDeer(
			parts[0],
			mustAtoi(parts[3]),
			mustAtoi(parts[6]),
			mustAtoi(parts[13]),
		))
	}
	fmt.Println("Race ends at " + raceTime)
	endTime := mustAtoi(raceTime)
	deerStars := make(map[string]int)
	for i := 1; i <= endTime; i++ {
		var topVal int
		for j := range allDeer {
			tmp := allDeer[j].travelFor(i)
			if tmp > topVal {
				topVal = tmp
			}
		}
		for j := range allDeer {
			if allDeer[j].travelFor(i) == topVal {
				deerStars[allDeer[j].name]++
			}
		}
	}
	for i := range deerStars {
		fmt.Println(i + ": " + strconv.Itoa(deerStars[i]))
	}
}

type deer struct {
	name         string
	speed        int
	moveDuration int
	restDuration int
}

func createDeer(n string, s, m, r int) *deer {
	d := deer{n, s, m, r}
	return &d
}

func (d *deer) travelFor(s int) int {
	var dist int
	for s > 0 {
		if s > d.moveDuration {
			dist += d.speed * d.moveDuration
		} else {
			dist += d.speed * s
		}
		s -= d.moveDuration
		s -= d.restDuration
	}
	return dist
}

func mustAtoi(s string) int {
	var i int
	var err error
	if i, err = strconv.Atoi(s); err != nil {
		fmt.Println("Tried to atoi " + s)
	}
	return i
}
