vRp.CD2g_test/utils/combination/validator_options.go

267 lines
8.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package combination
import (
"github.com/kercylan98/minotaur/utils/generic"
"github.com/kercylan98/minotaur/utils/maths"
)
type ValidatorOption[T Item] func(validator *Validator[T])
// WithValidatorHandle 通过特定的验证函数对组合进行验证
func WithValidatorHandle[T Item](handle func(items []T) bool) ValidatorOption[T] {
return func(validator *Validator[T]) {
validator.vh = append(validator.vh, handle)
}
}
// WithValidatorHandleLength 校验组合的长度是否符合要求
func WithValidatorHandleLength[T Item](length int) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
return len(items) == length
})
}
// WithValidatorHandleLengthRange 校验组合的长度是否在指定的范围内
func WithValidatorHandleLengthRange[T Item](min, max int) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
return len(items) >= min && len(items) <= max
})
}
// WithValidatorHandleLengthMin 校验组合的长度是否大于等于指定的最小值
func WithValidatorHandleLengthMin[T Item](min int) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
return len(items) >= min
})
}
// WithValidatorHandleLengthMax 校验组合的长度是否小于等于指定的最大值
func WithValidatorHandleLengthMax[T Item](max int) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
return len(items) <= max
})
}
// WithValidatorHandleLengthNot 校验组合的长度是否不等于指定的值
func WithValidatorHandleLengthNot[T Item](length int) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
return len(items) != length
})
}
// WithValidatorHandleTypeLength 校验组合成员类型数量是否为指定的值
func WithValidatorHandleTypeLength[T Item, E generic.Ordered](length int, getType func(item T) E) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
var types = make(map[E]bool)
for _, item := range items {
types[getType(item)] = true
if len(types) > length {
return false
}
}
return len(items) == length
})
}
// WithValidatorHandleTypeLengthRange 校验组合成员类型数量是否在指定的范围内
func WithValidatorHandleTypeLengthRange[T Item, E generic.Ordered](min, max int, getType func(item T) E) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
var types = make(map[E]bool)
for _, item := range items {
types[getType(item)] = true
if len(types) > max {
return false
}
}
return len(types) >= min && len(types) <= max
})
}
// WithValidatorHandleTypeLengthMin 校验组合成员类型数量是否大于等于指定的最小值
func WithValidatorHandleTypeLengthMin[T Item, E generic.Ordered](min int, getType func(item T) E) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
var types = make(map[E]bool)
for _, item := range items {
types[getType(item)] = true
if len(types) > min {
return false
}
}
return len(types) >= min
})
}
// WithValidatorHandleTypeLengthMax 校验组合成员类型数量是否小于等于指定的最大值
func WithValidatorHandleTypeLengthMax[T Item, E generic.Ordered](max int, getType func(item T) E) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
var types = make(map[E]bool)
for _, item := range items {
types[getType(item)] = true
if len(types) > max {
return false
}
}
return len(types) <= max
})
}
// WithValidatorHandleTypeLengthNot 校验组合成员类型数量是否不等于指定的值
func WithValidatorHandleTypeLengthNot[T Item, E generic.Ordered](length int, getType func(item T) E) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
var types = make(map[E]bool)
for _, item := range items {
types[getType(item)] = true
if len(types) > length {
return false
}
}
return len(types) != length
})
}
// WithValidatorHandleContinuous 校验组合成员是否连续
func WithValidatorHandleContinuous[T Item, Index generic.Integer](getIndex func(item T) Index) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
index := make([]Index, len(items))
for i, item := range items {
index[i] = getIndex(item)
}
return maths.IsContinuityWithSort(index)
})
}
// WithValidatorHandleContinuousNot 校验组合成员是否不连续
func WithValidatorHandleContinuousNot[T Item, Index generic.Integer](getIndex func(item T) Index) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
index := make([]Index, len(items))
for i, item := range items {
index[i] = getIndex(item)
}
return !maths.IsContinuityWithSort(index)
})
}
// WithValidatorHandleGroupContinuous 校验组合成员是否能够按类型分组并且连续
func WithValidatorHandleGroupContinuous[T Item, E generic.Ordered, Index generic.Integer](getType func(item T) E, getIndex func(item T) Index) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
var types = make(map[E]int)
var index = make([]Index, len(types))
for _, item := range items {
e := getType(item)
types[e]++
if types[e] == 1 {
index = append(index, getIndex(item))
}
}
var n = -1
for _, i := range types {
if n == -1 {
n = i
} else if n != i {
return false
}
}
return maths.IsContinuityWithSort(index)
})
}
// WithValidatorHandleGroupContinuousN 校验组合成员是否能够按分组为 n 组类型并且连续
func WithValidatorHandleGroupContinuousN[T Item, E generic.Ordered, Index generic.Integer](n int, getType func(item T) E, getIndex func(item T) Index) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
var types = make(map[E]int)
var index = make([]Index, len(types))
for _, item := range items {
e := getType(item)
types[e]++
if types[e] == 1 {
index = append(index, getIndex(item))
}
}
if n != len(types) {
return false
}
var n = -1
for _, i := range types {
if n == -1 {
n = i
} else if n != i {
return false
}
}
return maths.IsContinuityWithSort(index)
})
}
// WithValidatorHandleNCarryM 校验组合成员是否匹配 N 携带相同的 M 的组合
// - n: 组合中元素的数量表示需要匹配的组合数量n 的类型需要全部相同
// - m: 组合中元素的数量表示需要匹配的组合数量m 的类型需要全部相同
// - getType: 用于获取组合中元素的类型,用于判断是否相同
func WithValidatorHandleNCarryM[T Item, E generic.Ordered](n, m int, getType func(item T) E) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
if len(items) != n+m {
return false // 总数量不符合 n + m
}
typeCount := make(map[E]int)
for _, item := range items {
t := getType(item)
typeCount[t]++
}
if len(typeCount) != 2 {
return false
}
foundN := false
foundM := false
for _, count := range typeCount {
if count == n {
foundN = true
} else if count == m {
foundM = true
}
}
return foundN && foundM
})
}
// WithValidatorHandleNCarryIndependentM 校验组合成员是否匹配 N 携带独立的 M 的组合
// - n: 组合中元素的数量表示需要匹配的组合数量n 的类型需要全部相同
// - m: 组合中元素的数量表示需要匹配的组合数量m 的类型无需全部相同
// - getType: 用于获取组合中元素的类型,用于判断是否相同
func WithValidatorHandleNCarryIndependentM[T Item, E generic.Ordered](n, m int, getType func(item T) E) ValidatorOption[T] {
return WithValidatorHandle[T](func(items []T) bool {
if len(items) != n+m {
return false // 总数量不符合 n + m
}
typeCount := make(map[E]int)
for _, item := range items {
t := getType(item)
typeCount[t]++
}
// 检查是否有 n 个相同类型的元素
foundN := false
for _, count := range typeCount {
if count == n {
foundN = true
break
}
}
if !foundN {
return false // 没有找到 n 个相同类型的元素
}
// 检查剩余的元素数量是否为 m
remaining := len(items) - n
if remaining != m {
return false // 剩余元素数量不为 m
}
return true // 符合 N 带 M 的条件
})
}