mirror of
https://github.com/onyx-and-iris/aoc2023.git
synced 2024-11-15 15:10:49 +00:00
day-2
This commit is contained in:
parent
07d24c2e8a
commit
bf97f15d04
3
day-2/go.mod
Normal file
3
day-2/go.mod
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module github.com/onyx-and-iris/aoc2023/day-2
|
||||||
|
|
||||||
|
go 1.20
|
65
day-2/one.go
Normal file
65
day-2/one.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var regex = map[string]*regexp.Regexp{
|
||||||
|
"red": regexp.MustCompile(`(?P<red>\d+) red`),
|
||||||
|
"green": regexp.MustCompile(`(?P<green>\d+) green`),
|
||||||
|
"blue": regexp.MustCompile(`(?P<blue>\d+) blue`),
|
||||||
|
"game": regexp.MustCompile(`Game (?P<game>\d+)`),
|
||||||
|
}
|
||||||
|
|
||||||
|
var limits = map[string]int{
|
||||||
|
"red": 12,
|
||||||
|
"green": 13,
|
||||||
|
"blue": 14,
|
||||||
|
}
|
||||||
|
|
||||||
|
// isValidGame calculates if a game was possible based on the limits of each cube colour
|
||||||
|
func isValidGame(data string) (bool, error) {
|
||||||
|
valid := true
|
||||||
|
for _, colour := range []string{"red", "green", "blue"} {
|
||||||
|
m := regex[colour].FindAllStringSubmatch(data, -1)
|
||||||
|
for _, s := range m {
|
||||||
|
n, err := strconv.Atoi(s[1])
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if n > limits[colour] {
|
||||||
|
valid = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return valid, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// one returns the sum of ids for all games that were possible
|
||||||
|
func one(lines []string) (int, error) {
|
||||||
|
sum := 0
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
identifier, data := func() (string, string) {
|
||||||
|
x := strings.Split(line, ":")
|
||||||
|
return x[0], x[1]
|
||||||
|
}()
|
||||||
|
|
||||||
|
isValidGame, err := isValidGame(data)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if isValidGame {
|
||||||
|
id, err := getIdForGame(identifier)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
sum += id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum, nil
|
||||||
|
}
|
41
day-2/one_test.go
Normal file
41
day-2/one_test.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIsValidGame(t *testing.T) {
|
||||||
|
//t.Skip("skipping test")
|
||||||
|
game1 := "3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green"
|
||||||
|
game2 := "1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue"
|
||||||
|
game3 := "8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red"
|
||||||
|
game4 := "1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red"
|
||||||
|
game5 := "6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green"
|
||||||
|
isValid1, _ := isValidGame(game1)
|
||||||
|
isValid2, _ := isValidGame(game2)
|
||||||
|
isValid3, _ := isValidGame(game3)
|
||||||
|
isValid4, _ := isValidGame(game4)
|
||||||
|
isValid5, _ := isValidGame(game5)
|
||||||
|
|
||||||
|
t.Run("Should be a valid game", func(t *testing.T) {
|
||||||
|
assert.Equal(t, true, isValid1)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should be a valid game", func(t *testing.T) {
|
||||||
|
assert.Equal(t, true, isValid2)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should not be a valid game", func(t *testing.T) {
|
||||||
|
assert.Equal(t, false, isValid3)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should not be a valid game", func(t *testing.T) {
|
||||||
|
assert.Equal(t, false, isValid4)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should be a valid game", func(t *testing.T) {
|
||||||
|
assert.Equal(t, true, isValid5)
|
||||||
|
})
|
||||||
|
}
|
5
day-2/run.sh
Executable file
5
day-2/run.sh
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
INPUT="input.txt"
|
||||||
|
|
||||||
|
cat $INPUT | go run .
|
22
day-2/solution.go
Normal file
22
day-2/solution.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
lines := readlines()
|
||||||
|
|
||||||
|
ans, err := one(lines)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("solution one: %d\n", ans)
|
||||||
|
|
||||||
|
ans, err = two(lines)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("solution two: %d\n", ans)
|
||||||
|
}
|
51
day-2/two.go
Normal file
51
day-2/two.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// powerForGame returns the power of the minimum set of cubes for a game
|
||||||
|
func powerForGame(data string) (int, error) {
|
||||||
|
var counter = map[string]int{
|
||||||
|
"red": 0,
|
||||||
|
"green": 0,
|
||||||
|
"blue": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, colour := range []string{"red", "green", "blue"} {
|
||||||
|
m := regex[colour].FindAllStringSubmatch(data, -1)
|
||||||
|
for _, s := range m {
|
||||||
|
n, err := strconv.Atoi(s[1])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if counter[colour] == 0 {
|
||||||
|
counter[colour] = n
|
||||||
|
} else if counter[colour] < n {
|
||||||
|
counter[colour] = n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return counter["red"] * counter["green"] * counter["blue"], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// two returns the sum of powers for all games
|
||||||
|
func two(lines []string) (int, error) {
|
||||||
|
sum := 0
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
_, data := func() (string, string) {
|
||||||
|
x := strings.Split(line, ":")
|
||||||
|
return x[0], x[1]
|
||||||
|
}()
|
||||||
|
|
||||||
|
pow, err := powerForGame(data)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
sum += pow
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum, nil
|
||||||
|
}
|
42
day-2/two_test.go
Normal file
42
day-2/two_test.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPowerForGame(t *testing.T) {
|
||||||
|
//t.Skip("skipping test")
|
||||||
|
game1 := "3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green"
|
||||||
|
game2 := "1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue"
|
||||||
|
game3 := "8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red"
|
||||||
|
game4 := "1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red"
|
||||||
|
game5 := "6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green"
|
||||||
|
|
||||||
|
power1, _ := powerForGame(game1)
|
||||||
|
power2, _ := powerForGame(game2)
|
||||||
|
power3, _ := powerForGame(game3)
|
||||||
|
power4, _ := powerForGame(game4)
|
||||||
|
power5, _ := powerForGame(game5)
|
||||||
|
|
||||||
|
t.Run("Should have power value 48", func(t *testing.T) {
|
||||||
|
assert.Equal(t, 48, power1)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should have power value 12", func(t *testing.T) {
|
||||||
|
assert.Equal(t, 12, power2)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should have power value 1560", func(t *testing.T) {
|
||||||
|
assert.Equal(t, 1560, power3)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should have power value 630", func(t *testing.T) {
|
||||||
|
assert.Equal(t, 630, power4)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should have power value 36", func(t *testing.T) {
|
||||||
|
assert.Equal(t, 36, power5)
|
||||||
|
})
|
||||||
|
}
|
37
day-2/util.go
Normal file
37
day-2/util.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// getIdForGame returns the id for a game
|
||||||
|
func getIdForGame(identifier string) (int, error) {
|
||||||
|
m := regex["game"].FindStringSubmatch(identifier)
|
||||||
|
i := regex["game"].SubexpIndex("game")
|
||||||
|
id, err := strconv.Atoi(m[i])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return id, nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user