Skip to content

Commit

Permalink
refactor(puzzles): Dry for 2018/day01
Browse files Browse the repository at this point in the history
  • Loading branch information
obalunenko committed Nov 4, 2021
1 parent ecea98f commit 49d2482
Showing 1 changed file with 55 additions and 28 deletions.
83 changes: 55 additions & 28 deletions internal/puzzles/solutions/2018/day01/solution.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"regexp"
"strconv"
"sync"

"github.com/obalunenko/advent-of-code/internal/puzzles"
)
Expand Down Expand Up @@ -59,7 +60,7 @@ const (
func part1(in io.Reader) (string, error) {
scanner := bufio.NewScanner(in)

var curfreq int
fdevice := newDevice()

for scanner.Scan() {
line := scanner.Text()
Expand All @@ -69,19 +70,14 @@ func part1(in io.Reader) (string, error) {
return "", err
}

switch delta.sign {
case "+":
curfreq += delta.d
case "-":
curfreq -= delta.d
}
fdevice.Apply(delta)
}

if err := scanner.Err(); err != nil {
return "", fmt.Errorf("scanner error: %w", err)
}

return strconv.Itoa(curfreq), nil
return strconv.Itoa(fdevice.CurFreq()), nil
}

func part2(in io.Reader) (string, error) {
Expand All @@ -93,43 +89,31 @@ func part2(in io.Reader) (string, error) {

b := buf.Bytes()

seenfreqs := make(map[int]bool)

var (
curfreq int
loops int
found bool
loops int
found bool
)

for !found {
if len(seenfreqs) == 0 {
seenfreqs[curfreq] = true
}
fdevice := newDevice()

for !found {
scanner := bufio.NewScanner(bytes.NewReader(b))

for scanner.Scan() {
line := scanner.Text()

delta, err := getFreqDelta(line)
if err != nil {
return "", err
return "", fmt.Errorf("get frequency delta: %w", err)
}

switch delta.sign {
case "+":
curfreq += delta.d
case "-":
curfreq -= delta.d
}
fdevice.Apply(delta)

if seenfreqs[curfreq] {
if fdevice.SeenFreq(fdevice.CurFreq()) {
found = true

break
}

seenfreqs[curfreq] = true
}

if err := scanner.Err(); err != nil {
Expand All @@ -139,7 +123,50 @@ func part2(in io.Reader) (string, error) {
loops++
}

return strconv.Itoa(curfreq), nil
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 {
Expand Down

0 comments on commit 49d2482

Please sign in to comment.