2023-12-02 20:57:50 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"strconv"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
func mustAtoi(line string) int {
|
|
|
|
i, _ := strconv.Atoi(line)
|
|
|
|
return i
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
start := time.Now()
|
|
|
|
partOne()
|
|
|
|
duration := time.Since(start)
|
|
|
|
partTwo()
|
|
|
|
duration2 := time.Since(start)
|
|
|
|
fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration)
|
|
|
|
}
|
|
|
|
|
|
|
|
func makeScanner(test bool) *bufio.Scanner {
|
|
|
|
var f *os.File
|
|
|
|
if test {
|
|
|
|
f, _ = os.Open("inputs/testinput")
|
|
|
|
} else {
|
|
|
|
f, _ = os.Open("inputs/input")
|
|
|
|
}
|
|
|
|
reader := bufio.NewReader(f)
|
|
|
|
return bufio.NewScanner(reader)
|
|
|
|
}
|
|
|
|
|
|
|
|
type game struct {
|
|
|
|
red int
|
|
|
|
green int
|
|
|
|
blue int
|
|
|
|
}
|
|
|
|
|
2023-12-02 21:20:21 +00:00
|
|
|
func parseRound(line string) game {
|
|
|
|
g := game{}
|
|
|
|
n := []byte{}
|
|
|
|
for i := 0; i < len(line); i++ {
|
|
|
|
switch line[i] {
|
|
|
|
case ' ':
|
|
|
|
continue
|
|
|
|
case ',':
|
|
|
|
i++
|
|
|
|
continue
|
|
|
|
case '1', '2', '3', '4', '5', '6', '7', '8', '9', '0':
|
|
|
|
n = append(n, line[i])
|
|
|
|
case 'r':
|
|
|
|
g.red = mustAtoi(string(n))
|
|
|
|
n = []byte{}
|
|
|
|
i += 4
|
|
|
|
case 'g':
|
|
|
|
g.green = mustAtoi(string(n))
|
|
|
|
n = []byte{}
|
|
|
|
i += 6
|
|
|
|
case 'b':
|
|
|
|
g.blue = mustAtoi(string(n))
|
|
|
|
n = []byte{}
|
|
|
|
i += 5
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return g
|
|
|
|
}
|
|
|
|
|
2023-12-02 20:57:50 +00:00
|
|
|
func partOne() {
|
|
|
|
scanner := makeScanner(false)
|
|
|
|
|
|
|
|
sum := 0
|
|
|
|
round := 0
|
|
|
|
max := game{
|
|
|
|
red: 12,
|
|
|
|
green: 13,
|
|
|
|
blue: 14,
|
|
|
|
}
|
|
|
|
for scanner.Scan() {
|
|
|
|
line := scanner.Text()
|
|
|
|
ok := true
|
|
|
|
round++
|
2023-12-02 21:29:31 +00:00
|
|
|
for i, c := range line {
|
|
|
|
if c == ':' {
|
|
|
|
line = line[i+2:]
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var start, end int
|
|
|
|
for i, c := range line {
|
|
|
|
if c == ';' || i == len(line)-1 {
|
|
|
|
end = i + 1
|
|
|
|
g := parseRound(line[start:end])
|
|
|
|
if g.red > max.red || g.blue > max.blue || g.green > max.green {
|
|
|
|
ok = false
|
|
|
|
}
|
|
|
|
start = i + 2
|
2023-12-02 20:57:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if ok {
|
|
|
|
sum += round
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fmt.Println(sum)
|
|
|
|
}
|
|
|
|
|
|
|
|
func partTwo() {
|
|
|
|
scanner := makeScanner(false)
|
|
|
|
|
|
|
|
sum := 0
|
|
|
|
for scanner.Scan() {
|
|
|
|
line := scanner.Text()
|
2023-12-02 21:29:31 +00:00
|
|
|
for i, c := range line {
|
|
|
|
if c == ':' {
|
|
|
|
line = line[i+2:]
|
|
|
|
break
|
2023-12-02 20:57:50 +00:00
|
|
|
}
|
2023-12-02 21:29:31 +00:00
|
|
|
}
|
|
|
|
max := game{}
|
|
|
|
var start, end int
|
|
|
|
for i, c := range line {
|
|
|
|
if c == ';' || i == len(line)-1 {
|
|
|
|
end = i + 1
|
|
|
|
g := parseRound(line[start:end])
|
|
|
|
if g.red > max.red {
|
|
|
|
max.red = g.red
|
|
|
|
}
|
|
|
|
if g.blue > max.blue {
|
|
|
|
max.blue = g.blue
|
|
|
|
}
|
|
|
|
if g.green > max.green {
|
|
|
|
max.green = g.green
|
|
|
|
}
|
|
|
|
start = i + 2
|
2023-12-02 20:57:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
sum += max.blue * max.green * max.red
|
|
|
|
}
|
|
|
|
fmt.Println(sum)
|
|
|
|
}
|