mirror of
https://github.com/Threnklyn/advent-of-code-go.git
synced 2026-05-18 19:13:27 +02:00
update scripts
This commit is contained in:
+3
-1
@@ -1,3 +1,5 @@
|
||||
.vscode/*
|
||||
input*.txt
|
||||
prompt.*
|
||||
!scripts/skeleton/tmpls/input.txt
|
||||
prompt.md
|
||||
prompt.txt
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
# Advent of Code 2018
|
||||
Language: GoLang.
|
||||
|
||||
[https://adventofcode.com/2018](https://adventofcode.com/2018)
|
||||
|
||||
---
|
||||
## Summary
|
||||
Day | Name | Type of Algo & Notes
|
||||
--- | --- | ---
|
||||
1 | Chronal Calibration | - Pretty simple, direct math problem
|
||||
2 | Inventory Management System | - Pretty simple, brute force string comparison
|
||||
3 | No Matter How You Slice It | - Still pretty simple, 2D grid overlaps, simple hashmap problem
|
||||
4 | Repose Record | - Not very fun data manipulation, pretty straight forward "which time does X happen most often at"
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
# Advent of Code 2019
|
||||
Language: GoLang.
|
||||
Language: Go
|
||||
|
||||
[https://adventofcode.com/2019](https://adventofcode.com/2019)
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
## 2020 Event
|
||||
|
||||
To run days for 2020, I'm planning on using `go test -run RegExpToMatchFunctionNames .` to make it cleaner to run any given examples.
|
||||
`go run main.go -part <1 or 2>` will be usable to run the actual inputs for that day
|
||||
|
||||
Scripts have been added to the outer folder to setup files for a particular day more easily
|
||||
```zsh
|
||||
for ((i=1; i<26; i++)); do
|
||||
go run ../scripts/template/template.go -day $i -year 2020
|
||||
done
|
||||
```
|
||||
|
||||
and to fetch input prompts
|
||||
```go
|
||||
// optional -day and -year flags with sensible defaults (today)
|
||||
go run ../scripts/fetchers/cmd-inputs.go
|
||||
```
|
||||
@@ -0,0 +1,39 @@
|
||||
# https://gist.github.com/prwhite/8168133
|
||||
help: ## Show this help
|
||||
@ echo 'Usage: make <target>'
|
||||
@ echo
|
||||
@ echo 'Available targets:'
|
||||
@ grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-20s\033[0m %s\n", $$1, $$2}'
|
||||
|
||||
check-aoc-cookie: ## ensures $AOC_SESSION_COOKIE env var is set
|
||||
@ test $${AOC_SESSION_COOKIE?env var not set}
|
||||
|
||||
skeleton: ## make skeleton main(_test).go files, optional: $DAY and $YEAR
|
||||
# Check DAY and YEAR are both set
|
||||
@ if [[ -n $$DAY && -n $$YEAR ]]; then \
|
||||
go run scripts/cmd/skeleton/main.go -day $(DAY) -year $(YEAR); \
|
||||
fi
|
||||
# if DAY or YEAR are not set, allow the go binary to default to today
|
||||
@ if [[ -z $$DAY || -z $$YEAR ]]; then \
|
||||
go run scripts/cmd/skeleton/main.go; \
|
||||
fi
|
||||
|
||||
input: check-aoc-cookie ## get input, requires $AOC_SESSION_COOKIE, optional: $DAY and $YEAR
|
||||
# Check DAY and YEAR are both set
|
||||
@ if [[ -n $$DAY && -n $$YEAR ]]; then \
|
||||
go run scripts/cmd/input/main.go -day $(DAY) -year $(YEAR) -cookie $(AOC_SESSION_COOKIE); \
|
||||
fi
|
||||
# if DAY or YEAR are not yet, allow the go binary to default to today
|
||||
@ if [[ -z $$DAY || -z $$YEAR ]]; then \
|
||||
go run scripts/cmd/input/main.go -cookie $(AOC_SESSION_COOKIE); \
|
||||
fi
|
||||
|
||||
prompt: check-aoc-cookie ## get prompt, requires $AOC_SESSION_COOKIE, optional: $DAY and $YEAR
|
||||
# Check DAY and YEAR are both set
|
||||
@ if [[ -n $$DAY && -n $$YEAR ]]; then \
|
||||
go run scripts/cmd/prompt/main.go -day $(DAY) -year $(YEAR) -cookie $(AOC_SESSION_COOKIE); \
|
||||
fi
|
||||
# if DAY or YEAR are not yet, allow the go binary to default to today
|
||||
@ if [[ -z $$DAY || -z $$YEAR ]]; then \
|
||||
go run scripts/cmd/prompt/main.go -cookie $(AOC_SESSION_COOKIE); \
|
||||
fi
|
||||
@@ -1 +1,36 @@
|
||||
<img src="./300.png">
|
||||

|
||||
|
||||
|
||||
## Running Locally
|
||||
### Requirements
|
||||
Go 1.16+ is required because [embed][embed] is used for input files.
|
||||
|
||||
Use `go run main.go -part <1 or 2>` will be usable to run the actual inputs for that day.
|
||||
|
||||
Use `go test -run RegExpToMatchFunctionNames .` to run examples and unit tests via the `main_test.go` files.
|
||||
|
||||
## Scripts (used for all years but 2019)
|
||||
Makefile should be fairly self-documenting. Alternatively you can run the binaries yourself via `go run` or `go build`.
|
||||
|
||||
`make help` prints a help message.
|
||||
|
||||
### Make skeleton files
|
||||
```sh
|
||||
for ((i=1; i<26; i++)); do
|
||||
make skeleton DAY=$i YEAR=2021
|
||||
done
|
||||
```
|
||||
|
||||
Note that skeletons use [embed][embed] and __will not compile__ without an `input.txt` file located in the same folder. Input files can be made via `make input`.
|
||||
```sh
|
||||
make skeleton DAY=5 YEAR=2020
|
||||
make input DAY=5 YEAR=2020 AOC_SESSION_COOKIE=your_cookie
|
||||
```
|
||||
|
||||
### Fetch inputs and write to input.txt files
|
||||
Requires passing your cookie from AOC from either `-cookie` flag, or `AOC_SESSION_COOKIE` env variable.
|
||||
```sh
|
||||
make input DAY=1 YEAR=2020
|
||||
```
|
||||
|
||||
[embed]: https://golang.org/pkg/embed/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module github.com/alexchao26/advent-of-code-go
|
||||
|
||||
go 1.13
|
||||
go 1.16
|
||||
|
||||
require golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
// Package aoc gets inputs and prompts from adventofcode.com
|
||||
package aoc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func ParseFlags() (day, year int, cookie string) {
|
||||
today := time.Now()
|
||||
flag.IntVar(&day, "day", today.Day(), "day number to fetch, 1-25")
|
||||
flag.IntVar(&year, "year", today.Year(), "AOC year")
|
||||
// defaults to env variable
|
||||
flag.StringVar(&cookie, "cookie", os.Getenv("AOC_SESSION_COOKIE"), "AOC session cookie")
|
||||
flag.Parse()
|
||||
|
||||
if day > 25 || day < 1 {
|
||||
log.Fatalf("day out of range: %d", day)
|
||||
}
|
||||
|
||||
if year < 2015 {
|
||||
log.Fatalf("year is before 2015: %d", year)
|
||||
}
|
||||
|
||||
if cookie == "" {
|
||||
log.Fatalf("no session cookie set on flag or env var (AOC_SESSION_COOKIE)")
|
||||
}
|
||||
|
||||
return day, year, cookie
|
||||
}
|
||||
|
||||
func GetWithAOCCookie(url string, cookie string) []byte {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
defer cancel()
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
|
||||
if err != nil {
|
||||
log.Fatalf("making request: %s", err)
|
||||
}
|
||||
|
||||
sessionCookie := http.Cookie{
|
||||
Name: "session",
|
||||
Value: cookie,
|
||||
}
|
||||
req.AddCookie(&sessionCookie)
|
||||
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
log.Fatalf("making request: %s", err)
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
log.Fatalf("reading response body: %s", err)
|
||||
}
|
||||
fmt.Println("response length is", len(body))
|
||||
|
||||
// specific error message from AOC site
|
||||
if strings.HasPrefix(string(body), "Please don't repeatedly") {
|
||||
log.Fatalf("Repeated request github.com/alexchao26/advent-of-code-go error")
|
||||
}
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func WriteToFile(filename string, contents []byte) {
|
||||
err := os.MkdirAll(filepath.Dir(filename), os.ModePerm)
|
||||
if err != nil {
|
||||
log.Fatalf("making directory: %s", err)
|
||||
}
|
||||
err = os.WriteFile(filename, contents, os.FileMode(0644))
|
||||
if err != nil {
|
||||
log.Fatalf("writing file: %s", err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package aoc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/alexchao26/advent-of-code-go/util"
|
||||
)
|
||||
|
||||
func GetInput(day, year int, cookie string) {
|
||||
fmt.Printf("fetching for day %d, year %d\n", day, year)
|
||||
|
||||
// make the request
|
||||
url := fmt.Sprintf("https://adventofcode.com/%d/day/%d/input", year, day)
|
||||
body := GetWithAOCCookie(url, cookie)
|
||||
|
||||
if strings.HasPrefix(string(body), "Puzzle inputs differ by user") {
|
||||
panic("'Puzzle inputs differ by user' response")
|
||||
}
|
||||
|
||||
// write to file
|
||||
filename := filepath.Join(util.Dirname(), "../..", fmt.Sprintf("%d/day%02d/input.txt", year, day))
|
||||
WriteToFile(filename, body)
|
||||
|
||||
fmt.Println("Wrote to file: ", filename)
|
||||
|
||||
fmt.Println("Done!")
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package aoc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -8,25 +8,22 @@ import (
|
||||
|
||||
"golang.org/x/net/html"
|
||||
|
||||
"github.com/alexchao26/advent-of-code-go/scripts/fetchers"
|
||||
"github.com/alexchao26/advent-of-code-go/util"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// determine day to fetch
|
||||
day, year, cookie := fetchers.ParseFlags()
|
||||
fmt.Println("fetching for day", day)
|
||||
func GetPrompt(day, year int, cookie string) {
|
||||
fmt.Printf("fetching for day %d, year %d\n", day, year)
|
||||
|
||||
// make the request
|
||||
url := fmt.Sprintf("https://adventofcode.com/%d/day/%d", year, day)
|
||||
body := fetchers.GetWithAOCCookie(url, cookie)
|
||||
body := GetWithAOCCookie(url, cookie)
|
||||
|
||||
// parse the dang html
|
||||
prompt := parseHTML(body)
|
||||
|
||||
// write to file
|
||||
filename := filepath.Join(util.Dirname(), "../../../", fmt.Sprintf("%d/day%02d/prompt.md", year, day))
|
||||
fetchers.WriteToFile(filename, []byte(prompt))
|
||||
filename := filepath.Join(util.Dirname(), "../../", fmt.Sprintf("%d/day%02d/prompt.md", year, day))
|
||||
WriteToFile(filename, []byte(prompt))
|
||||
|
||||
fmt.Println("Wrote prompt to file: ", filename)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package main
|
||||
|
||||
import "github.com/alexchao26/advent-of-code-go/scripts/aoc"
|
||||
|
||||
func main() {
|
||||
day, year, cookie := aoc.ParseFlags()
|
||||
aoc.GetInput(day, year, cookie)
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package main
|
||||
|
||||
import "github.com/alexchao26/advent-of-code-go/scripts/aoc"
|
||||
|
||||
func main() {
|
||||
day, year, cookie := aoc.ParseFlags()
|
||||
aoc.GetPrompt(day, year, cookie)
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"time"
|
||||
|
||||
"github.com/alexchao26/advent-of-code-go/scripts/skeleton"
|
||||
)
|
||||
|
||||
func main() {
|
||||
today := time.Now()
|
||||
day := flag.Int("day", today.Day(), "day number to fetch, 1-25")
|
||||
year := flag.Int("year", today.Year(), "AOC year")
|
||||
flag.Parse()
|
||||
skeleton.Run(*day, *year)
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/alexchao26/advent-of-code-go/scripts/fetchers"
|
||||
"github.com/alexchao26/advent-of-code-go/util"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// determine day to fetch
|
||||
day, year, cookie := fetchers.ParseFlags()
|
||||
fmt.Println("fetching for day", day)
|
||||
|
||||
// make the request
|
||||
url := fmt.Sprintf("https://adventofcode.com/%d/day/%d/input", year, day)
|
||||
body := fetchers.GetWithAOCCookie(url, cookie)
|
||||
|
||||
// write to file
|
||||
filename := filepath.Join(util.Dirname(), "../../..", fmt.Sprintf("%d/day%02d/input.txt", year, day))
|
||||
fetchers.WriteToFile(filename, body)
|
||||
|
||||
fmt.Println("Wrote to file: ", filename)
|
||||
|
||||
fmt.Println("Done!")
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package fetchers
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func panicWrap(err error, str string) {
|
||||
panic(fmt.Sprintf("%s: %s", str, err))
|
||||
}
|
||||
|
||||
func ParseFlags() (day, year int, cookie string) {
|
||||
today := time.Now()
|
||||
flag.IntVar(&day, "day", today.Day(), "day number to fetch, 1-25")
|
||||
flag.IntVar(&year, "year", today.Year(), "AOC year")
|
||||
// env variable set via .bash_profile/.zshenv/etc
|
||||
flag.StringVar(&cookie, "cookie", os.Getenv("AOC_SESSION_COOKIE"), "AOC session cookie")
|
||||
flag.Parse()
|
||||
|
||||
if day > 25 {
|
||||
panic("day out of range")
|
||||
}
|
||||
|
||||
if cookie == "" {
|
||||
panic("No session cookie set on flag or env")
|
||||
}
|
||||
|
||||
return day, year, cookie
|
||||
}
|
||||
|
||||
func GetWithAOCCookie(url string, cookie string) []byte {
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
panicWrap(err, "making request")
|
||||
}
|
||||
|
||||
sessionCookie := http.Cookie{
|
||||
Name: "session",
|
||||
Value: cookie,
|
||||
}
|
||||
req.AddCookie(&sessionCookie)
|
||||
|
||||
cli := http.Client{
|
||||
Timeout: time.Second * 10,
|
||||
}
|
||||
res, err := cli.Do(req)
|
||||
if err != nil {
|
||||
panicWrap(err, "making request")
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
fmt.Println("response length is", len(body))
|
||||
|
||||
if strings.HasPrefix(string(body), "Please don't repeatedly") {
|
||||
panic("Repeated request github.com/alexchao26/advent-of-code-go error")
|
||||
}
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func WriteToFile(filename string, contents []byte) {
|
||||
MakeDir(filepath.Dir(filename))
|
||||
|
||||
err := ioutil.WriteFile(filename, contents, os.FileMode(0644))
|
||||
if err != nil {
|
||||
panicWrap(err, "writing file")
|
||||
}
|
||||
}
|
||||
|
||||
func MakeDir(dir string) {
|
||||
err := os.MkdirAll(dir, os.ModePerm)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// Package skeleton makes skeletons to be filled out with solutions.
|
||||
package skeleton
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"text/template"
|
||||
|
||||
"github.com/alexchao26/advent-of-code-go/util"
|
||||
)
|
||||
|
||||
//go:embed tmpls/*.go
|
||||
var fs embed.FS
|
||||
|
||||
// Run makes a skeleton main.go and main_test.go file for the given day and year
|
||||
func Run(day, year int) {
|
||||
if day > 25 || day <= 0 {
|
||||
log.Fatalf("invalid -day value, must be 1 through 25, got %v", day)
|
||||
}
|
||||
|
||||
if year < 2015 {
|
||||
log.Fatalf("year is before 2015: %d", year)
|
||||
}
|
||||
|
||||
ts, err := template.ParseFS(fs, "tmpls/*.go")
|
||||
if err != nil {
|
||||
log.Fatalf("parsing tmpls directory: %s", err)
|
||||
}
|
||||
|
||||
mainFilename := filepath.Join(util.Dirname(), "../../", fmt.Sprintf("%d/day%02d/main.go", year, day))
|
||||
testFilename := filepath.Join(util.Dirname(), "../../", fmt.Sprintf("%d/day%02d/main_test.go", year, day))
|
||||
|
||||
err = os.MkdirAll(filepath.Dir(mainFilename), os.ModePerm)
|
||||
if err != nil {
|
||||
log.Fatalf("making directory: %s", err)
|
||||
}
|
||||
|
||||
ensureNotOverwriting(mainFilename)
|
||||
ensureNotOverwriting(testFilename)
|
||||
|
||||
mainFile, err := os.Create(mainFilename)
|
||||
if err != nil {
|
||||
log.Fatalf("creating main.go file: %v", err)
|
||||
}
|
||||
testFile, err := os.Create(testFilename)
|
||||
if err != nil {
|
||||
log.Fatalf("creating main_test.go file: %v", err)
|
||||
}
|
||||
|
||||
ts.ExecuteTemplate(mainFile, "main.go", nil)
|
||||
ts.ExecuteTemplate(testFile, "main_test.go", nil)
|
||||
fmt.Printf("templates made for %d-day%d\n", year, day)
|
||||
}
|
||||
|
||||
func ensureNotOverwriting(filename string) {
|
||||
_, err := os.Stat(filename)
|
||||
if err == nil {
|
||||
log.Fatalf("File already exists: %s", filename)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
@@ -0,0 +1,57 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/alexchao26/advent-of-code-go/cast"
|
||||
"github.com/alexchao26/advent-of-code-go/util"
|
||||
)
|
||||
|
||||
//go:embed input.txt
|
||||
var input string
|
||||
|
||||
func init() {
|
||||
// do this in init (not main) so test file has same input
|
||||
input = strings.TrimRight(input, "\n")
|
||||
if len(input) == 0 {
|
||||
panic("empty input.txt file")
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var part int
|
||||
flag.IntVar(&part, "part", 1, "part 1 or 2")
|
||||
flag.Parse()
|
||||
fmt.Println("Running part", part)
|
||||
|
||||
if part == 1 {
|
||||
ans := part1(input)
|
||||
util.CopyToClipboard(fmt.Sprintf("%v", ans))
|
||||
fmt.Println("Output:", ans)
|
||||
} else {
|
||||
ans := part2(input)
|
||||
util.CopyToClipboard(fmt.Sprintf("%v", ans))
|
||||
fmt.Println("Output:", ans)
|
||||
}
|
||||
}
|
||||
|
||||
func part1(input string) int {
|
||||
parsed := parseInput(input)
|
||||
_ = parsed
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func part2(input string) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func parseInput(input string) (ans []int) {
|
||||
for _, line := range strings.Split(input, "\n") {
|
||||
ans = append(ans, cast.ToInt(line))
|
||||
}
|
||||
return ans
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_part1(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
want int
|
||||
}{
|
||||
{
|
||||
name: "actual",
|
||||
input: input,
|
||||
want: 0,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := part1(tt.input); got != tt.want {
|
||||
t.Errorf("part1() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_part2(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
want int
|
||||
}{
|
||||
{
|
||||
name: "actual",
|
||||
input: input,
|
||||
want: 0,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := part2(tt.input); got != tt.want {
|
||||
t.Errorf("part2() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"text/template"
|
||||
|
||||
"github.com/alexchao26/advent-of-code-go/scripts/fetchers"
|
||||
"github.com/alexchao26/advent-of-code-go/util"
|
||||
)
|
||||
|
||||
type TemplateData struct {
|
||||
Year int
|
||||
Day string // a string to include the prefixing zero
|
||||
}
|
||||
|
||||
var testTemplateString = `package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_part1(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
want int
|
||||
}{
|
||||
// {"actual", util.ReadFile("input.txt"), ACTUAL_ANSWER},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := part1(tt.input); got != tt.want {
|
||||
t.Errorf("part1() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_part2(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
want int
|
||||
}{
|
||||
// {"actual", util.ReadFile("input.txt"), ACTUAL_ANSWER},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := part2(tt.input); got != tt.want {
|
||||
t.Errorf("part2() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var solutionTemplateString = `package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/alexchao26/advent-of-code-go/cast"
|
||||
"github.com/alexchao26/advent-of-code-go/util"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var part int
|
||||
flag.IntVar(&part, "part", 1, "part 1 or 2")
|
||||
flag.Parse()
|
||||
fmt.Println("Running part", part)
|
||||
|
||||
if part == 1 {
|
||||
ans := part1(util.ReadFile("./input.txt"))
|
||||
util.CopyToClipboard(fmt.Sprintf("%v", ans))
|
||||
fmt.Println("Output:", ans)
|
||||
} else {
|
||||
ans := part2(util.ReadFile("./input.txt"))
|
||||
util.CopyToClipboard(fmt.Sprintf("%v", ans))
|
||||
fmt.Println("Output:", ans)
|
||||
}
|
||||
}
|
||||
|
||||
func part1(input string) int {
|
||||
parsed := parseInput(input)
|
||||
_ = parsed
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func part2(input string) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func parseInput(input string) (ans []int) {
|
||||
for _, line := range strings.Split(input, "\n") {
|
||||
ans = append(ans, cast.ToInt(l))
|
||||
}
|
||||
return ans
|
||||
}
|
||||
`
|
||||
|
||||
func main() {
|
||||
day, year, _ := fetchers.ParseFlags()
|
||||
data := TemplateData{
|
||||
Year: year,
|
||||
Day: fmt.Sprintf("%02d", day),
|
||||
}
|
||||
|
||||
testTemp, err := template.New("test-template").Parse(testTemplateString)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
solutionTemp, err := template.New("solution-template").Parse(solutionTemplateString)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
solutionFilename := filepath.Join(util.Dirname(), "../../", fmt.Sprintf("%d/day%02d/main.go", year, day))
|
||||
testFilename := filepath.Join(util.Dirname(), "../../", fmt.Sprintf("%d/day%02d/main_test.go", year, day))
|
||||
|
||||
fetchers.MakeDir(filepath.Dir(solutionFilename))
|
||||
|
||||
EnsureNotOverwriting(solutionFilename)
|
||||
EnsureNotOverwriting(testFilename)
|
||||
|
||||
solutionWriter, err := os.Create(solutionFilename)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
testWriter, err := os.Create(testFilename)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// note: data is no longer used, but keeping it for future reference of text/template
|
||||
solutionTemp.Execute(solutionWriter, data)
|
||||
testTemp.Execute(testWriter, data)
|
||||
fmt.Println("templates made")
|
||||
}
|
||||
|
||||
func EnsureNotOverwriting(filename string) {
|
||||
_, err := os.Stat(filename)
|
||||
if err == nil {
|
||||
panic(fmt.Sprintf("File already exists: %s", filename))
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -8,10 +8,10 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
ReadFile is a wrapper over io/ioutil.ReadFile but also determines the
|
||||
dynamic absolute path to the file.
|
||||
*/
|
||||
// ReadFile is a wrapper over io/ioutil.ReadFile but also determines the dynamic
|
||||
// absolute path to the file.
|
||||
//
|
||||
// Deprecated in favor of go:embed, refer to scripts/skeleton/tmpls
|
||||
func ReadFile(pathFromCaller string) string {
|
||||
// Docs: https://golang.org/pkg/runtime/#Caller
|
||||
_, filename, _, ok := runtime.Caller(1)
|
||||
|
||||
Reference in New Issue
Block a user