Skip to content

Commit 50b4e07

Browse files
committed
feat(puzzles): Implement 2018/day02 part2
1 parent ceaaa10 commit 50b4e07

File tree

3 files changed

+210
-14
lines changed

3 files changed

+210
-14
lines changed

internal/puzzles/solutions/2018/day01/solution.go

Lines changed: 119 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
package day01
22

33
import (
4+
"bufio"
5+
"bytes"
6+
"fmt"
47
"io"
8+
"regexp"
9+
"strconv"
510

611
"github.com/obalunenko/advent-of-code/internal/puzzles"
712
)
@@ -32,9 +37,121 @@ func init() {
3237
}
3338

3439
func (s solution) Part1(in io.Reader) (string, error) {
35-
return "", puzzles.ErrNotImplemented
40+
return part1(in)
3641
}
3742

3843
func (s solution) Part2(in io.Reader) (string, error) {
39-
return "", puzzles.ErrNotImplemented
44+
return part2(in)
45+
}
46+
47+
var (
48+
re = regexp.MustCompile(`(?s)(?P<sign>[+-])(?P<digits>\d+)`)
49+
)
50+
51+
const (
52+
_ = iota
53+
sign
54+
digits
55+
56+
totalmatches = 3
57+
)
58+
59+
func part1(in io.Reader) (string, error) {
60+
scanner := bufio.NewScanner(in)
61+
62+
var curfreq int
63+
64+
for scanner.Scan() {
65+
line := scanner.Text()
66+
67+
matches := re.FindStringSubmatch(line)
68+
69+
if len(matches) != totalmatches {
70+
return "", fmt.Errorf("wrong matches[%d] for line[%s], should be [%d]",
71+
len(matches), line, totalmatches)
72+
}
73+
74+
d, err := strconv.Atoi(matches[digits])
75+
if err != nil {
76+
return "", fmt.Errorf("strconv atoi: %w", err)
77+
}
78+
79+
switch matches[sign] {
80+
case "+":
81+
curfreq += d
82+
case "-":
83+
curfreq -= d
84+
}
85+
}
86+
87+
if err := scanner.Err(); err != nil {
88+
return "", fmt.Errorf("scanner error: %w", err)
89+
}
90+
91+
return strconv.Itoa(curfreq), nil
92+
}
93+
94+
func part2(in io.Reader) (string, error) {
95+
var buf bytes.Buffer
96+
97+
if _, err := buf.ReadFrom(in); err != nil {
98+
return "", fmt.Errorf("failed to read: %w", err)
99+
}
100+
101+
b := buf.Bytes()
102+
103+
seenfreqs := make(map[int]bool)
104+
105+
var (
106+
curfreq int
107+
loops int
108+
found bool
109+
)
110+
111+
for !found {
112+
if len(seenfreqs) == 0 {
113+
seenfreqs[curfreq] = true
114+
}
115+
116+
scanner := bufio.NewScanner(bytes.NewReader(b))
117+
118+
for scanner.Scan() {
119+
line := scanner.Text()
120+
121+
matches := re.FindStringSubmatch(line)
122+
123+
if len(matches) != totalmatches {
124+
return "", fmt.Errorf("wrong matches[%d] for line[%s], should be [%d]",
125+
len(matches), line, totalmatches)
126+
}
127+
128+
d, err := strconv.Atoi(matches[digits])
129+
if err != nil {
130+
return "", fmt.Errorf("strconv atoi: %w", err)
131+
}
132+
133+
switch matches[sign] {
134+
case "+":
135+
curfreq += d
136+
case "-":
137+
curfreq -= d
138+
}
139+
140+
if seenfreqs[curfreq] {
141+
found = true
142+
143+
break
144+
}
145+
146+
seenfreqs[curfreq] = true
147+
}
148+
149+
if err := scanner.Err(); err != nil {
150+
return "", fmt.Errorf("scanner error: %w", err)
151+
}
152+
153+
loops++
154+
}
155+
156+
return strconv.Itoa(curfreq), nil
40157
}

