如何编写紧凑逻辑函数判断抽样卡牌是否符合指定连续rank规则?
问题:判断抽样卡牌的Rank是否符合特定连续规则
用户生成了包含分组标识(A/B/C)和Rank(2-11)的卡牌数据框,并随机抽取5张卡牌,R代码如下:
card <- data.frame( pack = rep(c("A","B","C"), 10), rank = rep(2:11, 3) ) # 查看卡牌数据框 card # 随机抽取5张 s <- card[sample(seq_len(nrow(card)), 5),] s
连续Rank规则定义
- 常规连续:5张卡牌的Rank为连续数值序列(如3、4、5、6、7)
- 特殊连续:仅允许两种跨2的连续组合:
- 2、3、4、5、6
- 8、9、10、11、2
- 注意:9、10、11、2、3不视为连续
用户希望编写一个逻辑函数,判断抽样的5张卡牌是否符合上述规则,避免枚举所有排列的繁琐方式。
解决方案
可以通过以下步骤简化判断逻辑,无需枚举所有排列:
- 提取抽样卡牌的Rank并去重排序(同一Rank重复出现时,无法构成5个连续序列)
- 单独判断唯一的跨2特殊连续情况
- 用数值特征判断常规连续序列
实现代码
is_consecutive <- function(sample_df) { # 提取rank并去重后排序 ranks <- sort(unique(sample_df$rank)) # 首先必须是5个不同的rank,否则直接返回FALSE if (length(ranks) != 5) return(FALSE) # 判断特殊跨2的连续情况:8、9、10、11、2 if (identical(ranks, c(2,8,9,10,11))) return(TRUE) # 判断常规连续序列:排序后最大减最小等于4,且相邻差值全为1 if (max(ranks) - min(ranks) == 4 && all(diff(ranks) == 1)) return(TRUE) # 其他情况均不符合规则 return(FALSE) }
函数说明
- 去重步骤:如果存在重复Rank,必然无法满足5个连续序列的要求,直接排除
- 特殊情况判断:排序后的Rank集合为
c(2,8,9,10,11),对应规则中的8、9、10、11、2组合 - 常规连续判断:5个连续数值的最大最小值差为4,且相邻数值差值均为1,确保无间隔,覆盖了2-6、3-7等所有常规连续序列
测试示例
# 符合规则的测试用例 test1 <- data.frame(rank = c(2,4,3,5,6)) is_consecutive(test1) # 返回TRUE test2 <- data.frame(rank = c(8,11,9,2,10)) is_consecutive(test2) # 返回TRUE test3 <- data.frame(rank = c(3,5,4,7,6)) is_consecutive(test3) # 返回TRUE # 不符合规则的测试用例 test4 <- data.frame(rank = c(9,10,11,2,3)) is_consecutive(test4) # 返回FALSE test5 <- data.frame(rank = c(2,2,3,4,5)) is_consecutive(test5) # 返回FALSE(存在重复Rank)
内容的提问来源于stack exchange,提问作者PowerPoint Trenton
相关产品推荐
相关产品推荐

