Browse Source

solve part2 and refactor

master
Alexander Avery 1 year ago
parent
commit
ebe18a802e
  1. 108
      day01.go
  2. 1000
      input/1-2
  3. 43
      main.go
  4. 37
      main_test.go

108
day01.go

@ -5,64 +5,94 @@ import (
"fmt" "fmt"
"io" "io"
"strconv" "strconv"
"strings"
"unicode" "unicode"
) )
type day01 struct { func linevalue(digits []rune) int {
str := fmt.Sprintf("%c%c", digits[0], digits[len(digits)-1])
value, _ := strconv.Atoi(str)
return value
} }
type buffer struct { func finddigits(line string) []rune {
first bool d := make([]rune, 0, 7)
d1 rune for len(line) > 0 {
if unicode.IsDigit(rune(line[0])) {
last bool d = append(d, rune(line[0]))
d2 rune
} }
line = line[1:]
func (b *buffer) value() (value uint64) { }
var d2 rune return d
if b.last {
d2 = b.d2
} else {
d2 = b.d1
} }
str := fmt.Sprintf("%c%c", b.d1, d2) func findtextdigits(line string) []rune {
value, _ = strconv.ParseUint(str, 10, 64) d := make([]rune, 0, 7)
for len(line) > 0 {
b.first, b.last = false, false if unicode.IsDigit(rune(line[0])) {
return d = append(d, rune(line[0]))
} }
func (b *buffer) record(digit rune) { if strings.HasPrefix(line, "one") {
if !b.first { d = append(d, '1')
b.d1 = digit line = line[3:]
b.first = true } else if strings.HasPrefix(line, "two") {
d = append(d, '2')
line = line[3:]
} else if strings.HasPrefix(line, "three") {
d = append(d, '3')
line = line[5:]
} else if strings.HasPrefix(line, "four") {
d = append(d, '4')
line = line[4:]
} else if strings.HasPrefix(line, "five") {
d = append(d, '5')
line = line[4:]
} else if strings.HasPrefix(line, "six") {
d = append(d, '6')
line = line[3:]
} else if strings.HasPrefix(line, "seven") {
d = append(d, '7')
line = line[5:]
} else if strings.HasPrefix(line, "eight") {
d = append(d, '8')
line = line[5:]
} else if strings.HasPrefix(line, "nine") {
d = append(d, '9')
line = line[4:]
} else { } else {
b.d2 = digit line = line[1:]
b.last = true }
} }
return d
} }
func (d day01) solve(r io.Reader) string { type day01 struct {
}
func (d day01) solve1(r io.Reader) string {
var ( var (
buffer buffer total int
total uint64 scanner = bufio.NewScanner(r)
buf = bufio.NewReader(r)
) )
for { for scanner.Scan() {
b, _, err := buf.ReadRune() digits := finddigits(scanner.Text())
if err != nil { total += linevalue(digits)
return fmt.Sprintf("%d", total+buffer.value())
} }
return fmt.Sprintf("%d", total)
if unicode.IsDigit(b) {
buffer.record(b)
} else if b == '\n' {
total += buffer.value()
} }
func (d day01) solve2(r io.Reader) (ans string) {
var (
total int
scanner = bufio.NewScanner(r)
)
for scanner.Scan() {
digits := findtextdigits(scanner.Text())
total += linevalue(digits)
} }
return fmt.Sprintf("%d", total)
} }

1000
input/1-2

File diff suppressed because it is too large

43
main.go

@ -6,12 +6,12 @@ import (
"io" "io"
"log" "log"
"os" "os"
"path/filepath"
"strconv" "strconv"
) )
type puzzle interface { type puzzle interface {
solve(r io.Reader) string solve1(r io.Reader) string
solve2(r io.Reader) string
} }
var ( var (
@ -24,34 +24,25 @@ var (
} }
) )
func init() { func inputs(day int) [2]io.Reader {
flag.Parse() inputs := [2]io.Reader{}
path1 := fmt.Sprintf("input/%d-1", day)
} path2 := fmt.Sprintf("input/%d-2", day)
func inputs(day int64) []io.Reader {
inputs := make([]io.Reader, 0, 2)
path := fmt.Sprintf("input/%d-[1-2]", day)
matches, err := filepath.Glob(path)
if err != nil {
log.Fatalf("matching puzzle input files: %s", err.Error())
}
fmt.Println(matches)
for _, match := range matches { f1, err := os.Open(path1)
f, err := os.Open(match)
if err == nil { if err == nil {
inputs = append(inputs, f) inputs[0] = f1
} }
f2, err := os.Open(path2)
if err == nil {
inputs[1] = f2
} }
return inputs return inputs
} }
func main() { func main() {
puzzleIndex, err := strconv.ParseInt(*day, 10, 32) flag.Parse()
puzzleIndex, err := strconv.Atoi(*day)
if err != nil { if err != nil {
log.Fatalf("invalid puzzle day: %s", *day) log.Fatalf("invalid puzzle day: %s", *day)
} }
@ -59,10 +50,6 @@ func main() {
puzzle := puzzles[puzzleIndex-1] puzzle := puzzles[puzzleIndex-1]
fmt.Fprintf(os.Stdout, "Day %d:\n", puzzleIndex) fmt.Fprintf(os.Stdout, "Solution 1:\n%s\n", puzzle.solve1(inputs[0]))
for i := range inputs { fmt.Fprintf(os.Stdout, "Solution 2:\n%s\n", puzzle.solve2(inputs[1]))
ans := puzzle.solve(inputs[i])
fmt.Fprintf(os.Stdout, "Solution %d:\n%s", i+1, ans)
}
fmt.Fprintln(os.Stdout)
} }

37
main_test.go

@ -0,0 +1,37 @@
package main
import (
"strings"
"testing"
)
func TestDay01(t *testing.T) {
ans1 := "142"
input1 := `1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet`
ans2 := "281"
input2 := `two1nine
eightwothree
abcone2threexyz
xtwone3four
4nineeightseven2
zoneight234
7pqrstsixteen`
puzzle := day01{}
res1 := puzzle.solve1(strings.NewReader(input1))
t.Logf("day 1 solution 1: %s", res1)
if res1 != ans1 {
t.Errorf("day 1 solution 1 = %s; wanted %s", res1, ans1)
}
res2 := puzzle.solve2(strings.NewReader(input2))
t.Logf("day 1 solution 2: %s", res2)
if res2 != ans2 {
t.Errorf("day 1 solution 2 = %s; wanted %s", res2, ans2)
}
}
Loading…
Cancel
Save