use strings.FieldFunc

remove regex and parsing functions

upd compare test
This commit is contained in:
onyx-and-iris 2023-12-04 18:45:30 +00:00
parent 8aa073b5ad
commit f3985498ce
3 changed files with 55 additions and 71 deletions

View File

@ -1,53 +1,29 @@
package main package main
import ( import (
"regexp" "strings"
"unicode"
) )
type M map[string]interface{} type M map[string]interface{}
var allCards []M
var _regex_winning_numbers = regexp.MustCompile(
`^Card (?P<card>[\s\d]+):\s` +
`(?P<winning>[0-9\s]+)\s` +
`\|\s` +
`(?P<mynums>[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 // one computes points based on matching numbers
func one(lines []string) (int, error) { 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 sum := 0
for x, card := range allCards { cards = make([]Card, len(lines))
m, err := compareLists(card["winning"].(string), card["mynums"].(string)) 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 { if err != nil {
return 0, err return 0, err
} }

View File

@ -1,25 +1,45 @@
package main package main
import ( import (
"strings"
"testing" "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.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") input := []string{
assert.Equal(t, 4, res) "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) { t.Run("Should return 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, res2)
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)
}) })
} }

View File

@ -5,7 +5,6 @@ import (
"log" "log"
"math" "math"
"os" "os"
"strconv"
) )
// readlines reads lines from stdin. // readlines reads lines from stdin.
@ -25,29 +24,18 @@ func readlines() []string {
return lines return lines
} }
func parseAllCards(line string) { // compare returns the number of matching elements
groups := M{} func compare(a []string, b []string) (int, error) {
res := _regex_winning_numbers.FindStringSubmatch(line) n := 0
names := _regex_winning_numbers.SubexpNames() for _, elem := range a {
for i := range res { if contains(b, elem) {
groups[names[i]] = res[i] n += 1
} }
allCards = append(allCards, groups) }
return n, nil
} }
// numStrToArr converts a string of numbers or an array of numbers // contains returns true if a slice of elements contains a given element
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
}
arr = append(arr, n)
}
return arr, nil
}
// contains returns true if an slice of elements contains a given element
func contains[T comparable](elems []T, v T) bool { func contains[T comparable](elems []T, v T) bool {
for _, s := range elems { for _, s := range elems {
if v == s { if v == s {