Coverage for src/arcade_collection/input/group_template_conditions.py: 100%

50 statements  

« prev     ^ index     » next       coverage.py v7.1.0, created at 2024-12-09 19:07 +0000

1from itertools import groupby 

2 

3 

4def group_template_conditions(conditions: list[dict], max_seeds: int) -> list[dict]: 

5 """ 

6 Create conditions groups obeying specified max seeds for each group. 

7 

8 Parameters 

9 ---------- 

10 conditions 

11 List of conditions, containing a unique "key" and "seed". 

12 max_seeds 

13 Maximum number of total seeds in each group. 

14 

15 Returns 

16 ------- 

17 : 

18 List of condition groups. 

19 """ 

20 

21 grouped_conditions = group_seed_ranges(conditions, max_seeds) 

22 condition_sets = group_condition_sets(grouped_conditions, max_seeds) 

23 return [{"conditions": condition_set} for condition_set in condition_sets] 

24 

25 

26def group_seed_ranges(conditions: list[dict], max_seeds: int) -> list[dict]: 

27 """ 

28 Group conditions by continuous seed ranges. 

29 

30 Parameters 

31 ---------- 

32 conditions 

33 List of conditions, containing a unique "key" and "seed". 

34 max_seeds 

35 Maximum number of seeds in a single range. 

36 

37 Returns 

38 ------- 

39 : 

40 List of conditions updated with "start_seed" and "end_seed" ranges. 

41 """ 

42 

43 conditions.sort(key=lambda x: (x["key"], x["seed"])) 

44 grouped_conditions = [] 

45 

46 for _, condition_group in groupby(conditions, lambda x: x["key"]): 

47 key_seeds = [] 

48 key_conditions = {} 

49 

50 for condition in condition_group: 

51 key_seeds.append(condition["seed"]) 

52 key_conditions.update(condition) 

53 

54 key_conditions.pop("seed") 

55 seed_ranges = find_seed_ranges(key_seeds, max_seeds) 

56 

57 for range_start, range_end in seed_ranges: 

58 group_condition = key_conditions.copy() 

59 group_condition["start_seed"] = range_start 

60 group_condition["end_seed"] = range_end 

61 grouped_conditions.append(group_condition) 

62 

63 return grouped_conditions 

64 

65 

66def find_seed_ranges(seeds: list[int], max_seeds: int) -> list[tuple[int, int]]: 

67 """ 

68 Find continuous seed ranges, with range no larger than specified max seeds. 

69 

70 Parameters 

71 ---------- 

72 seeds 

73 List of seeds. 

74 max_seeds 

75 Maximum number of seeds in a single range. 

76 

77 Returns 

78 ------- 

79 : 

80 List of seeds grouped into ranges. 

81 """ 

82 

83 seeds.sort() 

84 ranges = [] 

85 

86 for _, group in groupby(enumerate(seeds), lambda x: x[0] - x[1]): 

87 group_list = list(group) 

88 subset = True 

89 range_start = group_list[0][1] 

90 range_end = group_list[-1][1] 

91 

92 while subset: 

93 ranges.append((range_start, min(range_end, range_start + max_seeds - 1))) 

94 range_start = range_start + max_seeds 

95 if range_start > range_end: 

96 subset = False 

97 

98 return ranges 

99 

100 

101def group_condition_sets(conditions: list[dict], max_seeds: int) -> list[list[dict]]: 

102 """ 

103 Group conditions, with total seeds no larger than specified max seeds. 

104 

105 Parameters 

106 ---------- 

107 conditions 

108 List of conditions, containing a unique "key" with "start_seed" and 

109 "end_seed" ranges. 

110 max_seeds 

111 Maximum number of seeds in a single group. 

112 

113 Returns 

114 ------- 

115 : 

116 List of groups of conditions. 

117 """ 

118 

119 seed_count = 0 

120 condition_set = [] 

121 condition_sets = [] 

122 

123 for condition in conditions: 

124 num_seeds = condition["end_seed"] - condition["start_seed"] + 1 

125 

126 if seed_count + num_seeds <= max_seeds: 

127 condition_set.append(condition) 

128 seed_count = seed_count + num_seeds 

129 else: 

130 condition_sets.append(condition_set) 

131 seed_count = num_seeds 

132 condition_set = [condition] 

133 

134 condition_sets.append(condition_set) 

135 

136 return condition_sets