Commit bf5e909
Changed files (17)
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
+```