Initial commit

This commit is contained in:
yxzzy-wtf
2023-12-01 15:13:45 +02:00
committed by GitHub
commit a474acea1e
9 changed files with 779 additions and 0 deletions

11
.devcontainer.json Normal file
View File

@@ -0,0 +1,11 @@
{
"image": "mcr.microsoft.com/devcontainers/go",
"customizations": {
"codespaces": {
"extensions": ["golang.go"]
},
"vscode": {
"extensions": ["golang.go"]
}
}
}

143
2022/02/code.go Executable file
View File

@@ -0,0 +1,143 @@
package main
import (
"fmt"
"strings"
"github.com/jpillora/puzzler/harness/aoc"
)
func main() {
aoc.Harness(run)
}
func run(part2 bool, input string) any {
sum := 0
for _, line := range strings.Split(strings.TrimSpace(input), "\n") {
pair := strings.SplitN(line, " ", 2)
var op move
op.unmarshal('A', pair[0])
if op.String() == "unknown" {
panic("invalid opponent move")
}
if part2 {
var o outcome
o.unmarshal(pair[1])
me := op.want(o)
sum += o.score() + me.score()
} else {
var me move
me.unmarshal('X', pair[1])
s := op.play(me).score()
sum += me.score() + s
}
}
return sum
}
type outcome byte
const (
lose outcome = iota
draw
win
)
func (o *outcome) unmarshal(s string) {
*o = outcome(delta('X', s))
}
func (o outcome) String() string {
switch o {
case lose:
return "lose"
case draw:
return "draw"
case win:
return "win"
}
return "unknown"
}
func (o outcome) score() int {
switch o {
case lose:
return 0
case draw:
return 3
case win:
return 6
}
panic("invalid outcome")
}
type move byte
const (
rock move = iota
paper
scissors
)
func (m *move) unmarshal(base byte, s string) {
*m = move(delta(base, s))
}
func (m move) String() string {
switch m {
case rock:
return "rock"
case paper:
return "paper"
case scissors:
return "scissors"
}
return "unknown"
}
func (m move) score() int {
return int(m) + 1
}
func (m move) play(against move) outcome {
if m == against {
return draw
}
if byte(m) == up(byte(against), 3) {
return lose
}
if byte(m) == down(byte(against), 3) {
return win
}
panic(fmt.Sprintf("invalid moves: %d plays %d", m, against))
}
func (m move) want(outcome outcome) move {
switch outcome {
case lose:
return move(down(byte(m), 3))
case draw:
return m
case win:
return move(up(byte(m), 3))
}
panic("invalid outcome")
}
func delta(base byte, m string) byte {
if len(m) != 1 {
panic("invalid delta")
}
return m[0] - base
}
func up(n, mod byte) byte {
return (n + 1) % mod
}
func down(n, mod byte) byte {
if n == 0 {
return mod - 1
}
return (n - 1) % mod
}

77
2022/04/code.go Executable file
View File

@@ -0,0 +1,77 @@
package main
import (
"fmt"
"log"
"strconv"
"strings"
"github.com/jpillora/puzzler/harness/aoc"
)
func main() {
aoc.Harness(run)
}
func run(part2 bool, input string) any {
if input == "" {
return "not implemented"
}
count := 0
lines := strings.Split(strings.TrimSpace(input), "\n")
for _, line := range lines {
pair := strings.SplitN(line, ",", 2)
if len(pair) != 2 {
log.Panicf("invalid input %q", line)
}
a := parse(pair[0])
b := parse(pair[1])
if !part2 && a.subsetEither(b) {
count++
} else if part2 && a.intersetsEither(b) {
count++
}
}
return count
}
type hilo struct {
lo, hi int
}
func (h hilo) String() string {
return fmt.Sprintf("%d-%d", h.lo, h.hi)
}
func parse(s string) hilo {
pair := strings.SplitN(s, "-", 2)
if len(pair) != 2 {
panic("bad pair")
}
lo, err := strconv.Atoi(pair[0])
if err != nil {
panic(err)
}
hi, err := strconv.Atoi(pair[1])
if err != nil {
panic(err)
}
return hilo{lo, hi}
}
func (a hilo) subsetEither(b hilo) bool {
return a.subsetOf(b) || b.subsetOf(a)
}
func (a hilo) subsetOf(b hilo) bool {
return a.lo >= b.lo && a.hi <= b.hi
}
func (a hilo) intersetsEither(b hilo) bool {
return a.intersets(b) || b.intersets(a)
}
func (a hilo) intersets(b hilo) bool {
return a.lo <= b.lo && b.lo <= a.hi || // b.lo in a OR
a.lo <= b.hi && b.hi <= a.hi // b.hi in a
}

