diff --git a/day-4/one.go b/day-4/one.go index d2299ec..064492e 100644 --- a/day-4/one.go +++ b/day-4/one.go @@ -1,53 +1,29 @@ package main import ( - "regexp" + "strings" + "unicode" ) type M map[string]interface{} -var allCards []M - -var _regex_winning_numbers = regexp.MustCompile( - `^Card (?P[\s\d]+):\s` + - `(?P[0-9\s]+)\s` + - `\|\s` + - `(?P[0-9\s]+)$`) - -var _regex_nums = regexp.MustCompile("[0-9]+") - -// compareLists returns the number of matching elements between winning and mynums -func compareLists(winningStr string, mynumsStr string) (int, error) { - x, err := numStrToArr(winningStr, []int{}) - if err != nil { - return 0, err - } - winning := x - x, err = numStrToArr(mynumsStr, []int{}) - if err != nil { - return 0, err - } - mynums := x - - n := 0 - for _, num := range mynums { - if contains(winning, num) { - n += 1 - } - } - return n, nil -} - // one computes points based on matching numbers func one(lines []string) (int, error) { - for _, line := range lines { - parseAllCards(line) + + f := func(c rune) bool { + return !unicode.IsDigit(c) } - cards = make([]Card, len(lines)) sum := 0 - for x, card := range allCards { - m, err := compareLists(card["winning"].(string), card["mynums"].(string)) + cards = make([]Card, len(lines)) + for x, line := range lines { + winning, mynums := func() (string, string) { + y := strings.Split(line, ":") + z := strings.Split(y[1], "|") + return z[0], z[1] + }() + + m, err := compare(strings.FieldsFunc(winning, f), strings.FieldsFunc(mynums, f)) if err != nil { return 0, err } diff --git a/day-4/one_test.go b/day-4/one_test.go index 0eab921..45b4b0f 100644 --- a/day-4/one_test.go +++ b/day-4/one_test.go @@ -1,25 +1,45 @@ package main import ( + "strings" "testing" + "unicode" - "github.com/go-playground/assert/v2" + "github.com/go-playground/assert" ) -func TestCompareLists(t *testing.T) { +func TestCompare(t *testing.T) { //t.Skip("skipping test") - t.Run("Should find 4 matches", func(t *testing.T) { - res, _ := compareLists("41 48 83 86 17", "83 86 6 31 17 9 48 53") - assert.Equal(t, 4, res) + + input := []string{ + "Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53", + "Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19", + } + + winning1, mynums1 := func() (string, string) { + y := strings.Split(input[0], ":") + z := strings.Split(y[1], "|") + return z[0], z[1] + }() + + winning2, mynums2 := func() (string, string) { + y := strings.Split(input[1], ":") + z := strings.Split(y[1], "|") + return z[0], z[1] + }() + + f := func(c rune) bool { + return !unicode.IsDigit(c) + } + + res1, _ := compare(strings.FieldsFunc(winning1, f), strings.FieldsFunc(mynums1, f)) + res2, _ := compare(strings.FieldsFunc(winning2, f), strings.FieldsFunc(mynums2, f)) + + t.Run("Should return 4 matches", func(t *testing.T) { + assert.Equal(t, 4, res1) }) - t.Run("Should find 2 matches", func(t *testing.T) { - res, _ := compareLists(" 1 21 53 59 44 ", "69 82 63 72 16 21 14 1") - assert.Equal(t, 2, res) - }) - - t.Run("Should find 0 matches", func(t *testing.T) { - res, _ := compareLists("87 83 26 28 32", "88 30 70 12 93 22 82 36") - assert.Equal(t, 0, res) + t.Run("Should return 2 matches", func(t *testing.T) { + assert.Equal(t, 2, res2) }) } diff --git a/day-4/util.go b/day-4/util.go index 29fbc79..f2d7180 100644 --- a/day-4/util.go +++ b/day-4/util.go @@ -5,7 +5,6 @@ import ( "log" "math" "os" - "strconv" ) // readlines reads lines from stdin. @@ -25,29 +24,18 @@ func readlines() []string { return lines } -func parseAllCards(line string) { - groups := M{} - res := _regex_winning_numbers.FindStringSubmatch(line) - names := _regex_winning_numbers.SubexpNames() - for i := range res { - groups[names[i]] = res[i] - } - allCards = append(allCards, groups) -} - -// numStrToArr converts a string of numbers or an array of numbers -func numStrToArr(nums string, arr []int) ([]int, error) { - for _, num := range _regex_nums.FindAllString(nums, -1) { - n, err := strconv.Atoi(num) - if err != nil { - return []int{}, err +// compare returns the number of matching elements +func compare(a []string, b []string) (int, error) { + n := 0 + for _, elem := range a { + if contains(b, elem) { + n += 1 } - arr = append(arr, n) } - return arr, nil + return n, nil } -// contains returns true if an slice of elements contains a given element +// contains returns true if a slice of elements contains a given element func contains[T comparable](elems []T, v T) bool { for _, s := range elems { if v == s {