127 lines
2.9 KiB
Go
127 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
// "strings"
|
|
"bufio"
|
|
// "math"
|
|
"os"
|
|
"strconv"
|
|
"regexp"
|
|
"sync"
|
|
)
|
|
|
|
type Race struct {
|
|
mu sync.Mutex
|
|
total int
|
|
}
|
|
|
|
func (r *Race) WeRaceBoys(time, distance int, wg *sync.WaitGroup) {
|
|
// As we just need to find the minimum necessary and then subtract it from
|
|
// the maximum, probably a good idea starting form the middle
|
|
tempTime := 0
|
|
for i := int(time/2); i > 0; i-- {
|
|
tempDist := i * (time - i)
|
|
if tempDist <= distance {
|
|
tempTime = i + 1
|
|
break
|
|
}
|
|
}
|
|
// If the minimum is tempTime, then the maximum is time - tempTime
|
|
// time - 2*tempTime is the number of possible victories
|
|
r.mu.Lock()
|
|
r.total *= (time - (2 * tempTime - 1))
|
|
r.mu.Unlock()
|
|
wg.Done()
|
|
}
|
|
|
|
func MultRaceDist(time, dist []string) ([]int, []int){
|
|
tempT, tempD := make([]int, 0), make([]int, 0)
|
|
for i := range time {
|
|
num, _ := strconv.Atoi(time[i])
|
|
tempT = append(tempT, num)
|
|
num, _ = strconv.Atoi(dist[i])
|
|
tempD = append(tempD, num)
|
|
}
|
|
return tempT, tempD
|
|
}
|
|
|
|
func SingleRaceDist(time, dist []string) (int, int) {
|
|
strT, strD := "", ""
|
|
numT, numD := 0, 0
|
|
// Create two big strings
|
|
for i := range time {
|
|
strT += time[i]
|
|
strD += dist[i]
|
|
}
|
|
|
|
numT, _ = strconv.Atoi(strT)
|
|
numD, _ = strconv.Atoi(strD)
|
|
|
|
return numT, numD
|
|
}
|
|
|
|
func check(e error) {
|
|
if e != nil {
|
|
panic(e)
|
|
}
|
|
}
|
|
|
|
func PrintAndWait(x ...any) {
|
|
fmt.Print(x...)
|
|
fmt.Scanln()
|
|
}
|
|
|
|
func main() {
|
|
|
|
file, err := os.Open("./inputs/day06_input")
|
|
check(err)
|
|
defer file.Close()
|
|
|
|
// Struct for multiple races
|
|
rMult := Race{
|
|
total: 1,
|
|
}
|
|
// Struct for a single race
|
|
rSing := Race{
|
|
total: 1,
|
|
}
|
|
_ = &rSing
|
|
var wg sync.WaitGroup
|
|
|
|
// Regex that finds the numbers in a row
|
|
renum := regexp.MustCompile("[0-9]+")
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
time, distance := make([]int, 0), make([]int, 0)
|
|
tempStrings := make([]string, 0)
|
|
// Generic, would work for more rows
|
|
for scanner.Scan() {
|
|
tempStrings = append(tempStrings, scanner.Text())
|
|
}
|
|
// Now populate time and distance
|
|
timeStr := renum.FindAllString(tempStrings[0], - 1)
|
|
distStr := renum.FindAllString(tempStrings[1], - 1)
|
|
|
|
time, distance = MultRaceDist(timeStr, distStr)
|
|
|
|
// E.g.: if I hold the button for 1ms and then release it, it will travel at
|
|
// 1mm/ms fo the remaining amount of seconds.
|
|
// We can skip the holding down 0 and tMAX ms.
|
|
// Once we find the MIN amount of ms necessary to win, the limit is
|
|
// MAX - MIN
|
|
wg.Add(len(time))
|
|
for i := 0; i < len(time); i++ {
|
|
go rMult.WeRaceBoys(time[i], distance[i], &wg)
|
|
}
|
|
|
|
// Silly implementation of the single race
|
|
singT, singD := SingleRaceDist(timeStr, distStr)
|
|
wg.Add(1)
|
|
go rSing.WeRaceBoys(singT, singD, &wg)
|
|
|
|
wg.Wait()
|
|
fmt.Printf("Multiple races result: %d.\n", rMult.total)
|
|
fmt.Printf("Single race result: %d.\n", rSing.total)
|
|
}
|