260
2022/07/code.go Executable file
View File

@@ -0,0 +1,260 @@
package main
import (
"fmt"
"math"
"strconv"
"strings"
"github.com/jpillora/puzzler/harness/aoc"
)
func main() {
aoc.Harness(run)
}
func run(part2 bool, input string) any {
if input == "" {
return "skip"
}
var e *exec
execs := []*exec{}
for _, line := range strings.Split(strings.TrimSpace(input), "\n") {
if strings.HasPrefix(line, "$ ") {
command := strings.Split(line[2:], " ")
e = &exec{command: command}
execs = append(execs, e)
} else {
e.output = append(e.output, line)
}
}
fs := newFileSystem()
for _, e := range execs {
fs.simulate(e)
}
const draw = false
if draw {
fmt.Println(fs.root.tree())
}
if part2 {
return fs.MinDeleteFor(updateSize)
}
return fs.root.Size100KB()
}
type exec struct {
command []string
output []string
}
func (e exec) prog() string {
return e.command[0]
}
func (e exec) arg(i int) string {
return e.command[1+i]
}
type fileSystem struct {
root *dir
wd *dir
total int64
}
const updateSize = 30000000
func newFileSystem() *fileSystem {
root := newDir("", nil)
return &fileSystem{
root: root,
wd: root,
total: 70000000,
}
}
func (fs *fileSystem) simulate(e *exec) {
switch e.prog() {
case "cd":
fs.changeDir(e.arg(0))
case "ls":
fs.listDir(e.output)
default:
panic("unknown command")
}
}
func (fs *fileSystem) unused() int64 {
return fs.total - fs.root.Size()
}
func (fs *fileSystem) changeDir(target string) {
switch target {
case "/":
fs.wd = fs.root
case "..":
if fs.wd.parent == nil {
panic("nil parent")
}
fs.wd = fs.wd.parent
default:
fs.wd = fs.wd.subDir(target)
}
}
func (fs fileSystem) listDir(output []string) {
for _, line := range output {
pair := strings.SplitN(line, " ", 2)
name := pair[1]
if pair[0] == "dir" {
fs.wd.subDir(name)
continue
}
size, err := strconv.ParseInt(pair[0], 10, 64)
if err != nil {
panic(err)
}
fs.wd.file(name, size)
}
}
func (fs fileSystem) MinDeleteFor(target int64) int64 {
required := target - fs.unused()
if required < 0 {
panic("no min required")
}
min := int64(math.MaxInt64)
fs.root.forEach(func(d *dir) {
s := d.Size()
if s < required {
return
}
// d is a candidate
if s < min {
min = s
}
})
if min == math.MaxInt64 {
panic("no min found")
}
return min
}
type dir struct {
name string
children map[string]any
parent *dir
}
func newDir(name string, parent *dir) *dir {
return &dir{
name: name,
children: map[string]any{},
parent: parent,
}
}
func (d *dir) subDir(name string) *dir {
x, ok := d.children[name]
if !ok {
dir := newDir(name, d)
d.children[name] = dir
return dir
}
dir, ok := x.(*dir)
if !ok {
panic("file/dir mismatch")
}
return dir
}
func (d dir) tree() string {
sb := strings.Builder{}
fmt.Fprintf(&sb, "%s (%d) {\n", d.path(), d.Size())
for _, c := range d.children {
var out string
switch v := c.(type) {
case *dir:
out = v.tree()
case *file:
out = v.String()
default:
panic("invalid child")
}
ls := strings.Split(out, "\n")
for i := range ls {
ls[i] = " " + ls[i]
}
indented := strings.Join(ls, "\n")
sb.WriteString(indented)
sb.WriteRune('\n')
}
sb.WriteString("}")
return sb.String()
}
func (d *dir) file(name string, size int64) {
d.children[name] = &file{
name: name,
size: size,
}
}
func (d *dir) path() string {
if d.name == "" {
return "/"
}
p := []string{d.name}
w := d.parent
for w != nil {
p = append([]string{w.name}, p...)
w = w.parent
}
return strings.Join(p, "/")
}
func (d dir) Size() int64 {
sum := int64(0)
for _, c := range d.children {
switch v := c.(type) {
case *dir:
sum += v.Size()
case *file:
sum += v.size
default:
panic("invalid child")
}
}
return sum
}
func (d *dir) forEach(fn func(*dir)) {
fn(d)
for _, c := range d.children {
sub, ok := c.(*dir)
if !ok {
continue
}
sub.forEach(fn)
}
}
func (d dir) Size100KB() int64 {
const limit = 100000
sum := int64(0)
d.forEach(func(sub *dir) {
size := sub.Size()
if size < limit {
sum += size
}
})
return sum
}
type file struct {
name string
size int64
}
func (f file) String() string {
return fmt.Sprintf("%s (%d)", f.name, f.size)
}

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Jaime Pillora
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

