diff --git a/README.md b/README.md index fb536d5..e0b384a 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,12 @@ In this repository, you'll find my Advent of Code framework and solutions. If you want to use this framework for your own solution, just remove all data in the `./data` folder. -## 🛠 Setup and running +It provides both a PHP and a Go framework. The PHP framework is the most complete one while +the Go framework is still a work in progress and is meant to learn Go. + +## PHP + +### 🛠 Setup and running - Run `composer install` to install the dependencies. - Run `./aoc day {day} {year?}` to run the solution for a specific day. If year is not given, use the current year (for example `./aoc day 1` to run the code for day 1 2023) - Run `./aoc test {day} {year?}` to run the solution against the specified results. @@ -15,12 +20,12 @@ use this framework for your own solution, just remove all data in the `./data` f > - You can add `--one` or `--two` (or `-1` and `-2`) to the day to run the solution for part 1 or part 2. > - You can add `--skip-example` (or `-s`) to skip the example data. -## 🧪 Testing and quality control +### 🧪 Testing and quality control - Run `./vendor/bin/pest` to automatically validate the solutions. - Run `./vendor/bin/phpstan analyse` to run static analysis on the code. - Run `./vendor/bin/php-cs-fixer fix` to run (and fix) code style checks. -## 🧩 Add a new puzzle/solution +### 🧩 Add a new puzzle/solution - Run `./aoc new {day?} {year?}` to create a new puzzle/solution.
diff --git a/aoc.go b/aoc.go new file mode 100644 index 0000000..1b0f82c --- /dev/null +++ b/aoc.go @@ -0,0 +1,21 @@ +package main + +import ( + y22 "adventofcode/data/Y22" + "adventofcode/src-go/helpers" + "fmt" + "github.com/fatih/color" +) + +func main() { + runY22() + day, year := helpers.GetDayYear() + + fmt.Println(day, year) +} + +func runY22() { + color.HiYellow("\n--- Advent of Code 2022 ---\n\n") + helpers.PrintDayResults(y22.Day1()) + helpers.PrintDayResults(y22.Day2()) +} diff --git a/data/Y22/day1/day1.go b/data/Y22/day1/day1.go new file mode 100644 index 0000000..fde0e96 --- /dev/null +++ b/data/Y22/day1/day1.go @@ -0,0 +1,56 @@ +package Y22 + +import ( + "adventofcode/src-go/helpers" + "sort" + "strconv" +) + +func Day1() helpers.DayResults { + day1Example := helpers.ReadFileByLine("data/Y22/day1/example.txt") + day1 := helpers.ReadFileByLine("data/Y22/day1/data.txt") + + calorieCount := calculateCalories(day1Example) + part1Example := calorieCount[len(calorieCount)-1] + part2Example := calorieCount[len(calorieCount)-1] + calorieCount[len(calorieCount)-2] + calorieCount[len(calorieCount)-3] + + calorieCount = calculateCalories(day1) + part1Result := calorieCount[len(calorieCount)-1] + part2Result := calorieCount[len(calorieCount)-1] + calorieCount[len(calorieCount)-2] + calorieCount[len(calorieCount)-3] + + results := helpers.DayResults{ + Day: 1, + Year: 2022, + Part1Example: part1Example, + Part1: part1Result, + Part2Example: part2Example, + Part2: part2Result, + } + + return results +} + +func calculateCalories(data []string) []int { + var calorieCount []int + total := 0 + for _, line := range data { + if line == "" { + calorieCount = append(calorieCount, total) + total = 0 + continue + } + + val, err := strconv.Atoi(line) + if err != nil { + panic(err) + } + + total += val + } + + sort.Slice(calorieCount, func(i, j int) bool { + return calorieCount[i] < calorieCount[j] + }) + + return calorieCount +} diff --git a/data/Y22/day2/day2.go b/data/Y22/day2/day2.go new file mode 100644 index 0000000..18bfc1a --- /dev/null +++ b/data/Y22/day2/day2.go @@ -0,0 +1,93 @@ +package Y22 + +import ( + "adventofcode/src-go/helpers" + "strings" +) + +const ( + aRock string = "A" + aPaper string = "B" + aScissors string = "C" + + bRock string = "X" + bPaper string = "Y" + bScissors string = "Z" + + resultLose string = "X" + resultDraw string = "Y" + resultWin string = "Z" +) + +var scoreTable = map[string]map[string]int{ + aRock: { + bRock: 4, + bPaper: 8, + bScissors: 3, + }, + aPaper: { + bRock: 1, + bPaper: 5, + bScissors: 9, + }, + aScissors: { + bRock: 7, + bPaper: 2, + bScissors: 6, + }, +} + +var winOrLoseTable = map[string]map[string]string{ + aRock: { + resultWin: bPaper, + resultDraw: bRock, + resultLose: bScissors, + }, + aPaper: { + resultWin: bScissors, + resultDraw: bPaper, + resultLose: bRock, + }, + aScissors: { + resultWin: bRock, + resultDraw: bScissors, + resultLose: bPaper, + }, +} + +func Day2() helpers.DayResults { + day2Example := helpers.ReadFileByLine("data/Y22/day2/example.txt") + day2 := helpers.ReadFileByLine("data/Y22/day2/data.txt") + + results := helpers.DayResults{ + Day: 2, + Year: 2022, + Part1Example: part1(day2Example), + Part1: part1(day2), + Part2Example: part2(day2Example), + Part2: part2(day2), + } + + return results +} + +func part1(input []string) int { + score := 0 + for _, line := range input { + data := strings.Split(line, " ") + score += scoreTable[data[0]][data[1]] + } + + return score +} + +func part2(input []string) int { + score := 0 + for _, line := range input { + data := strings.Split(line, " ") + scoreValue := winOrLoseTable[data[0]][data[1]] + score += scoreTable[data[0]][scoreValue] + } + + return score +} diff --git a/data/Y22/y22.go b/data/Y22/y22.go new file mode 100644 index 0000000..3bb2a2c --- /dev/null +++ b/data/Y22/y22.go @@ -0,0 +1,15 @@ +package Y22 + +import ( + Y22D1 "adventofcode/data/Y22/day1" + Y22D2 "adventofcode/data/Y22/day2" + "adventofcode/src-go/helpers" +) + +func Day1() helpers.DayResults { + return Y22D1.Day1() +} + +func Day2() helpers.DayResults { + return Y22D2.Day2() +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d0e1e8e --- /dev/null +++ b/go.mod @@ -0,0 +1,11 @@ +module adventofcode + +go 1.21.4 + +require github.com/fatih/color v1.16.0 + +require ( + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + golang.org/x/sys v0.14.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..7f13de9 --- /dev/null +++ b/go.sum @@ -0,0 +1,11 @@ +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/src-go/helpers/Day.go b/src-go/helpers/Day.go new file mode 100644 index 0000000..0030169 --- /dev/null +++ b/src-go/helpers/Day.go @@ -0,0 +1,29 @@ +package helpers + +import ( + "strconv" + "strings" + + "github.com/fatih/color" +) + +type DayResults struct { + Day int `json:"day"` + Year int `json:"year"` + Part1Example int `json:"part1-example"` + Part1 int `json:"part1"` + Part2Example int `json:"part2-example"` + Part2 int `json:"part2"` +} + +func PrintDayResults(results DayResults) { + yellow := color.New(color.FgYellow).SprintFunc() + gray := color.New(color.FgHiBlack).SprintFunc() + + color.HiBlue("Day %d%s", results.Day, gray("/"+strconv.Itoa(results.Year))) + color.Green(" Part 1 (example): %s", yellow(results.Part1Example)) + color.HiGreen(" Part 1 : %s", yellow(results.Part1)) + color.Blue(" " + strings.Repeat("-", 23)) + color.Green(" Part 2 (example): %s", yellow(results.Part2Example)) + color.HiGreen(" Part 2 : %s", yellow(results.Part2)) +} diff --git a/src-go/helpers/ReadFileByLine.go b/src-go/helpers/ReadFileByLine.go new file mode 100644 index 0000000..8611d99 --- /dev/null +++ b/src-go/helpers/ReadFileByLine.go @@ -0,0 +1,55 @@ +package helpers + +import ( + "bufio" + "log" + "os" + "strconv" + "time" +) + +func ReadFileByLine(path string) []string { + file, err := os.Open(path) + if err != nil { + log.Fatal(err) + } + defer func(file *os.File) { + err := file.Close() + if err != nil { + log.Fatal(err) + } + }(file) + + scanner := bufio.NewScanner(file) + var returnData []string + for scanner.Scan() { + returnData = append(returnData, scanner.Text()) + } + + if err := scanner.Err(); err != nil { + log.Fatal(err) + } + + return returnData +} + +func GetDayYear() (int, int) { + // get current year + year, _, day := time.Now().Date() + // Change 2023 to 23 + year = year % 100 + + if len(os.Args) == 2 { + day, _ := strconv.Atoi(os.Args[1]) + return day, year + } + + if len(os.Args) == 3 { + day, _ := strconv.Atoi(os.Args[1]) + year, _ := strconv.Atoi(os.Args[2]) + + return day, year + } + + return day, year +}