internal/puzzles/solutions/2018/day01/solution_test.go

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func Test_solution_Part1(t *testing.T) {
3232
year: "2018",
3333
},
3434
args: args{
35-
input: strings.NewReader("+1, +1, +1"),
35+
input: strings.NewReader("+1\n+1\n+1"),
3636
},
3737
want: "3",
3838
wantErr: false,
@@ -44,19 +44,19 @@ func Test_solution_Part1(t *testing.T) {
4444
year: "2018",
4545
},
4646
args: args{
47-
input: strings.NewReader("+1, +1, -2"),
47+
input: strings.NewReader("+1\n+1\n-2"),
4848
},
4949
want: "0",
5050
wantErr: false,
5151
},
5252
{
53-
name: "`1, -2, -3` results in `-6`",
53+
name: "`-1, -2, -3` results in `-6`",
5454
fields: fields{
5555
name: "day01",
5656
year: "2018",
5757
},
5858
args: args{
59-
input: strings.NewReader("1, -2, -3"),
59+
input: strings.NewReader("-1\n-2\n-3"),
6060
},
6161
want: "-6",
6262
wantErr: false,
@@ -67,9 +67,9 @@ func Test_solution_Part1(t *testing.T) {
6767
name: "",
6868
},
6969
args: args{
70-
input: strings.NewReader("+1, -2, +3, +1"),
70+
input: strings.NewReader("+1\n-2\n+3\n+1"),
7171
},
72-
want: "12",
72+
want: "3",
7373
wantErr: false,
7474
},
7575
}
@@ -113,16 +113,64 @@ func Test_solution_Part2(t *testing.T) {
113113
want string
114114
wantErr bool
115115
}{
116-
{ // TODO(@obalunenko): Fill the tests
117-
name: "",
116+
{
117+
name: "`+1, -2, +3, +1` results in `2`",
118+
fields: fields{
119+
name: "2018",
120+
year: "day01",
121+
},
122+
args: args{
123+
input: strings.NewReader("+1\n-2\n+3\n+1"),
124+
},
125+
want: "2",
126+
wantErr: false,
127+
},
128+
{
129+
name: "`+1, -1` first reaches `0` twice.",
130+
fields: fields{
131+
name: "2018",
132+
year: "day01",
133+
},
134+
args: args{
135+
input: strings.NewReader("+1\n-1"),
136+
},
137+
want: "0",
138+
wantErr: false,
139+
},
140+
{
141+
name: "`+3, +3, +4, -2, -4` first reaches `10` twice.",
142+
fields: fields{
143+
name: "2018",
144+
year: "day01",
145+
},
146+
args: args{
147+
input: strings.NewReader("+3\n+3\n+4\n-2\n-4"),
148+
},
149+
want: "10",
150+
wantErr: false,
151+
},
152+
{
153+
name: "`-6, +3, +8, +5, -6` first reaches `5` twice.",
154+
fields: fields{
155+
name: "2018",
156+
year: "day01",
157+
},
158+
args: args{
159+
input: strings.NewReader("-6\n+3\n+8\n+5\n-6"),
160+
},
161+
want: "5",
162+
wantErr: false,
163+
},
164+
{
165+
name: "`+7, +7, -2, -7, -4` first reaches `14` twice.",
118166
fields: fields{
119167
name: "2018",
120168
year: "day01",
121169
},
122170
args: args{
123-
input: strings.NewReader(""),
171+
input: strings.NewReader("+7\n+7\n-2\n-7\n-4"),
124172
},
125-
want: "",
173+
want: "14",
126174
wantErr: false,
127175
},
128176
}

internal/puzzles/solutions/2018/day01/spec.md

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# --- Day 1: Chronal Calibration ---
2+
3+
## --- Part One ---
4+
25
"We've detected some temporal anomalies," one of Santa's Elves at the Temporal Anomaly Research and Detection
36
Instrument Station tells you. She sounded pretty worried when she called you down here.
47
"At 500-year intervals into the past, someone has been changing Santa's history!"
@@ -34,10 +37,38 @@ then starting from a frequency of zero, the following changes would occur:
3437

3538
In this example, the resulting frequency is `3`.
3639

37-
## Here are other example situations:
40+
### Here are other example situations:
3841

3942
- `+1, +1, +1` results in `3`
4043
- `+1, +1, -2` results in `0`
4144
- `1, -2, -3` results in `-6`
4245

43-
Starting with a frequency of zero, what is the resulting frequency after all the changes in frequency have been applied?
46+
Starting with a frequency of zero, what is the resulting frequency after all the changes in frequency have been applied?
47+
48+
## --- Part Two ---
49+
50+
You notice that the device repeats the same frequency change list over and over.
51+
To calibrate the device, you need to find the first frequency it reaches twice.
52+
53+
For example, using the same list of changes above, the device would loop as follows:
54+
55+
- Current frequency `0`, change of `+1`; resulting frequency `1`.
56+
- Current frequency `1`, change of `-2`; resulting frequency `-1`.
57+
- Current frequency `-1`, change of `+3`; resulting frequency `2`.
58+
- Current frequency `2`, change of `+1`; resulting frequency `3`.
59+
`(At this point, the device continues from the start of the list.)`
60+
- Current frequency `3`, change of `+1`; resulting frequency `4`.
61+
- Current frequency `4`, change of `-2`; resulting frequency `2`, which has already been seen.
62+
63+
In this example, the first frequency reached twice is `2`.
64+
Note that your device might need to repeat its list of frequency changes many times before a duplicate frequency
65+
is found, and that duplicates might be found while in the middle of processing the list.
66+
67+
### Here are other examples:
68+
69+
- `+1, -1` first reaches `0` twice.
70+
- `+3, +3, +4, -2, -4` first reaches `10` twice.
71+
- `-6, +3, +8, +5, -6` first reaches `5` twice.
72+
- `+7, +7, -2, -7, -4` first reaches `14` twice.
73+
74+
What is the first frequency your device reaches twice?

0 commit comments

Comments
 (0)