77
README.md Normal file
View File

@@ -0,0 +1,77 @@
# Advent of Code in Go
A handy template repository to hold your [Advent of Code](https://adventofcode.com) solutions in Go (golang).
Advent of Code (https://adventofcode.com) is a yearly series of programming questions based on the [Advent Calendar](https://en.wikipedia.org/wiki/Advent_calendar). For each day leading up to christmas, there is one question released, and from the second it is released, there is a timer running and a leaderboard showing who solved it first.
---
### Features
* A directory per question `<year>/<day>`
* Auto-download questions into `<year>/<day>/README.md`
* Auto-download example input into `<year>/<day>/input-example.txt`
* With env variable `AOC_SESSION` set:
* Auto-download part 2 of questions into `<year>/<day>/README.md`
* Auto-download user input into `<year>/<day>/input-user.md`
* When you save `code.go`, it will execute your `run` function 4 times:
* Input `input-example.txt` and `part2=false`
* Input `input-example.txt` and `part2=true`
* Input `input-user.txt` and `part2=false`
* Input `input-user.txt` and `part2=true`
* and, will show the results and timing of each
---
### Usage
1. Click "**Use this template**" above to fork it into your account
1. Setup repo, either locally or in codespaces
* Locally
* Install Go from https://go.dev/dl/ or from brew, etc
* Git clone your fork
* Open in VS Code, and install the Go extension
* Codespaces
* Click "Open in Codespaces"
1. Open a terminal and `./run.sh <year> <day>` like this:
```sh
$ ./run.sh 2023 1
[run.sh] created ./2023/01
[run.sh] created ./2023/01/code.go
Created file README.md
Created file input-example.txt
run(part1, input-example) returned in 616µs => 42
```
1. Implement your solution in `./2023/01/code.go` inside the `run` function
* I have provided solutions for year `2022`, days `2`,`4`,`7` however you can delete them and do them yourself if you'd like
1. Changes will re-run the code
* For example, update `code.go` to `return 43` instead you should see:
```sh
file changed code.go
run(part1, input-example) returned in 34µs => 43
```
1. The question is downloaded to `./2023/01/README.md`
1. Login to https://adventofcode.com
1. Find your question (e.g. https://adventofcode.com/2023/day/1) and **[get your puzzle input](https://adventofcode.com/2023/day/1/input)** and save it to `./2023/01/input-user.txt`
* See **Session** below to automate this step
1. Iterate on `code.go` until you get the answer
1. Submit it to https://adventofcode.com/2023/day/1
---
#### Session
**Optionally**, you can set `export AOC_SESSION=<session>` to your adventofcode.com `session` cookie. That is:
* Login with your browser
* Open developer tools > Application/Storage > Cookies
* Retrieve the contents of `session`
* Export it as `AOC_SESSION`
With your session set, running `code.go` will download your user-specifc `input-user.txt` and also update `README.md` with part 2 of the question once you've completed part 1.
Currently, your session is NOT used to submit your answer. You still need to login to https://adventofcode.com to submit.

18
go.mod Normal file
View File

@@ -0,0 +1,18 @@
module aoc-in-go
go 1.21.3
require github.com/jpillora/puzzler v1.2.4
require (
github.com/JohannesKaufmann/html-to-markdown v1.4.2 // indirect
github.com/PuerkitoBio/goquery v1.8.1 // indirect
github.com/andybalholm/cascadia v1.3.2 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/jpillora/ansi v1.0.3 // indirect
github.com/jpillora/maplock v0.0.0-20160420012925-5c725ac6e22a // indirect
github.com/maruel/panicparse/v2 v2.3.1 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.15.0 // indirect
)

118
go.sum Normal file
View File

@@ -0,0 +1,118 @@
github.com/JohannesKaufmann/html-to-markdown v1.3.6 h1:i3Ma4RmIU97gqArbxZXbFqbWKm7XtImlMwVNUouQ7Is=
github.com/JohannesKaufmann/html-to-markdown v1.3.6/go.mod h1:Ol3Jv/xw8jt8qsaLeSh/6DBBw4ZBJrTqrOu3wbbUUg8=
github.com/JohannesKaufmann/html-to-markdown v1.4.2 h1:Jt3i/2l98+yOb5uD0ovoIGwccF4DfNxBeUye4P5KP9g=
github.com/JohannesKaufmann/html-to-markdown v1.4.2/go.mod h1:AwPLQeuGhVGKyWXJR8t46vR0iL1d3yGuembj8c1VcJU=
github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/jpillora/ansi v1.0.3 h1:nn4Jzti0EmRfDxm7JtEs5LzCbNwd5sv+0aE+LdS9/ZQ=
github.com/jpillora/ansi v1.0.3/go.mod h1:D2tT+6uzJvN1nBVQILYWkIdq7zG+b5gcFN5WI/VyjMY=
github.com/jpillora/maplock v0.0.0-20160420012925-5c725ac6e22a h1:40K0UjFKjfaXcJaGMgf9C0fOzwDxPZMOI0CPbNP89cQ=
github.com/jpillora/maplock v0.0.0-20160420012925-5c725ac6e22a/go.mod h1:bn3xq9G+QDq2j6fczyaTq47L6980t7/NnqCnCK7kqD0=
github.com/jpillora/puzzler v1.2.4 h1:GqvRA7yMWWYXyLx+WXhkZjTldvEdQ4F5z+86rCHzjpQ=
github.com/jpillora/puzzler v1.2.4/go.mod h1:OQ/o2V9d+0kZhtOwAZ/x3n91i0seYWvMfVLa6M9riUQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/maruel/panicparse/v2 v2.3.1 h1:NtJavmbMn0DyzmmSStE8yUsmPZrZmudPH7kplxBinOA=
github.com/maruel/panicparse/v2 v2.3.1/go.mod h1:s3UmQB9Fm/n7n/prcD2xBGDkwXD6y2LeZnhbEXvs9Dg=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y=
github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.4.14 h1:jwww1XQfhJN7Zm+/a1ZA/3WUiEBEroYFNTiV3dKwM8U=
github.com/yuin/goldmark v1.4.14/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI=
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

54
run.sh Executable file
View File

@@ -0,0 +1,54 @@
#!/bin/bash
set -euf -o pipefail
# functions
function template() {
cat <<EOF
package main
import (
"github.com/jpillora/puzzler/harness/aoc"
)
func main() {
aoc.Harness(run)
}
// on code change, run will be executed 4 times:
// 1. with: false (part1), and example input
// 2. with: true (part2), and example input
// 3. with: false (part1), and user input
// 4. with: true (part2), and user input
// the return value of each run is printed to stdout
func run(part2 bool, input string) any {
// when you're ready to do part 2, remove this "not implemented" block
if part2 {
return "not implemented"
}
// solve part 1 here
return 42
}
EOF
}
# two args YEAR and DAY
YEAR="${1:-}"
DAY="${2:-}"
if [ -z "$YEAR" ] || [ -z "$DAY" ]; then
echo "Usage: $0 <YEAR> <DAY>"
exit 1
fi
# pad DAY to 2 digits
DAY=$(printf "%02d" $DAY)
DIR="./$YEAR/$DAY"
# create missing files as needed
if [ ! -d "$DIR" ]; then
mkdir -p "$DIR"
echo "[run.sh] created $DIR"
fi
if [ ! -f "$DIR/code.go" ]; then
template >"$DIR/code.go"
echo "[run.sh] created $DIR/code.go"
fi
# go run
cd "$DIR" && go run code.go