mirror of
https://github.com/onyx-and-iris/aoc2023.git
synced 2024-11-15 15:10:49 +00:00
day-6
This commit is contained in:
parent
fd65c94298
commit
60ef7a0557
3
day-6/go.mod
Normal file
3
day-6/go.mod
Normal file
@ -0,0 +1,3 @@
|
||||
module github.com/onyx-and-iris/aoc2023/day-6
|
||||
|
||||
go 1.20
|
39
day-6/one.go
Normal file
39
day-6/one.go
Normal file
@ -0,0 +1,39 @@
|
||||
package main
|
||||
|
||||
type data struct {
|
||||
time int
|
||||
distance int
|
||||
}
|
||||
|
||||
var datas = make([]data, 0)
|
||||
|
||||
// calculate returns the number of different ways to win a single race
|
||||
func calculate(time, recordDistance int) int {
|
||||
distanceCovered := 0
|
||||
numWins := 0
|
||||
|
||||
f := func(x, time int) int {
|
||||
return x * (time - x)
|
||||
}
|
||||
|
||||
for i := 1; i < time; i++ {
|
||||
distanceCovered = f(i, time)
|
||||
if distanceCovered > recordDistance {
|
||||
numWins++
|
||||
}
|
||||
}
|
||||
return numWins
|
||||
}
|
||||
|
||||
// one returns the product of all race calculations
|
||||
func one(lines []string) int {
|
||||
parseLines(lines)
|
||||
|
||||
product := 1
|
||||
for _, data := range datas {
|
||||
n := calculate(data.time, data.distance)
|
||||
product *= n
|
||||
}
|
||||
|
||||
return product
|
||||
}
|
16
day-6/one_test.go
Normal file
16
day-6/one_test.go
Normal file
@ -0,0 +1,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/go-playground/assert"
|
||||
)
|
||||
|
||||
func TestCalculate(t *testing.T) {
|
||||
//t.Skip("skipping test")
|
||||
res := calculate(7, 9)
|
||||
|
||||
t.Run("Should produce an equal number of win possibilities", func(t *testing.T) {
|
||||
assert.Equal(t, []int{2, 3, 4, 5}, res)
|
||||
})
|
||||
}
|
21
day-6/solution.go
Normal file
21
day-6/solution.go
Normal file
@ -0,0 +1,21 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
}
|
||||
|
||||
func main() {
|
||||
lines := readlines()
|
||||
|
||||
ans := one(lines)
|
||||
fmt.Printf("solution one: %d\n", ans)
|
||||
|
||||
ans = two(lines)
|
||||
fmt.Printf("solution two: %d\n", ans)
|
||||
}
|
34
day-6/two.go
Normal file
34
day-6/two.go
Normal file
@ -0,0 +1,34 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// calculateFaster uses quadratic formula to calculate number of ways to win
|
||||
func calculateFaster(time, recordDistance int) int {
|
||||
a := float64(-1)
|
||||
b := float64(time)
|
||||
c := float64(-(recordDistance + 1))
|
||||
|
||||
x1 := (-b + math.Sqrt(math.Pow(b, 2)-4*a*c)) / (2 * a)
|
||||
x2 := (-b - math.Sqrt(math.Pow(b, 2)-4*a*c)) / (2 * a)
|
||||
|
||||
return int(math.Floor(x2) - math.Ceil(x1) + 1)
|
||||
}
|
||||
|
||||
func two(lines []string) int {
|
||||
timeStr := ""
|
||||
distStr := ""
|
||||
for _, data := range datas {
|
||||
timeStr += fmt.Sprintf("%d", data.time)
|
||||
distStr += fmt.Sprintf("%d", data.distance)
|
||||
}
|
||||
time, _ := strconv.Atoi(timeStr)
|
||||
distance, _ := strconv.Atoi(distStr)
|
||||
|
||||
n := calculateFaster(time, distance)
|
||||
|
||||
return n
|
||||
}
|
57
day-6/util.go
Normal file
57
day-6/util.go
Normal file
@ -0,0 +1,57 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// readlines reads lines from stdin.
|
||||
// Then it returns them as an array of strings
|
||||
func readlines() []string {
|
||||
lines := []string{}
|
||||
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
for scanner.Scan() {
|
||||
lines = append(lines, scanner.Text())
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return lines
|
||||
}
|
||||
|
||||
func parseLines(lines []string) {
|
||||
f := func(c rune) bool {
|
||||
return !unicode.IsDigit(c)
|
||||
}
|
||||
|
||||
times := []int{}
|
||||
distances := []int{}
|
||||
for _, line := range lines {
|
||||
if strings.HasPrefix(line, "Time") {
|
||||
times = convertToInts(strings.FieldsFunc(line, f))
|
||||
} else {
|
||||
distances = convertToInts(strings.FieldsFunc(line, f))
|
||||
}
|
||||
}
|
||||
|
||||
for i := range times {
|
||||
datas = append(datas, data{time: times[i], distance: distances[i]})
|
||||
}
|
||||
}
|
||||
|
||||
// convertToInts converts a string representing ints to an array of ints
|
||||
func convertToInts(data []string) []int {
|
||||
nums := []int{}
|
||||
for _, elem := range data {
|
||||
n, _ := strconv.Atoi(elem)
|
||||
nums = append(nums, n)
|
||||
}
|
||||
return nums
|
||||
}
|
Loading…
Reference in New Issue
Block a user