diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index dc45a0f5..ee2715f3 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -21,6 +21,7 @@ on: jobs: linting: + needs: testing strategy: fail-fast: false max-parallel: 2 @@ -56,6 +57,7 @@ jobs: make lint-pipeline reports: + needs: linting strategy: fail-fast: true max-parallel: 1 @@ -130,6 +132,7 @@ jobs: build: + needs: linting strategy: fail-fast: false max-parallel: 2 diff --git a/.goreleaser.yml b/.goreleaser.yml index 7b811d8c..4f57ffee 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -40,6 +40,10 @@ builds: - -trimpath ldflags: - "{{ .Env.GO_BUILD_LDFLAGS }}" + - +universal_binaries: + - id: cli + replace: true archives: - id: cli diff --git a/README.md b/README.md index 0430af92..b2fb0f13 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ This repository contains solutions for puzzles and cli tool to run solutions to
2018 - - [ ] [Day 1: Chronal Calibration](https://adventofcode.com/2018/day/1) + - [x] [Day 1: Chronal Calibration](https://adventofcode.com/2018/day/1) - [ ] [Day 2: Inventory Management System](https://adventofcode.com/2018/day/2) - [ ] [Day 3: No Matter How You Slice It](https://adventofcode.com/2018/day/3) - [ ] [Day 4: Repose Record](https://adventofcode.com/2018/day/4) diff --git a/cmd/aoc-cli/main.go b/cmd/aoc-cli/main.go index abe4ce53..5261915b 100644 --- a/cmd/aoc-cli/main.go +++ b/cmd/aoc-cli/main.go @@ -4,7 +4,6 @@ package main import ( "bytes" "context" - "encoding/json" "errors" "fmt" "os" @@ -169,26 +168,6 @@ func handlePuzzleChoices(ctx context.Context, year string, opt promptui.Select) } } -// PrettyPrint appends to passed struct indents and returns a human-readable form of struct. -// Each element of JSON object will start from indent with prefix. -func PrettyPrint(v interface{}, prefix string, indent string) (string, error) { - b, err := json.Marshal(v) - if err != nil { - return "", fmt.Errorf("failed to marshal: %w", err) - } - - var out bytes.Buffer - if err := json.Indent(&out, b, prefix, indent); err != nil { - return "", fmt.Errorf("failed to indent: %w", err) - } - - if _, err := out.WriteString("\n"); err != nil { - return "", fmt.Errorf("failed to write string: %w", err) - } - - return out.String(), nil -} - func isExit(input string) bool { return strings.EqualFold(exit, input) } diff --git a/internal/puzzles/input/data/2018/day01.txt b/internal/puzzles/input/data/2018/day01.txt new file mode 100644 index 00000000..242093a7 --- /dev/null +++ b/internal/puzzles/input/data/2018/day01.txt @@ -0,0 +1,989 @@ ++16 +-15 +-2 +-6 +-6 +-17 ++3 ++11 +-5 ++19 ++16 ++10 +-4 ++10 ++7 ++5 +-8 ++7 ++10 +-15 ++16 +-8 ++19 ++13 +-17 +-16 ++18 ++4 +-19 ++11 +-10 ++9 ++19 ++5 ++18 +-1 ++14 ++14 ++4 ++14 ++7 +-11 +-4 +-1 ++7 ++11 ++16 ++16 +-15 ++12 ++12 +-7 ++2 +-10 ++13 +-2 ++16 ++18 +-13 +-8 +-2 ++18 +-7 +-17 ++21 ++1 +-19 ++16 ++9 ++2 +-7 +-19 ++16 ++16 +-1 ++12 ++18 +-3 +-8 +-17 ++8 +-7 +-7 ++2 +-18 +-13 ++3 ++7 ++13 ++1 ++15 ++9 +-18 ++2 ++14 +-6 ++11 +-1 ++16 +-8 ++19 ++3 ++5 +-12 +-18 +-2 ++18 +-17 +-10 ++21 ++21 +-11 +-18 ++4 +-14 +-6 +-16 +-17 ++8 +-20 +-15 +-5 +-10 ++18 +-17 +-19 +-4 +-13 +-3 +-1 +-8 +-6 +-5 ++18 ++15 +-5 +-4 +-14 +-18 ++14 ++3 +-7 +-17 ++12 +-16 ++18 +-19 ++10 ++18 ++9 ++15 +-20 ++3 ++11 ++18 ++19 +-14 ++3 ++14 ++3 ++6 ++11 +-15 +-18 +-19 +-12 ++20 ++5 ++3 +-12 +-11 ++27 ++2 +-1 ++5 +-15 ++22 +-5 ++10 ++25 +-19 +-17 ++38 +-20 ++25 ++25 ++27 ++12 +-7 ++19 ++8 ++17 +-1 +-9 ++17 ++18 ++13 +-6 ++14 ++2 +-4 ++16 ++7 ++18 ++11 +-19 ++13 +-16 ++2 ++8 +-19 ++17 +-20 ++6 ++13 +-12 ++3 +-19 +-18 ++15 +-5 ++19 ++19 ++4 +-9 ++15 ++8 +-4 +-3 +-19 ++20 +-3 ++21 +-9 ++15 ++15 +-16 ++7 ++8 ++15 ++8 +-17 ++3 ++21 +-8 +-17 +-2 ++1 +-21 +-5 ++21 ++11 +-16 +-19 ++12 +-5 +-16 +-13 ++3 +-18 +-14 ++4 ++19 +-1 +-6 +-15 ++8 +-17 +-8 ++10 ++1 +-5 ++9 +-25 ++12 +-19 +-9 +-4 +-14 +-3 ++4 ++16 +-8 ++10 +-15 +-5 ++13 +-6 +-17 +-4 ++3 ++17 ++19 ++13 ++2 ++19 ++8 +-9 +-12 +-20 +-2 +-12 ++15 +-13 +-5 ++21 +-22 +-16 +-10 +-9 +-15 +-18 ++19 ++19 +-17 ++9 ++10 ++16 +-12 ++9 ++2 ++2 ++20 ++17 +-18 +-17 +-14 +-2 +-9 +-2 +-7 ++16 +-18 ++25 ++35 ++20 +-12 ++10 +-19 ++15 +-4 ++11 ++19 +-31 +-11 +-30 +-58 +-4 ++18 +-57 +-21 ++11 +-24 +-14 +-27 +-3 +-18 +-7 +-2 +-12 +-4 ++14 +-1 +-5 ++13 +-4 ++11 +-21 +-26 ++3 ++13 +-7 ++9 ++6 +-17 +-14 ++19 ++16 ++17 +-7 +-21 +-4 +-14 +-16 +-9 +-10 ++8 ++13 +-5 +-4 ++8 +-24 ++7 +-5 ++11 ++25 ++7 +-11 +-28 ++11 ++13 ++21 ++11 ++9 +-17 +-19 ++20 ++38 +-1 ++11 ++15 +-28 ++40 ++10 ++52 ++51 +-3 ++25 +-6 ++133 ++9 ++15 +-16 +-15 ++14 ++5 ++14 +-12 ++9 ++32 +-13 +-38 ++33 +-65 ++56 ++15 +-263 ++210 ++62330 ++12 +-3 ++10 ++1 ++9 ++11 +-9 +-7 ++18 ++3 +-1 ++4 ++9 +-8 ++15 ++7 ++4 ++6 +-4 +-11 ++16 ++1 ++10 +-14 +-19 +-8 +-15 ++10 +-13 ++19 ++14 +-17 ++11 ++9 +-15 ++13 ++16 ++11 ++12 +-10 +-5 ++17 ++2 ++3 ++9 ++11 ++16 ++3 +-16 ++15 ++8 ++7 ++10 ++4 ++8 ++19 +-17 ++8 +-13 ++12 ++17 +-15 ++19 ++17 ++19 ++8 ++12 +-2 ++18 ++11 ++4 ++17 ++8 ++1 +-18 ++7 +-11 +-11 +-19 ++15 ++3 +-15 ++7 +-12 ++18 +-2 +-1 +-1 ++19 ++17 ++12 +-6 +-1 +-6 ++11 +-16 ++7 +-16 +-13 +-18 +-8 +-8 ++15 +-9 +-10 +-10 ++5 ++20 +-9 +-17 +-4 +-18 ++12 ++1 +-14 ++2 ++8 +-1 +-10 +-5 ++17 +-6 ++1 ++14 +-5 ++6 ++10 ++2 +-7 +-1 ++11 ++1 +-7 ++11 ++10 ++5 ++20 ++12 ++8 +-19 +-8 ++12 +-8 +-13 +-17 +-15 ++11 +-22 ++5 ++10 +-28 +-14 ++22 +-26 +-17 +-14 ++1 +-19 +-18 +-6 +-9 +-12 +-4 ++6 ++5 +-9 ++1 +-19 ++6 +-10 +-2 ++10 ++17 +-8 ++18 ++18 ++12 ++8 ++2 +-17 ++8 ++2 +-19 ++3 ++18 ++8 +-11 ++17 +-12 ++20 ++19 ++6 +-3 ++2 ++14 ++5 +-22 ++2 +-10 ++1 +-17 +-3 +-12 +-11 +-4 +-15 +-16 ++20 ++2 +-18 ++10 +-5 +-18 +-17 ++10 +-7 +-23 +-15 +-7 +-17 +-6 ++3 +-18 ++17 +-5 ++2 +-9 +-6 +-3 ++13 +-1 ++17 ++16 ++15 +-16 +-4 ++22 ++9 +-13 +-10 +-11 +-23 ++18 ++27 ++14 ++2 ++13 ++1 +-17 ++19 ++7 ++17 ++14 +-8 +-18 ++8 ++11 +-10 ++13 ++19 ++15 ++23 +-21 +-3 ++15 ++18 +-10 +-16 ++15 ++9 +-13 +-14 +-19 ++21 +-22 ++36 ++1 ++13 ++19 +-1 +-7 +-13 ++12 ++4 ++1 ++23 ++45 +-2 +-2 ++23 +-5 ++15 ++7 ++18 ++19 +-5 ++17 +-1 ++15 +-6 +-13 +-18 +-1 ++5 ++4 ++13 ++7 +-9 +-4 ++15 +-13 +-5 ++4 ++8 ++9 ++19 ++5 ++17 +-8 +-17 +-7 ++13 +-17 ++10 ++3 +-16 ++10 ++18 +-3 ++18 +-20 +-2 +-12 +-1 +-14 ++11 +-4 +-16 +-15 ++5 +-8 +-11 +-7 +-16 +-12 ++19 ++15 ++5 ++6 +-16 +-6 ++17 ++13 ++5 +-7 ++20 ++20 +-1 ++16 ++10 ++4 ++7 ++6 +-10 +-9 ++5 ++5 +-7 +-4 ++12 ++18 +-7 ++6 +-12 ++15 +-5 +-6 ++3 ++11 +-20 +-19 +-6 +-5 ++17 ++20 ++18 +-6 +-16 +-10 +-24 ++14 ++15 ++12 ++1 ++31 ++3 +-16 +-3 +-25 +-24 +-11 ++18 +-29 +-13 +-1 ++9 +-2 +-34 +-12 ++11 ++16 +-20 +-5 +-19 +-3 +-2 +-45 +-24 +-11 ++77 ++42 +-9 +-59 +-156 ++12 +-32 +-41 ++11 ++11 +-26 ++23 ++2 ++9 ++52 ++125 ++139 +-23 +-169 ++61744 +-9 +-2 ++4 ++3 +-9 +-8 +-19 ++2 +-1 ++10 +-12 +-10 ++3 ++3 +-5 ++17 +-3 +-8 ++7 +-12 ++27 +-3 +-6 ++11 ++2 +-5 +-12 ++16 ++7 ++6 ++8 ++8 +-3 +-8 ++5 ++19 ++10 ++2 ++1 +-18 ++10 ++18 ++8 ++14 +-11 +-1 ++19 ++9 ++15 ++8 +-2 +-11 ++16 +-18 +-11 ++16 ++3 +-15 ++2 +-5 +-8 +-16 ++19 ++12 ++4 ++8 +-3 ++5 +-8 ++18 ++19 ++18 ++14 ++12 ++19 +-2 ++14 +-18 ++1 ++2 +-19 +-14 +-8 ++7 ++8 +-1 ++9 ++10 +-2 ++1 +-4 ++18 ++1 ++18 ++15 +-2 ++14 ++10 ++18 +-15 +-2 +-7 +-7 +-3 +-12 +-4 ++18 +-7 +-6 +-3 +-124478 \ No newline at end of file diff --git a/internal/puzzles/solutions/2018/day01/solution.go b/internal/puzzles/solutions/2018/day01/solution.go new file mode 100644 index 00000000..1a4160f1 --- /dev/null +++ b/internal/puzzles/solutions/2018/day01/solution.go @@ -0,0 +1,194 @@ +package day01 + +import ( + "bufio" + "bytes" + "fmt" + "io" + "regexp" + "strconv" + "sync" + + "github.com/obalunenko/advent-of-code/internal/puzzles" +) + +const ( + puzzleName = "day01" + year = "2018" +) + +type solution struct { + year string + name string +} + +func (s solution) Name() string { + return s.name +} + +func (s solution) Year() string { + return s.year +} + +func init() { + puzzles.Register(solution{ + year: year, + name: puzzleName, + }) +} + +func (s solution) Part1(in io.Reader) (string, error) { + return part1(in) +} + +func (s solution) Part2(in io.Reader) (string, error) { + return part2(in) +} + +var ( + re = regexp.MustCompile(`(?s)(?P[+-])(?P\d+)`) +) + +const ( + _ = iota + sign + digits + + totalmatches = 3 +) + +func part1(in io.Reader) (string, error) { + scanner := bufio.NewScanner(in) + + fdevice := newDevice() + + for scanner.Scan() { + line := scanner.Text() + + delta, err := getFreqDelta(line) + if err != nil { + return "", err + } + + fdevice.Apply(delta) + } + + if err := scanner.Err(); err != nil { + return "", fmt.Errorf("scanner error: %w", err) + } + + return strconv.Itoa(fdevice.CurFreq()), nil +} + +func part2(in io.Reader) (string, error) { + var buf bytes.Buffer + + if _, err := buf.ReadFrom(in); err != nil { + return "", fmt.Errorf("failed to read: %w", err) + } + + b := buf.Bytes() + + var ( + loops int + found bool + ) + + fdevice := newDevice() + + for !found { + scanner := bufio.NewScanner(bytes.NewReader(b)) + + for scanner.Scan() { + line := scanner.Text() + + delta, err := getFreqDelta(line) + if err != nil { + return "", fmt.Errorf("get frequency delta: %w", err) + } + + fdevice.Apply(delta) + + if fdevice.SeenFreq(fdevice.CurFreq()) { + found = true + + break + } + } + + if err := scanner.Err(); err != nil { + return "", fmt.Errorf("scanner error: %w", err) + } + + loops++ + } + + return strconv.Itoa(fdevice.CurFreq()), nil +} + +type device struct { + frequency int + mu sync.Mutex + seen map[int]int +} + +func newDevice() *device { + d := device{ + frequency: 0, + mu: sync.Mutex{}, + seen: make(map[int]int), + } + + d.seen[0] = 1 + + return &d +} + +func (d *device) Apply(delta freqDelta) { + switch delta.sign { + case "+": + d.frequency += delta.d + case "-": + d.frequency -= delta.d + } + + d.mu.Lock() + defer d.mu.Unlock() + + d.seen[d.frequency] = d.seen[d.frequency] + 1 +} + +func (d *device) CurFreq() int { + return d.frequency +} + +func (d *device) SeenFreq(freq int) bool { + d.mu.Lock() + defer d.mu.Unlock() + + return d.seen[freq] > 1 +} + +type freqDelta struct { + sign string + d int +} + +func getFreqDelta(line string) (freqDelta, error) { + matches := re.FindStringSubmatch(line) + + if len(matches) != totalmatches { + return freqDelta{}, fmt.Errorf("wrong matches[%d] for line[%s], should be [%d]", + len(matches), line, totalmatches) + } + + d, err := strconv.Atoi(matches[digits]) + if err != nil { + return freqDelta{}, fmt.Errorf("strconv atoi: %w", err) + } + + return freqDelta{ + sign: matches[sign], + d: d, + }, nil +} diff --git a/internal/puzzles/solutions/2018/day01/solution_test.go b/internal/puzzles/solutions/2018/day01/solution_test.go new file mode 100644 index 00000000..e600232c --- /dev/null +++ b/internal/puzzles/solutions/2018/day01/solution_test.go @@ -0,0 +1,246 @@ +package day01 + +import ( + "io" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_solution_Part1(t *testing.T) { + type fields struct { + name string + year string + } + + type args struct { + input io.Reader + } + + tests := []struct { + name string + fields fields + args args + want string + wantErr bool + }{ + { + name: "+1, +1, +1` results in `3`", + fields: fields{ + name: "day01", + year: "2018", + }, + args: args{ + input: strings.NewReader("+1\n+1\n+1"), + }, + want: "3", + wantErr: false, + }, + { + name: "`+1, +1, -2` results in `0`", + fields: fields{ + name: "day01", + year: "2018", + }, + args: args{ + input: strings.NewReader("+1\n+1\n-2"), + }, + want: "0", + wantErr: false, + }, + { + name: "`-1, -2, -3` results in `-6`", + fields: fields{ + name: "day01", + year: "2018", + }, + args: args{ + input: strings.NewReader("-1\n-2\n-3"), + }, + want: "-6", + wantErr: false, + }, + { + name: "`+1, -2, +3, +1` results in `3`", + fields: fields{ + name: "", + }, + args: args{ + input: strings.NewReader("+1\n-2\n+3\n+1"), + }, + want: "3", + wantErr: false, + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + s := solution{ + year: tt.fields.year, + name: tt.fields.name, + } + + got, err := s.Part1(tt.args.input) + if tt.wantErr { + assert.Error(t, err) + + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.want, got) + }) + } +} + +func Test_solution_Part2(t *testing.T) { + type fields struct { + name string + year string + } + + type args struct { + input io.Reader + } + + tests := []struct { + name string + fields fields + args args + want string + wantErr bool + }{ + { + name: "`+1, -2, +3, +1` results in `2`", + fields: fields{ + name: "2018", + year: "day01", + }, + args: args{ + input: strings.NewReader("+1\n-2\n+3\n+1"), + }, + want: "2", + wantErr: false, + }, + { + name: "`+1, -1` first reaches `0` twice.", + fields: fields{ + name: "2018", + year: "day01", + }, + args: args{ + input: strings.NewReader("+1\n-1"), + }, + want: "0", + wantErr: false, + }, + { + name: "`+3, +3, +4, -2, -4` first reaches `10` twice.", + fields: fields{ + name: "2018", + year: "day01", + }, + args: args{ + input: strings.NewReader("+3\n+3\n+4\n-2\n-4"), + }, + want: "10", + wantErr: false, + }, + { + name: "`-6, +3, +8, +5, -6` first reaches `5` twice.", + fields: fields{ + name: "2018", + year: "day01", + }, + args: args{ + input: strings.NewReader("-6\n+3\n+8\n+5\n-6"), + }, + want: "5", + wantErr: false, + }, + { + name: "`+7, +7, -2, -7, -4` first reaches `14` twice.", + fields: fields{ + name: "2018", + year: "day01", + }, + args: args{ + input: strings.NewReader("+7\n+7\n-2\n-7\n-4"), + }, + want: "14", + wantErr: false, + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + s := solution{ + year: tt.fields.year, + name: tt.fields.name, + } + + got, err := s.Part2(tt.args.input) + if tt.wantErr { + assert.Error(t, err) + + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.want, got) + }) + } +} + +func Test_getFreqDelta(t *testing.T) { + type args struct { + line string + } + tests := []struct { + name string + args args + want freqDelta + wantErr bool + }{ + { + name: "", + args: args{ + line: "+2", + }, + want: freqDelta{ + sign: "+", + d: 2, + }, + wantErr: false, + }, + { + name: "", + args: args{ + line: "2", + }, + want: freqDelta{ + sign: "", + d: 0, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := getFreqDelta(tt.args.line) + if tt.wantErr { + assert.Error(t, err) + + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/internal/puzzles/solutions/2018/day01/spec.md b/internal/puzzles/solutions/2018/day01/spec.md new file mode 100644 index 00000000..67e9b32d --- /dev/null +++ b/internal/puzzles/solutions/2018/day01/spec.md @@ -0,0 +1,74 @@ +# --- Day 1: Chronal Calibration --- + +## --- Part One --- + +"We've detected some temporal anomalies," one of Santa's Elves at the Temporal Anomaly Research and Detection +Instrument Station tells you. She sounded pretty worried when she called you down here. +"At 500-year intervals into the past, someone has been changing Santa's history!" + +"The good news is that the changes won't propagate to our time stream for another 25 days, and we have a device" - +she attaches something to your wrist - "that will let you fix the changes with no such propagation delay. +It's configured to send you 500 years further into the past every few days; that was the best we could do +on such short notice." + +"The bad news is that we are detecting roughly fifty anomalies throughout time; the device will indicate fixed +anomalies with stars. The other bad news is that we only have one device, and you're the best person for the job! +Good lu--" She taps a button on the device, and you suddenly feel like you're falling. +To save Christmas, you need to get all fifty stars by December 25th. + +Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; +the second puzzle is unlocked when you complete the first. Each puzzle grants one star. +Good luck! + +After feeling like you've been falling for a few minutes, you look at the device's tiny screen. +"Error: Device must be calibrated before first use. Frequency drift detected. Cannot maintain destination lock." +Below the message, the device shows a sequence of changes in frequency (your puzzle input). +A value like `+6` means the current frequency increases by `6`; +a value like `-3` means the current frequency decreases by `3`. + +For example, if the device displays frequency changes of `+1, -2, +3, +1`, +then starting from a frequency of zero, the following changes would occur: + +- Current frequency `0`, change of `+1`; resulting frequency `1`. +- Current frequency `1`, change of `-2`; resulting frequency `-1`. +- Current frequency `-1`, change of `+3`; resulting frequency `2`. +- Current frequency `2`, change of `+1`; resulting frequency `3`. + + +In this example, the resulting frequency is `3`. + +### Here are other example situations: + +- `+1, +1, +1` results in `3` +- `+1, +1, -2` results in `0` +- `1, -2, -3` results in `-6` + +Starting with a frequency of zero, what is the resulting frequency after all the changes in frequency have been applied? + +## --- Part Two --- + +You notice that the device repeats the same frequency change list over and over. +To calibrate the device, you need to find the first frequency it reaches twice. + +For example, using the same list of changes above, the device would loop as follows: + +- Current frequency `0`, change of `+1`; resulting frequency `1`. +- Current frequency `1`, change of `-2`; resulting frequency `-1`. +- Current frequency `-1`, change of `+3`; resulting frequency `2`. +- Current frequency `2`, change of `+1`; resulting frequency `3`. +`(At this point, the device continues from the start of the list.)` +- Current frequency `3`, change of `+1`; resulting frequency `4`. +- Current frequency `4`, change of `-2`; resulting frequency `2`, which has already been seen. + +In this example, the first frequency reached twice is `2`. +Note that your device might need to repeat its list of frequency changes many times before a duplicate frequency +is found, and that duplicates might be found while in the middle of processing the list. + +### Here are other examples: + +- `+1, -1` first reaches `0` twice. +- `+3, +3, +4, -2, -4` first reaches `10` twice. +- `-6, +3, +8, +5, -6` first reaches `5` twice. +- `+7, +7, -2, -7, -4` first reaches `14` twice. + +What is the first frequency your device reaches twice? \ No newline at end of file diff --git a/internal/puzzles/solutions/register.go b/internal/puzzles/solutions/register.go index 77950f3e..84f93f12 100644 --- a/internal/puzzles/solutions/register.go +++ b/internal/puzzles/solutions/register.go @@ -16,6 +16,11 @@ import ( */ // register day01 solution. _ "github.com/obalunenko/advent-of-code/internal/puzzles/solutions/2017/day01" + /* + 2018 solutions. + */ + // register day01 solution. + _ "github.com/obalunenko/advent-of-code/internal/puzzles/solutions/2018/day01" /* 2019 solutions. */