mirror of
https://github.com/onyx-and-iris/aoc2023.git
synced 2024-11-21 18:00:47 +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