problemreductions/
config.rs1pub fn index_to_config(index: usize, num_variables: usize, num_flavors: usize) -> Vec<usize> {
7 let mut config = vec![0; num_variables];
8 let mut remaining = index;
9 for i in (0..num_variables).rev() {
10 config[i] = remaining % num_flavors;
11 remaining /= num_flavors;
12 }
13 config
14}
15
16pub fn config_to_index(config: &[usize], num_flavors: usize) -> usize {
20 let mut index = 0;
21 for &value in config {
22 index = index * num_flavors + value;
23 }
24 index
25}
26
27#[cfg(test)]
29pub(crate) fn config_to_bits(config: &[usize]) -> Vec<bool> {
30 config.iter().map(|&v| v != 0).collect()
31}
32
33#[cfg(test)]
35pub(crate) fn bits_to_config(bits: &[bool]) -> Vec<usize> {
36 bits.iter().map(|&b| if b { 1 } else { 0 }).collect()
37}
38
39pub struct DimsIterator {
43 dims: Vec<usize>,
44 current: Option<Vec<usize>>,
45 total_configs: usize,
46 current_index: usize,
47}
48
49impl DimsIterator {
50 pub fn new(dims: Vec<usize>) -> Self {
55 let total_configs = if dims.is_empty() {
56 1
58 } else {
59 dims.iter()
60 .copied()
61 .try_fold(
62 1usize,
63 |acc, d| {
64 if d == 0 {
65 None
66 } else {
67 acc.checked_mul(d)
68 }
69 },
70 )
71 .unwrap_or(0)
72 };
73 let current = if total_configs == 0 {
74 None
75 } else {
76 Some(vec![0; dims.len()])
77 };
78 Self {
79 dims,
80 current,
81 total_configs,
82 current_index: 0,
83 }
84 }
85
86 pub fn total(&self) -> usize {
88 self.total_configs
89 }
90}
91
92impl Iterator for DimsIterator {
93 type Item = Vec<usize>;
94
95 fn next(&mut self) -> Option<Self::Item> {
96 let current = self.current.take()?;
97 let result = current.clone();
98
99 let mut next = current;
101 let mut carry = true;
102 for i in (0..self.dims.len()).rev() {
103 if carry {
104 next[i] += 1;
105 if next[i] >= self.dims[i] {
106 next[i] = 0;
107 } else {
108 carry = false;
109 }
110 }
111 }
112
113 self.current_index += 1;
114 if self.current_index < self.total_configs {
115 self.current = Some(next);
116 }
117
118 Some(result)
119 }
120
121 fn size_hint(&self) -> (usize, Option<usize>) {
122 let remaining = self.total_configs - self.current_index;
123 (remaining, Some(remaining))
124 }
125}
126
127impl ExactSizeIterator for DimsIterator {}
128
129#[cfg(test)]
130#[path = "unit_tests/config.rs"]
131mod tests;