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
import (
"regexp"
"strings"
"unicode"
)
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
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
}

View File

@ -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)
})
}

View File

@ -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]
// 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
}
allCards = append(allCards, groups)
}
return n, nil
}
// 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
}
arr = append(arr, n)
}
return arr, 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 {