Commit bf5e909

bryfry <bryon.fryer@gmail.com>
2023-12-02 01:31:07
day 2
1 parent b0f689a
2023/go/01/main.go
@@ -0,0 +1,86 @@
+package main
+
+import (
+	"advent2023/internal/aoc"
+	"log"
+	"strconv"
+	"strings"
+)
+
+func solvePart1(input []string) (solution int) {
+	sum := 0
+	for _, line := range input {
+		first := ""
+		last := ""
+		for _, c := range line {
+			if _, err := strconv.Atoi(string(c)); err == nil {
+				if first == "" {
+					first = string(c)
+				}
+				last = string(c)
+			}
+		}
+		value, err := strconv.Atoi(strings.Join([]string{first, last}, ""))
+		if err != nil {
+			log.Fatal(err)
+		}
+		sum = sum + value
+	}
+	return sum
+}
+
+var digits map[string]string = map[string]string{
+	"one":   "1",
+	"1":     "1",
+	"two":   "2",
+	"2":     "2",
+	"three": "3",
+	"3":     "3",
+	"four":  "4",
+	"4":     "4",
+	"five":  "5",
+	"5":     "5",
+	"six":   "6",
+	"6":     "6",
+	"seven": "7",
+	"7":     "7",
+	"eight": "8",
+	"8":     "8",
+	"nine":  "9",
+	"9":     "9",
+}
+
+type digitIndex struct {
+	digit string
+	index int
+}
+
+func solvePart2(input []string) (solution int) {
+	sum := 0
+	for _, line := range input {
+		first := digitIndex{digit: "", index: 5000}
+		last := digitIndex{digit: "", index: -1}
+		for k := range digits {
+			f := strings.Index(line, k)
+			if f != -1 && f < first.index {
+				first = digitIndex{digit: k, index: f}
+			}
+			l := strings.LastIndex(line, k)
+			if l != -1 && l > last.index {
+				last = digitIndex{digit: k, index: l}
+			}
+		}
+		joinedDigits := strings.Join([]string{digits[first.digit], digits[last.digit]}, "")
+		value, _ := strconv.Atoi(joinedDigits)
+		sum = sum + value
+	}
+	return sum
+}
+
+func main() {
+	day := 1
+	aoc.SolveExample(day, aoc.Part1, solvePart1, 142)
+	aoc.SolvePuzzle(day, aoc.Part1, solvePart1, 56397)
+	aoc.SolveExample(day, aoc.Part2, solvePart2, 281)
+	aoc.SolvePuzzle(day, aoc.Part2, solvePart2, 55701)
+}
2023/go/02/main.go
@@ -0,0 +1,135 @@
+package main
+
+import (
+	"advent2023/internal/aoc"
+	"strconv"
+	"strings"
+)
+
+type instance struct {
+	blue  int
+	red   int
+	green int
+}
+
+type game struct {
+	id        int
+	instances []instance
+}
+
+const (
+	blue  = "blue"
+	green = "green"
+	red   = "red"
+)
+
+func (i instance) valid(maxCubes instance) bool {
+	if i.blue > maxCubes.blue {
+		return false
+	}
+	if i.green > maxCubes.green {
+		return false
+	}
+	if i.red > maxCubes.red {
+		return false
+	}
+	return true
+}
+
+func (i instance) power() int {
+	return i.green * i.red * i.blue
+}
+
+func parseInstances(input string) (instances []instance) {
+
+	instances = []instance{}
+
+	instanceString := strings.Split(input, ";")
+	for _, iString := range instanceString {
+
+		i := instance{}
+		cubes := strings.Split(iString, ",")
+		for _, c := range cubes {
+
+			c = strings.Trim(c, " ")
+			countSplit := strings.Split(c, " ")
+			if countSplit[1] == blue {
+				i.blue, _ = strconv.Atoi(countSplit[0])
+			}
+			if countSplit[1] == red {
+				i.red, _ = strconv.Atoi(countSplit[0])
+			}
+			if countSplit[1] == green {
+				i.green, _ = strconv.Atoi(countSplit[0])
+			}
+		}
+		instances = append(instances, i)
+	}
+	return instances
+}
+
+func parseGame(input string) game {
+	s := strings.TrimPrefix(input, "Game ")
+	split := strings.Split(s, ":")
+	id, _ := strconv.Atoi(split[0])
+	instancesString := split[1]
+	return game{
+		id:        id,
+		instances: parseInstances(instancesString),
+	}
+}
+
+func solvePart1(input []string) (solution int) {
+	sum := 0
+	for _, line := range input {
+		maxCubes := instance{
+			blue:  14,
+			red:   12,
+			green: 13,
+		}
+		g := parseGame(line)
+		valid := true
+		for _, i := range g.instances {
+			if !i.valid(maxCubes) {
+				valid = false
+			}
+		}
+		if valid {
+			sum = sum + g.id
+		}
+	}
+	return sum
+}
+
+func solvePart2(input []string) (solution int) {
+	sum := 0
+	for _, line := range input {
+		minCubes := instance{
+			blue:  0,
+			red:   0,
+			green: 0,
+		}
+		g := parseGame(line)
+		for _, i := range g.instances {
+			if i.blue > minCubes.blue {
+				minCubes.blue = i.blue
+			}
+			if i.red > minCubes.red {
+				minCubes.red = i.red
+			}
+			if i.green > minCubes.green {
+				minCubes.green = i.green
+			}
+		}
+		sum = sum + minCubes.power()
+	}
+	return sum
+}
+
+func main() {
+	day := 2
+	aoc.SolveExample(day, aoc.Part1, solvePart1, 8)
+	aoc.SolvePuzzle(day, aoc.Part1, solvePart1, 2447)
+	aoc.SolveExample(day, aoc.Part2, solvePart2, 2286)
+	aoc.SolvePuzzle(day, aoc.Part2, solvePart2, 56322)
+}
2023/go/internal/aoc/aoc.go
@@ -0,0 +1,89 @@
+package aoc
+
+import (
+	"bufio"
+	"fmt"
+	"log"
+	"os"
+)
+
+const (
+	example         = "e"
+	puzzle          = "p"
+	Part1           = 1
+	Part2           = 2
+	UnknownExpected = -1
+)
+
+type InputType string
+
+type solve func([]string) int
+
+type Input struct {
+	Day      int
+	Part     int
+	Type     InputType
+	Solve    solve
+	Expected int
+}
+
+func (i Input) Calculate() (err error) {
+
+	inputFilename := fmt.Sprintf("../input/%02d-%s%d.txt", i.Day, i.Type, i.Part)
+	input := []string{}
+	file, err := os.Open(inputFilename)
+	if err != nil {
+		return fmt.Errorf("failed to open %s: %w", inputFilename, err)
+	}
+	defer file.Close()
+
+	scanner := bufio.NewScanner(file)
+	for scanner.Scan() {
+		input = append(input, scanner.Text())
+	}
+	if err := scanner.Err(); err != nil {
+		return fmt.Errorf("failed to scan by lines: %w", err)
+	}
+
+	solution := i.Solve(input)
+	if i.Expected == UnknownExpected {
+		fmt.Printf("%-6d\n", solution)
+		return nil
+	}
+	if solution != i.Expected {
+		fmt.Printf("%-6d โŒ\n", solution)
+		return nil
+	}
+	fmt.Printf("%-6d โœ…\n", solution)
+	return nil
+}
+
+func SolveExample(day int, part int, fn solve, expected int) {
+	fmt.Printf("Day %02d, Part %d Example: ", day, part)
+	i := Input{
+		Day:      day,
+		Part:     part,
+		Type:     example,
+		Solve:    fn,
+		Expected: expected,
+	}
+	err := i.Calculate()
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func SolvePuzzle(day int, part int, fn solve, expected int) {
+	fmt.Printf("Day %02d, Part %d Puzzle:  ", day, part)
+	i := Input{
+		Day:      day,
+		Part:     part,
+		Type:     puzzle,
+		Solve:    fn,
+		Expected: expected,
+	}
+	err := i.Calculate()
+	if err != nil {
+		log.Fatal(err)
+	}
+}
2023/go/template/main.go
@@ -0,0 +1,21 @@
+package main
+
+import (
+	"advent2023/internal/aoc"
+)
+
+func solvePart1(input []string) (solution int) {
+	return 0
+}
+
+func solvePart2(input []string) (solution int) {
+	return 0
+}
+
+func main() {
+	day := 3
+	aoc.SolveExample(day, aoc.Part1, solvePart1, 0)
+	aoc.SolvePuzzle(day, aoc.Part1, solvePart1, aoc.UnknownExpected)
+	aoc.SolveExample(day, aoc.Part2, solvePart2, 0)
+	aoc.SolvePuzzle(day, aoc.Part2, solvePart2, aoc.UnknownExpected)
+}
2023/go/.gitignore
@@ -0,0 +1,1 @@
+bin/*
2023/go/01.go
@@ -1,161 +0,0 @@
-package main
-
-import (
-	"bufio"
-	"fmt"
-	"log"
-	"os"
-	"strconv"
-	"strings"
-)
-
-const (
-	example = "e"
-	puzzle  = "p"
-)
-
-type InputType string
-
-func Input(day int, part int, inputType InputType) (input []string, err error) {
-
-	inputFilename := fmt.Sprintf("../input/%02d-%s%di.txt", day, inputType, part)
-	file, err := os.Open(inputFilename)
-	if err != nil {
-		return input, fmt.Errorf("failed to open %s: %w", inputFilename, err)
-	}
-	defer file.Close()
-
-	scanner := bufio.NewScanner(file)
-	for scanner.Scan() {
-		input = append(input, scanner.Text())
-	}
-	if err := scanner.Err(); err != nil {
-		return input, fmt.Errorf("failed to scan by lines: %w", err)
-	}
-	return input, nil
-
-}
-
-func InputExample(day int, part int) (input []string, err error) {
-	return Input(day, part, example)
-}
-
-func InputPuzzle(day int, part int) (input []string, err error) {
-	return Input(day, part, puzzle)
-}
-
-func part1(input []string) (solution int) {
-	sum := 0
-	for _, line := range input {
-		first := ""
-		last := ""
-		for _, c := range line {
-			if _, err := strconv.Atoi(string(c)); err == nil {
-				if first == "" {
-					first = string(c)
-				}
-				last = string(c)
-			}
-		}
-		value, err := strconv.Atoi(strings.Join([]string{first, last}, ""))
-		if err != nil {
-			log.Fatal(err)
-		}
-		sum = sum + value
-	}
-	return sum
-}
-
-func unSpellOut(s string) int {
-	type digitIndex struct {
-		digit string
-		index int
-	}
-	firstIndex := map[string]int{}
-	lastIndex := map[string]int{}
-	digits := map[string]string{
-		"one":   "1",
-		"1":     "1",
-		"two":   "2",
-		"2":     "2",
-		"three": "3",
-		"3":     "3",
-		"four":  "4",
-		"4":     "4",
-		"five":  "5",
-		"5":     "5",
-		"six":   "6",
-		"6":     "6",
-		"seven": "7",
-		"7":     "7",
-		"eight": "8",
-		"8":     "8",
-		"nine":  "9",
-		"9":  "9",
-	}
-
-	for k := range digits {
-		f := strings.Index(s, k)
-		if f != -1 {
-			firstIndex[k] = f
-		}
-		l := strings.LastIndex(s, k)
-		if l != -1 {
-			lastIndex[k] = l
-		}
-	}
-	first := digitIndex{digit: "", index: 5000}
-	last := digitIndex{digit: "", index: -1}
-	for k, v := range firstIndex {
-		if v < first.index {
-			first = digitIndex{digit: k, index: v}
-		}
-	}
-	for k, v := range lastIndex {
-		if v > last.index {
-			last = digitIndex{digit: k, index: v}
-		}
-	}
-	if first.index == last.index {
-		value, _ := strconv.Atoi(digits[first.digit])
-		fmt.Printf("%40s %v %v %d\n", s, first, last, value)
-		return value
-	}
-	value, _ := strconv.Atoi(strings.Join([]string{digits[first.digit], digits[last.digit]}, ""))
-	fmt.Printf("%40s %v %v %d\n", s, first, last, value)
-	return value
-}
-
-// 1tbbsmdhtwonedtt
-func part2(input []string) (solution int) {
-	sum := 0
-	for _, line := range input {
-		value := unSpellOut(line)
-		sum = sum + value
-	}
-	return sum
-}
-
-func main() {
-	e1, err := InputExample(1, 1)
-	if err != nil {
-		log.Fatal(err)
-	}
-	p1, err := InputPuzzle(1, 1)
-	if err != nil {
-		log.Fatal(err)
-	}
-	e2, err := InputExample(1, 2)
-	if err != nil {
-		log.Fatal(err)
-	}
-	fmt.Println("Example 1:", part1(e1))
-	fmt.Println("Puzzle  1:", part1(p1))
-	fmt.Println("Example 2:", part2(e2))
-	p2, err := InputPuzzle(1, 2)
-	if err != nil {
-		log.Fatal(err)
-	}
-	fmt.Println("Puzzle  2:", part2(p2))
-
-}
2023/go/Justfile
@@ -0,0 +1,14 @@
+default: run
+
+build: 
+	go build -o bin/01 01/main.go
+	go build -o bin/02 02/main.go
+
+run: clean build
+	bin/01
+	bin/02
+
+clean: 
+	rm -f bin/*
+
+# vim: set ft=make :
2023/input/01-e1i.txt โ†’ 2023/input/01-e1.txt
File renamed without changes
2023/input/01-e2i.txt โ†’ 2023/input/01-e2.txt
File renamed without changes
2023/input/01-p1i.txt โ†’ 2023/input/01-p1.txt
File renamed without changes
2023/input/01-p2.txt
@@ -0,0 +1,1 @@
+01-p1.txt
\ No newline at end of file
2023/input/01-p2i.txt
@@ -1,1 +0,0 @@
-01-p1i.txt
\ No newline at end of file
2023/input/02-e1.txt
@@ -0,0 +1,5 @@
+Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
+Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
+Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
+Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
+Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green
2023/input/02-e2.txt
@@ -0,0 +1,1 @@
+02-e1.txt
\ No newline at end of file
2023/input/02-p1.txt
@@ -0,0 +1,100 @@
+Game 1: 7 green, 4 blue, 3 red; 4 blue, 10 red, 1 green; 1 blue, 9 red
+Game 2: 2 red, 4 blue, 3 green; 5 green, 3 red, 1 blue; 3 green, 5 blue, 3 red
+Game 3: 12 red, 1 blue; 6 red, 2 green, 3 blue; 2 blue, 5 red, 3 green
+Game 4: 3 green, 1 red, 3 blue; 1 red; 2 green, 1 red, 1 blue; 3 green, 1 blue; 2 blue; 2 green, 4 blue
+Game 5: 3 blue, 3 red, 8 green; 5 blue, 1 red; 1 green, 19 blue, 3 red; 1 red, 5 green, 3 blue; 4 green, 20 blue, 4 red; 20 blue, 4 green
+Game 6: 7 green, 6 blue, 1 red; 3 blue, 5 green, 3 red; 9 blue, 3 red, 6 green; 8 blue, 11 green, 3 red; 2 blue, 1 red; 7 green, 4 blue, 1 red
+Game 7: 5 green, 1 blue; 2 green, 2 blue; 1 blue, 1 red; 5 blue, 2 green; 3 green
+Game 8: 5 blue, 5 red, 10 green; 6 green, 1 blue, 1 red; 5 red, 2 blue, 16 green; 2 blue, 14 green, 9 red; 9 red, 3 green, 7 blue; 8 red, 4 blue, 10 green
+Game 9: 1 red, 1 blue, 7 green; 4 red, 6 green, 2 blue; 6 green, 14 blue, 3 red
+Game 10: 1 red, 16 green, 3 blue; 1 red, 3 blue; 6 green; 4 green, 2 blue, 1 red
+Game 11: 5 red, 2 blue; 14 blue, 8 red, 10 green; 8 green, 1 red, 15 blue; 2 green, 5 red, 11 blue; 8 red, 11 blue, 4 green
+Game 12: 5 green, 8 blue, 4 red; 15 green, 8 blue, 8 red; 13 red, 1 blue; 6 blue, 7 green, 14 red; 9 red
+Game 13: 7 blue, 5 red; 3 green, 10 blue; 5 blue, 2 green, 5 red; 3 blue, 1 green, 5 red; 6 blue, 4 red, 6 green; 5 red, 2 green, 6 blue
+Game 14: 5 red, 1 blue, 5 green; 6 blue, 13 green, 4 red; 7 blue, 4 red, 1 green; 6 blue, 5 red; 2 red, 7 blue, 2 green
+Game 15: 8 red, 16 green; 10 green, 1 blue; 16 green, 7 blue, 3 red; 13 red, 7 blue, 8 green; 4 red, 2 green, 8 blue
+Game 16: 1 red, 1 blue, 5 green; 5 green, 2 red; 2 green, 1 red; 3 red, 4 green
+Game 17: 3 green, 7 blue, 5 red; 2 red, 1 blue; 8 blue, 1 red
+Game 18: 9 green, 6 blue, 3 red; 3 red, 15 green, 5 blue; 7 green, 3 red, 3 blue
+Game 19: 4 green, 3 red, 7 blue; 4 blue, 6 red, 4 green; 6 red, 5 green, 1 blue; 6 blue, 4 green, 3 red; 5 green, 5 red, 2 blue
+Game 20: 3 green, 5 blue, 1 red; 1 red, 1 blue; 1 red, 6 blue; 1 green, 4 blue
+Game 21: 2 green, 1 blue, 3 red; 16 green, 1 blue, 4 red; 11 green, 2 red, 1 blue; 6 green, 1 blue; 10 green, 1 red, 1 blue
+Game 22: 1 blue, 2 green, 4 red; 3 red, 4 green; 1 blue, 3 red, 10 green; 7 green, 1 blue
+Game 23: 2 red, 14 blue; 2 red, 14 blue; 1 red, 14 blue, 1 green; 1 red, 6 blue; 13 blue, 1 green
+Game 24: 3 green, 7 blue, 3 red; 4 green, 2 blue; 12 blue, 8 red, 4 green; 10 blue, 9 red, 1 green; 13 blue, 4 red; 12 blue, 9 red, 2 green
+Game 25: 9 green, 11 red; 14 green, 3 red, 1 blue; 8 red, 7 green; 10 red, 8 green, 1 blue; 6 red, 11 green, 1 blue
+Game 26: 10 blue, 6 red, 11 green; 9 red, 2 green, 10 blue; 5 red; 9 red, 8 blue, 7 green; 13 green, 10 red, 1 blue
+Game 27: 3 blue, 1 green; 10 green, 1 blue; 8 red, 6 green, 6 blue
+Game 28: 10 blue, 2 red, 13 green; 2 blue, 2 red, 6 green; 10 blue; 4 red, 4 blue, 11 green; 3 green, 2 red, 6 blue; 14 green, 2 red, 2 blue
+Game 29: 8 blue, 5 red, 6 green; 1 green, 4 blue, 15 red; 8 blue, 14 red, 3 green; 9 blue, 4 red, 5 green; 3 red, 3 green, 4 blue
+Game 30: 19 green, 14 blue, 2 red; 2 red, 8 green, 7 blue; 4 blue, 1 red, 13 green; 10 blue, 3 green; 8 blue, 2 red
+Game 31: 12 green, 5 blue, 3 red; 15 blue, 11 green, 6 red; 6 green, 6 red; 4 green, 6 blue, 10 red
+Game 32: 7 red, 2 green, 3 blue; 9 red, 1 green; 2 green, 5 red, 1 blue; 12 red; 14 red, 4 blue
+Game 33: 9 red, 4 green, 6 blue; 4 red, 10 green; 16 red, 4 green, 4 blue; 15 blue, 12 red
+Game 34: 5 green, 1 blue; 18 red, 1 green, 1 blue; 1 blue, 9 green, 3 red; 6 green, 11 red
+Game 35: 2 blue, 19 green, 6 red; 16 green, 1 red, 1 blue; 1 green, 2 blue, 5 red; 8 green, 3 blue, 13 red; 11 red, 10 green, 4 blue
+Game 36: 17 green, 6 blue; 10 blue, 2 red, 8 green; 16 green, 4 blue, 1 red
+Game 37: 9 green, 7 red, 8 blue; 1 blue, 10 red; 10 red, 4 blue, 11 green; 8 green, 11 red, 5 blue
+Game 38: 8 green, 11 blue; 13 green, 2 blue; 7 blue, 2 red, 8 green
+Game 39: 14 red, 2 green; 2 red, 3 green, 1 blue; 4 red, 5 green, 4 blue; 2 blue, 3 red, 1 green; 17 red, 2 blue; 5 green, 3 red
+Game 40: 10 blue; 2 red, 9 blue; 5 red, 1 green, 2 blue; 8 blue, 2 red; 6 blue, 2 red; 4 red, 2 blue, 1 green
+Game 41: 2 blue, 3 red, 2 green; 4 green, 2 red, 11 blue; 11 blue, 3 red, 1 green; 1 red, 6 green, 1 blue; 5 red, 7 green
+Game 42: 1 blue, 14 green, 1 red; 2 blue, 2 green; 5 green, 2 blue, 8 red
+Game 43: 15 red, 5 blue, 5 green; 15 green, 15 red, 1 blue; 4 blue, 13 green, 13 red; 3 red, 16 green; 2 red, 3 green, 2 blue
+Game 44: 8 green, 8 blue; 9 blue, 9 green; 9 green, 3 blue; 8 green, 3 blue; 8 blue, 2 green; 9 blue, 1 red, 8 green
+Game 45: 4 red, 4 blue, 4 green; 5 red, 2 green, 9 blue; 8 blue, 5 red, 3 green; 4 red, 3 blue; 5 red, 5 green, 1 blue
+Game 46: 1 blue, 9 green, 2 red; 2 blue, 9 green, 1 red; 8 green, 3 red
+Game 47: 2 green, 4 blue, 10 red; 4 green, 5 blue, 1 red; 10 green, 13 red, 6 blue; 4 green, 4 blue, 12 red; 15 red, 1 blue, 4 green
+Game 48: 1 red, 7 green; 2 blue, 4 green, 5 red; 5 red, 3 green, 1 blue; 8 green
+Game 49: 3 blue, 4 green, 3 red; 6 red, 5 green, 5 blue; 1 blue, 4 green, 3 red; 6 red, 1 blue, 5 green; 4 red, 3 green, 5 blue; 2 green, 3 blue, 1 red
+Game 50: 1 green, 5 red, 6 blue; 3 red, 2 green; 1 red, 1 green, 6 blue; 1 green, 7 red, 3 blue
+Game 51: 7 green, 8 blue; 6 blue, 6 red, 4 green; 6 green, 1 blue; 8 blue, 5 red, 4 green
+Game 52: 7 red, 3 blue, 6 green; 7 green, 5 red, 4 blue; 6 red, 4 blue
+Game 53: 12 blue, 1 red, 5 green; 4 green, 2 blue, 5 red; 5 red, 4 green; 1 green, 3 blue, 5 red; 5 blue, 2 red, 5 green
+Game 54: 15 green, 12 red; 11 red, 3 green, 2 blue; 3 blue, 6 green; 3 red, 1 blue, 5 green; 17 red, 7 green
+Game 55: 7 green, 10 red, 7 blue; 8 red, 4 blue, 11 green; 9 green, 11 red
+Game 56: 7 green, 3 blue, 5 red; 6 green, 1 red, 4 blue; 4 green, 2 red; 5 blue, 6 red, 8 green
+Game 57: 1 green, 3 red, 3 blue; 5 blue, 2 red, 2 green; 1 green, 5 blue
+Game 58: 4 red, 2 green; 13 green, 4 red, 1 blue; 12 green, 4 blue
+Game 59: 4 red, 4 green; 5 blue, 1 green, 20 red; 11 red, 3 green, 15 blue; 5 blue, 7 red, 3 green; 18 blue, 4 green, 19 red
+Game 60: 5 blue, 8 red, 4 green; 4 blue, 12 green, 19 red; 3 blue, 1 green, 17 red; 1 green, 3 blue; 2 green, 6 blue, 3 red
+Game 61: 3 red, 7 blue, 12 green; 7 red, 1 green, 6 blue; 6 red, 2 green, 18 blue; 14 blue, 5 red, 1 green
+Game 62: 1 red, 2 blue; 1 green, 3 red; 1 green, 9 blue, 4 red
+Game 63: 6 green, 4 blue, 17 red; 2 green, 2 blue, 12 red; 10 green, 9 blue, 13 red; 15 red, 8 green, 5 blue
+Game 64: 4 green, 7 blue, 10 red; 3 green, 4 blue, 12 red; 6 green, 6 red, 8 blue; 4 green, 9 red, 1 blue; 2 blue, 15 red, 15 green
+Game 65: 5 green, 4 blue, 7 red; 6 green, 7 blue, 8 red; 1 green, 7 red; 1 blue, 10 red, 8 green
+Game 66: 5 green, 5 blue, 2 red; 3 red; 1 red, 1 blue, 16 green; 2 blue, 1 green; 8 green, 1 blue, 3 red; 14 green, 4 red
+Game 67: 12 blue, 7 green; 7 blue, 7 green, 1 red; 12 blue, 1 green, 6 red
+Game 68: 2 blue, 8 red, 1 green; 9 blue, 3 green, 12 red; 14 blue, 15 red, 6 green
+Game 69: 7 red, 1 blue; 11 green, 2 blue, 13 red; 3 blue, 13 green, 3 red; 1 blue, 10 red, 8 green; 15 red, 2 blue, 19 green
+Game 70: 10 green, 10 red, 12 blue; 7 red, 15 blue, 2 green; 8 blue, 9 green
+Game 71: 1 blue, 2 green, 13 red; 7 red; 1 green, 5 red
+Game 72: 2 red, 1 blue, 11 green; 1 red, 2 blue, 18 green; 5 red, 3 blue, 3 green
+Game 73: 13 red, 3 blue, 4 green; 3 green, 17 red, 1 blue; 6 blue, 4 green, 4 red; 13 red, 7 blue
+Game 74: 1 blue, 3 red; 13 blue, 5 red, 2 green; 1 red, 8 green, 11 blue; 4 blue, 1 green, 5 red; 11 blue, 8 red, 6 green; 8 red, 3 green, 4 blue
+Game 75: 7 blue, 4 green, 1 red; 3 green, 4 blue; 5 green, 2 red, 3 blue; 6 blue, 3 red, 5 green
+Game 76: 9 green, 1 blue, 4 red; 6 red, 9 green, 3 blue; 2 red, 6 green, 2 blue; 5 green; 6 green, 2 red, 3 blue; 6 blue, 5 red, 5 green
+Game 77: 2 green, 2 red; 1 blue, 6 red, 2 green; 4 green, 3 red, 2 blue; 2 blue, 1 green, 1 red
+Game 78: 2 green, 10 red, 2 blue; 6 green, 2 red, 2 blue; 2 blue, 9 red, 6 green; 11 red, 6 green; 3 red, 8 green; 1 blue, 6 green, 1 red
+Game 79: 3 blue, 8 green, 13 red; 3 blue, 2 red, 3 green; 10 red, 6 green, 4 blue; 11 red, 1 blue, 3 green
+Game 80: 3 green, 5 red, 9 blue; 3 red, 5 blue, 2 green; 5 green, 6 red, 2 blue
+Game 81: 2 green, 7 blue, 3 red; 9 blue, 3 red; 1 green, 17 blue, 2 red
+Game 82: 4 green, 8 blue, 7 red; 10 blue, 1 green, 10 red; 7 blue, 4 green, 5 red
+Game 83: 7 green, 4 blue, 3 red; 15 blue, 3 red, 14 green; 9 blue, 4 red, 7 green
+Game 84: 5 red, 5 green; 16 blue, 1 red, 7 green; 17 blue, 11 red
+Game 85: 7 red, 1 green, 11 blue; 13 blue, 5 green, 6 red; 11 blue, 2 green, 8 red; 5 blue, 17 red, 4 green; 12 blue, 2 green, 8 red
+Game 86: 3 red, 8 blue, 2 green; 15 green, 15 blue, 2 red; 18 blue, 2 red, 11 green
+Game 87: 1 blue; 6 red, 6 green; 1 blue, 9 red, 3 green
+Game 88: 10 green, 2 blue, 1 red; 7 blue, 1 green, 1 red; 9 green, 4 blue; 8 green, 1 red, 7 blue
+Game 89: 6 green, 2 red, 2 blue; 5 red, 3 blue, 3 green; 3 blue, 4 red, 1 green; 5 red, 4 green, 5 blue; 4 blue, 6 green, 3 red; 3 red, 1 green
+Game 90: 1 green, 6 blue; 1 blue, 1 red; 2 blue, 3 green; 7 green, 6 blue; 1 red, 7 green, 6 blue
+Game 91: 8 blue, 14 green, 5 red; 8 red, 6 green; 4 red, 7 blue, 14 green; 4 blue, 7 green; 9 blue, 7 red; 14 green, 7 blue, 4 red
+Game 92: 11 blue, 8 green, 6 red; 11 blue, 1 red, 11 green; 10 blue, 19 green, 5 red
+Game 93: 5 green, 1 red, 7 blue; 8 green, 14 blue, 2 red; 5 red, 14 blue, 7 green
+Game 94: 2 blue, 6 red, 3 green; 4 red, 2 green, 2 blue; 4 red, 1 blue, 1 green
+Game 95: 9 red, 15 green, 1 blue; 2 blue, 10 red, 18 green; 3 red, 10 green; 10 red, 17 green, 2 blue; 3 blue, 13 green, 1 red; 2 red, 2 blue, 6 green
+Game 96: 8 green, 1 blue; 1 blue, 1 red, 11 green; 2 green, 15 blue; 1 red, 2 green, 1 blue
+Game 97: 3 green, 3 blue; 5 green, 3 blue, 1 red; 5 green, 1 red, 3 blue; 1 green, 1 red, 2 blue; 2 green, 2 blue, 3 red
+Game 98: 6 red, 6 green, 5 blue; 19 red, 7 green; 6 green, 8 blue, 4 red; 10 green, 4 red
+Game 99: 9 red, 8 blue, 10 green; 3 blue, 7 green, 8 red; 6 red, 12 blue; 8 blue, 8 green, 2 red; 16 green, 14 blue, 5 red
+Game 100: 8 red, 13 green; 5 red, 4 green; 7 blue, 3 red, 8 green; 13 blue, 6 green; 1 blue, 8 green, 7 red; 2 red, 1 green, 16 blue
2023/input/02-p2.txt
@@ -0,0 +1,1 @@
+02-p1.txt
\ No newline at end of file
2023/input/README.md
@@ -0,0 +1,32 @@
+# Input Files
+
+Filename format:
+
+`{{ day }}-{{ type }}{{ part }}.txt`
+
+Where:
+
+ - day: `01`, `02`, `03` ... `25`
+ - type: `e` for example or `p` for puzzel input type
+ - part: `1` part 1, `2` part 2
+
+Symlinks are encouraged when content doesnt change
+
+### Examples:
+
+```
+01-e1.txt
+01-p1.txt
+01-e2.txt
+01-p2.txt
+...
+09-e1.txt
+09-p1.txt
+09-e2.txt
+09-p2.txt
+...
+25-e1.txt
+25-p1.txt
+25-e2.txt
+25-p2.txt
+```