refactor: massive refactor to have only one binary to call
This commit is contained in:
1 parent
314da54495
commit
3723f84d1a
41 files changed
+272
-188
No files matched your search
@@ -1,3 +0,0 @@
|
||||
module 2020/day01
|
||||
|
||||
go 1.25.4
|
||||
@@ -1,3 +0,0 @@
|
||||
module 2020/day02
|
||||
|
||||
go 1.25.4
|
||||
@@ -1,3 +0,0 @@
|
||||
module 2020/day03
|
||||
|
||||
go 1.25.4
|
||||
@@ -1,3 +0,0 @@
|
||||
module 2020/day04
|
||||
|
||||
go 1.25.4
|
||||
@@ -1,3 +0,0 @@
|
||||
module 2020/day05
|
||||
|
||||
go 1.25.4
|
||||
@@ -1,3 +0,0 @@
|
||||
module 2020/day06
|
||||
|
||||
go 1.25.4
|
||||
@@ -1,3 +0,0 @@
|
||||
module 2021/day01
|
||||
|
||||
go 1.25.4
|
||||
@@ -1,3 +0,0 @@
|
||||
module 2021/day02
|
||||
|
||||
go 1.25.4
|
||||
@@ -1,3 +0,0 @@
|
||||
module 2021/day03
|
||||
|
||||
go 1.25.4
|
||||
@@ -0,0 +1,13 @@
|
||||
GO = go
|
||||
BIN = bin/aoc
|
||||
|
||||
.PHONY: build test clean
|
||||
|
||||
build:
|
||||
$(GO) build -o $(BIN) ./cmd/aoc
|
||||
|
||||
test:
|
||||
$(GO) test ./...
|
||||
|
||||
clean:
|
||||
rm -f $(BIN)
|
||||
@@ -16,26 +16,61 @@ Also, it's a fresh start from 2025. I do some exercises from other years along t
|
||||
## Repository Structure
|
||||
|
||||
```
|
||||
yyyy/
|
||||
├── dayXX/
|
||||
│ ├── main.go # The main code to run to print solutions.
|
||||
│ ├── main_test.go # The test file that validates the logic.
|
||||
│ └── input.txt # The day's puzzle input.
|
||||
└── ...
|
||||
├── cmd/
|
||||
│ └── aoc/
|
||||
│ └── main.go # CLI entry point that runs solutions
|
||||
└── internal/
|
||||
├── 2020/
|
||||
│ ├── DayOne/
|
||||
│ │ ├── code.go # Go solution for Day 1 (2020)
|
||||
│ │ └── code_test.go # Unit tests for Day 1
|
||||
│ └── ...
|
||||
├── 2021/
|
||||
│ └── ... # Additional years and days
|
||||
├── registry/
|
||||
│ └── registry.go # Central registry for day runners
|
||||
└── data/
|
||||
├── 2020/
|
||||
│ ├── DayOne/
|
||||
│ │ └── input.txt # Puzzle input for Day 1 (2020)
|
||||
│ └── ...
|
||||
└── ...
|
||||
```
|
||||
|
||||
Each day's code can be run with:
|
||||
Each day's solution is organized into its own folder, named according to the day number (e.g., `DayOne`, `DayTwo`). Inside each folder, you'll find a `code.go` file with the Go implementation of the solution and a `code_test.go` file containing corresponding tests. The input data for each puzzle is located in the `internal/data` directory, mirroring the code structure for easy access.
|
||||
|
||||
To connect each solution to the CLI, the repository uses a central registry located in `internal/registry/registry.go`. This registry is essentially a map linking a day key (combining year and day number) to assign a "day runner" which is a struct that specifies the `ParseInput`, `PartOne` and `PartTwo` functions of the day's problem.
|
||||
|
||||
When running a solution, the CLI (`cmd/aoc/main.go`) looks up the appropriate runner from the registry based on your command-line input, uses the parsing function to load the input data, and then runs the desired part (or both parts) using the registered solution functions.
|
||||
|
||||
## Usage
|
||||
|
||||
Build the CLI tool:
|
||||
|
||||
```bash
|
||||
cd yyyy/dayXX
|
||||
go run main.go
|
||||
make
|
||||
```
|
||||
|
||||
Expected output:
|
||||
Run a day's solution:
|
||||
|
||||
```bash
|
||||
Part 1: <answer>
|
||||
Part 2: <answer>
|
||||
bin/aoc 2020D1 # Run both parts
|
||||
bin/aoc 2020D1P1 # Run only part one
|
||||
bin/aoc 2020D1P2 # Run only part two
|
||||
```
|
||||
|
||||
Example output:
|
||||
|
||||
```bash
|
||||
$ bin/aoc 2020D1
|
||||
197451
|
||||
138233720
|
||||
|
||||
$ bin/aoc 2020D1P1
|
||||
197451
|
||||
|
||||
$ bin/aoc 2020D1P2
|
||||
138233720
|
||||
```
|
||||
|
||||
## Tests
|
||||
@@ -55,13 +90,18 @@ In this example, the calibration values of these four lines are 12, 38, 15, and
|
||||
Adding these together produces 142.
|
||||
```
|
||||
|
||||
I'm using these examples to validate my logic.
|
||||
I'm using these examples each day to validate my logic.
|
||||
|
||||
If you want to run those, you can use:
|
||||
Run all tests:
|
||||
|
||||
```bash
|
||||
cd dayXX
|
||||
go test
|
||||
make test
|
||||
```
|
||||
|
||||
Or run tests for a specific day:
|
||||
|
||||
```bash
|
||||
go test ./internal/2020/DayOne/...
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"advent-of-code/internal/registry"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
||||
_ "advent-of-code/internal/2020/DayFour"
|
||||
_ "advent-of-code/internal/2020/DayOne"
|
||||
_ "advent-of-code/internal/2020/DaySix"
|
||||
_ "advent-of-code/internal/2020/DayThree"
|
||||
_ "advent-of-code/internal/2020/DayTwo"
|
||||
_ "advent-of-code/internal/2021/DayOne"
|
||||
_ "advent-of-code/internal/2021/DayThree"
|
||||
_ "advent-of-code/internal/2021/DayTwo"
|
||||
)
|
||||
|
||||
func capitalize(day string) string {
|
||||
dayNames := map[string]string{
|
||||
"1": "One", "2": "Two", "3": "Three", "4": "Four", "5": "Five",
|
||||
"6": "Six", "7": "Seven", "8": "Eight", "9": "Nine", "10": "Ten",
|
||||
"11": "Eleven", "12": "Twelve", "13": "Thirteen", "14": "Fourteen", "15": "Fifteen",
|
||||
"16": "Sixteen", "17": "Seventeen", "18": "Eighteen", "19": "Nineteen", "20": "Twenty",
|
||||
"21": "TwentyOne", "22": "TwentyTwo", "23": "TwentyThree", "24": "TwentyFour", "25": "TwentyFive",
|
||||
}
|
||||
return dayNames[day]
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Fprintf(os.Stderr, "Usage: %s <YEAR>D<DAY>[P<PART>]\n", os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(`^(\d{4})D(\d+)(?:P(\d+))?$`)
|
||||
matches := re.FindStringSubmatch(os.Args[1])
|
||||
if matches == nil {
|
||||
fmt.Fprintf(os.Stderr, "Invalid format: %s\n", os.Args[1])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
year, dayNum, part := matches[1], matches[2], matches[3]
|
||||
dayKey := fmt.Sprintf("%sD%s", year, dayNum)
|
||||
dayName := fmt.Sprintf("Day%s", capitalize(dayNum))
|
||||
input := filepath.Join("internal", "data", year, dayName, "input.txt")
|
||||
|
||||
runner, ok := registry.Days[dayKey].(registry.Runner)
|
||||
if !ok {
|
||||
log.Fatalf("Day not found: %s\n", dayKey)
|
||||
}
|
||||
|
||||
runner.Run(input, part)
|
||||
}
|
||||
@@ -1,18 +1,13 @@
|
||||
package main
|
||||
package dayfive
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"advent-of-code/internal/registry"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parseInput(file string) []string {
|
||||
content, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read input file: %v", err)
|
||||
}
|
||||
return strings.Split(string(content), "\n")
|
||||
func init() {
|
||||
registry.Register("2020D5", ParseInput, PartOne, PartTwo)
|
||||
}
|
||||
|
||||
func calculateSeatID(pass string) int {
|
||||
@@ -39,6 +34,11 @@ func calculateSeatID(pass string) int {
|
||||
return row*8 + column
|
||||
}
|
||||
|
||||
func ParseInput(filepath string) []string {
|
||||
content, _ := os.ReadFile(filepath)
|
||||
return strings.Split(string(content), "\n")
|
||||
}
|
||||
|
||||
func PartOne(input []string) int {
|
||||
maxSeatID := 0
|
||||
for _, pass := range input {
|
||||
@@ -77,9 +77,3 @@ func PartTwo(input []string) int {
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
input := parseInput("input.txt")
|
||||
fmt.Println("Part 1:", PartOne(input))
|
||||
fmt.Println("Part 2:", PartTwo(input))
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package dayfive
|
||||
|
||||
import "testing"
|
||||
|
||||
@@ -32,3 +32,4 @@ func TestPartTwo(t *testing.T) {
|
||||
t.Errorf("PartTwo() = %d, want %d", got, expected)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
package main
|
||||
package dayfour
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"advent-of-code/internal/registry"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parseInput(file string) []string {
|
||||
content, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read input file: %v", err)
|
||||
}
|
||||
func init() {
|
||||
registry.Register("2020D4", ParseInput, PartOne, PartTwo)
|
||||
}
|
||||
|
||||
func ParseInput(filepath string) []string {
|
||||
content, _ := os.ReadFile(filepath)
|
||||
|
||||
text := string(content)
|
||||
passports := strings.Split(text, "\n\n")
|
||||
@@ -152,8 +152,3 @@ func PartTwo(data []string) int {
|
||||
return count
|
||||
}
|
||||
|
||||
func main() {
|
||||
data := parseInput("input.txt")
|
||||
fmt.Println("Part 1:", PartOne(data))
|
||||
fmt.Println("Part 2:", PartTwo(data))
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package dayfour
|
||||
|
||||
import "testing"
|
||||
|
||||
@@ -13,7 +13,7 @@ func TestPartOne(t *testing.T) {
|
||||
expected := 2
|
||||
got := PartOne(testInput)
|
||||
if got != expected {
|
||||
t.Errorf("PartOne(%v) = %d, want %d", testInput, got, expected)
|
||||
t.Errorf("PartOne() = %d, want %d", got, expected)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ func TestPartTwo(t *testing.T) {
|
||||
expected := 2
|
||||
got := PartTwo(testInput)
|
||||
if got != expected {
|
||||
t.Errorf("PartTwo(%v) = %d, want %d", testInput, got, expected)
|
||||
t.Errorf("PartTwo() = %d, want %d", got, expected)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
package main
|
||||
package dayone
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"advent-of-code/internal/registry"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parseInput(file string) []int {
|
||||
content, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read input file: %v", err)
|
||||
}
|
||||
func init() {
|
||||
registry.Register("2020D1", ParseInput, PartOne, PartTwo)
|
||||
}
|
||||
|
||||
func ParseInput(filepath string) []int {
|
||||
content, _ := os.ReadFile(filepath)
|
||||
lines := strings.Fields(string(content))
|
||||
var data []int
|
||||
for _, line := range lines {
|
||||
num, err := strconv.Atoi(line)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to convert string to int: %v", err)
|
||||
}
|
||||
num, _ := strconv.Atoi(line)
|
||||
data = append(data, num)
|
||||
}
|
||||
return data
|
||||
@@ -51,8 +48,3 @@ func PartTwo(data []int) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
data := parseInput("input.txt")
|
||||
fmt.Println("Part 1:", PartOne(data))
|
||||
fmt.Println("Part 2:", PartTwo(data))
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package dayone
|
||||
|
||||
import "testing"
|
||||
|
||||
@@ -8,7 +8,7 @@ func TestPartOne(t *testing.T) {
|
||||
expected := 514579
|
||||
got := PartOne(testInput)
|
||||
if got != expected {
|
||||
t.Errorf("PartOne(%v) = %d, want %d", testInput, got, expected)
|
||||
t.Errorf("PartOne() = %d, want %d", got, expected)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ func TestPartTwo(t *testing.T) {
|
||||
expected := 241861950
|
||||
got := PartTwo(testInput)
|
||||
if got != expected {
|
||||
t.Errorf("PartTwo(%v) = %d, want %d", testInput, got, expected)
|
||||
t.Errorf("PartTwo() = %d, want %d", got, expected)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package main
|
||||
package daysix
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"advent-of-code/internal/registry"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parseInput(file string) []string {
|
||||
content, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read input file: %v", err)
|
||||
}
|
||||
func init() {
|
||||
registry.Register("2020D6", ParseInput, PartOne, PartTwo)
|
||||
}
|
||||
|
||||
func ParseInput(filepath string) []string {
|
||||
content, _ := os.ReadFile(filepath)
|
||||
return strings.Split(strings.TrimSpace(string(content)), "\n")
|
||||
}
|
||||
|
||||
@@ -68,8 +68,3 @@ func PartTwo(input []string) int {
|
||||
return total
|
||||
}
|
||||
|
||||
func main() {
|
||||
input := parseInput("input.txt")
|
||||
fmt.Println("Part 1:", PartOne(input))
|
||||
fmt.Println("Part 2:", PartTwo(input))
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package main
|
||||
package daysix
|
||||
|
||||
import "testing"
|
||||
|
||||
var input = []string{
|
||||
var testInput = []string{
|
||||
"abc",
|
||||
"",
|
||||
"a",
|
||||
@@ -22,7 +22,7 @@ var input = []string{
|
||||
|
||||
func TestPartOne(t *testing.T) {
|
||||
expected := 11
|
||||
got := PartOne(input)
|
||||
got := PartOne(testInput)
|
||||
if got != expected {
|
||||
t.Errorf("PartOne() = %d, want %d", got, expected)
|
||||
}
|
||||
@@ -30,8 +30,9 @@ func TestPartOne(t *testing.T) {
|
||||
|
||||
func TestPartTwo(t *testing.T) {
|
||||
expected := 6
|
||||
got := PartTwo(input)
|
||||
got := PartTwo(testInput)
|
||||
if got != expected {
|
||||
t.Errorf("PartTwo() = %d, want %d", got, expected)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package main
|
||||
package daythree
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"advent-of-code/internal/registry"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parseInput(file string) []string {
|
||||
content, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read input file: %v", err)
|
||||
}
|
||||
func init() {
|
||||
registry.Register("2020D3", ParseInput, PartOne, PartTwo)
|
||||
}
|
||||
|
||||
func ParseInput(filepath string) []string {
|
||||
content, _ := os.ReadFile(filepath)
|
||||
return strings.Split(string(content), "\n")
|
||||
}
|
||||
|
||||
@@ -50,8 +50,3 @@ func PartTwo(input []string) int {
|
||||
return result
|
||||
}
|
||||
|
||||
func main() {
|
||||
data := parseInput("input.txt")
|
||||
fmt.Println("Part 1:", PartOne(data))
|
||||
fmt.Println("Part 2:", PartTwo(data))
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package daythree
|
||||
|
||||
import "testing"
|
||||
|
||||
@@ -31,3 +31,4 @@ func TestPartTwo(t *testing.T) {
|
||||
t.Errorf("PartTwo() = %d, want %d", got, expected)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
package main
|
||||
package daytwo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"advent-of-code/internal/registry"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parseInput(file string) []string {
|
||||
content, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read input file: %v", err)
|
||||
}
|
||||
func init() {
|
||||
registry.Register("2020D2", ParseInput, PartOne, PartTwo)
|
||||
}
|
||||
|
||||
func ParseInput(filepath string) []string {
|
||||
content, _ := os.ReadFile(filepath)
|
||||
lines := strings.Split(string(content), "\n")
|
||||
var data []string
|
||||
for _, line := range lines {
|
||||
@@ -75,8 +75,3 @@ func PartTwo(data []string) int {
|
||||
return valid
|
||||
}
|
||||
|
||||
func main() {
|
||||
data := parseInput("input.txt")
|
||||
fmt.Println("Part 1:", PartOne(data))
|
||||
fmt.Println("Part 2:", PartTwo(data))
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package daytwo
|
||||
|
||||
import "testing"
|
||||
|
||||
@@ -12,7 +12,7 @@ func TestPartOne(t *testing.T) {
|
||||
expected := 2
|
||||
got := PartOne(testInput)
|
||||
if got != expected {
|
||||
t.Errorf("PartOne(%v) = %d, want %d", testInput, got, expected)
|
||||
t.Errorf("PartOne() = %d, want %d", got, expected)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ func TestPartTwo(t *testing.T) {
|
||||
expected := 1
|
||||
got := PartTwo(testInput)
|
||||
if got != expected {
|
||||
t.Errorf("PartTwo(%v) = %d, want %d", testInput, got, expected)
|
||||
t.Errorf("PartTwo() = %d, want %d", got, expected)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,21 @@
|
||||
package main
|
||||
package dayone
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"advent-of-code/internal/registry"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parseInput(file string) []int {
|
||||
content, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read input file: %v", err)
|
||||
}
|
||||
func init() {
|
||||
registry.Register("2021D1", ParseInput, PartOne, PartTwo)
|
||||
}
|
||||
|
||||
func ParseInput(filepath string) []int {
|
||||
content, _ := os.ReadFile(filepath)
|
||||
var data []int
|
||||
for line := range strings.SplitSeq(string(content), "\n") {
|
||||
num, err := strconv.Atoi(line)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to convert string to int: %v", err)
|
||||
}
|
||||
num, _ := strconv.Atoi(line)
|
||||
data = append(data, num)
|
||||
}
|
||||
return data
|
||||
@@ -44,8 +41,3 @@ func PartTwo(data []int) int {
|
||||
return count
|
||||
}
|
||||
|
||||
func main() {
|
||||
data := parseInput("input.txt")
|
||||
fmt.Println("Part 1:", PartOne(data))
|
||||
fmt.Println("Part 2:", PartTwo(data))
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package dayone
|
||||
|
||||
import "testing"
|
||||
|
||||
@@ -19,3 +19,4 @@ func TestPartTwo(t *testing.T) {
|
||||
t.Errorf("PartTwo() = %d, want %d", got, expected)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package main
|
||||
package daythree
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"advent-of-code/internal/registry"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parseInput(file string) []string {
|
||||
content, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read input file: %v", err)
|
||||
}
|
||||
func init() {
|
||||
registry.Register("2021D3", ParseInput, PartOne, PartTwo)
|
||||
}
|
||||
|
||||
func ParseInput(filepath string) []string {
|
||||
content, _ := os.ReadFile(filepath)
|
||||
return strings.Split(strings.TrimSpace(string(content)), "\n")
|
||||
}
|
||||
|
||||
@@ -115,8 +115,3 @@ func PartTwo(data []string) int {
|
||||
return oxygenRating * co2Rating
|
||||
}
|
||||
|
||||
func main() {
|
||||
data := parseInput("input.txt")
|
||||
fmt.Println("Part 1:", PartOne(data))
|
||||
fmt.Println("Part 2:", PartTwo(data))
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package daythree
|
||||
|
||||
import "testing"
|
||||
|
||||
@@ -32,3 +32,4 @@ func TestPartTwo(t *testing.T) {
|
||||
t.Errorf("PartTwo() = %d, want %d", got, expected)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
package main
|
||||
package daytwo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"advent-of-code/internal/registry"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parseInput(file string) []string {
|
||||
content, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read input file: %v", err)
|
||||
}
|
||||
func init() {
|
||||
registry.Register("2021D2", ParseInput, PartOne, PartTwo)
|
||||
}
|
||||
|
||||
func ParseInput(filepath string) []string {
|
||||
content, _ := os.ReadFile(filepath)
|
||||
return strings.Split(string(content), "\n")
|
||||
}
|
||||
|
||||
@@ -58,8 +58,3 @@ func PartTwo(data []string) int {
|
||||
return horizontal * depth
|
||||
}
|
||||
|
||||
func main() {
|
||||
data := parseInput("input.txt")
|
||||
fmt.Println("Part 1:", PartOne(data))
|
||||
fmt.Println("Part 2:", PartTwo(data))
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package daytwo
|
||||
|
||||
import "testing"
|
||||
|
||||
@@ -26,3 +26,4 @@ func TestPartTwo(t *testing.T) {
|
||||
t.Errorf("PartTwo() = %d, want %d", got, expected)
|
||||
}
|
||||
}
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,42 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Runner interface {
|
||||
Run(input string, part string)
|
||||
}
|
||||
|
||||
type DayRunner[T any] struct {
|
||||
ParseInput func(string) T
|
||||
PartOne func(T) int
|
||||
PartTwo func(T) int
|
||||
}
|
||||
|
||||
func (r *DayRunner[T]) Run(input string, part string) {
|
||||
data := r.ParseInput(input)
|
||||
switch part {
|
||||
case "":
|
||||
fmt.Println(r.PartOne(data))
|
||||
fmt.Println(r.PartTwo(data))
|
||||
case "1":
|
||||
fmt.Println(r.PartOne(data))
|
||||
case "2":
|
||||
fmt.Println(r.PartTwo(data))
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "Invalid part: %s\n", part)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
var Days = make(map[string]any)
|
||||
|
||||
func Register[T any](key string, parseInput func(string) T, partOne func(T) int, partTwo func(T) int) {
|
||||
Days[key] = &DayRunner[T]{
|
||||
ParseInput: parseInput,
|
||||
PartOne: partOne,
|
||||
PartTwo: partTwo,
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user