1+ #include < stdexcept>
12#include < iostream>
23#include < numeric>
34#include < vector>
@@ -33,39 +34,66 @@ typedef std::vector<size_t>::const_iterator it;
3334class subelections {
3435 private:
3536 bool add_subelection (combo::it begin, combo::it end);
37+ size_t numcands;
3638
3739 public:
3840 std::vector<std::vector<size_t > > subelection_members;
39- std::vector<size_t > max_options;
40- subelections (size_t numcands);
41+ std::vector<std::vector<bool > > is_subelection_member;
42+
43+ std::vector<size_t > num_options;
44+ size_t distinct_fingerprints;
45+
46+ subelections (size_t numcands_in);
4147
4248 size_t get_num_fingerprint_indices () const ;
4349};
4450
4551bool subelections::add_subelection (combo::it begin, combo::it end) {
4652 subelection_members.push_back (std::vector<size_t >(begin, end));
4753 size_t num_members = end-begin;
48- max_options.push_back ((1 <<num_members) - 2 );
54+ num_options.push_back ((1 <<num_members) - 2 );
55+
56+ // Also add a vector where is_member[x] is true if the xth
57+ // candidate is a part of this subelection.
58+ std::vector<bool > is_member (numcands, false );
59+
60+ for (combo::it pos = begin; pos != end; ++pos) {
61+ is_member[*pos] = true ;
62+ }
4963
5064 return false ;
5165}
5266
53- subelections::subelections (size_t numcands) {
67+ subelections::subelections (size_t numcands_in) {
68+
69+ numcands = numcands_in;
70+
71+ size_t i;
5472
5573 // Curry the implicit reference to the calling object.
5674 auto this_add_subelection = [this ](combo::it begin,
5775 combo::it end) {
5876 return add_subelection (begin, end);
5977 };
6078
61- for (size_t i = 2 ; i <= numcands; ++i) {
79+ for (i = 2 ; i <= numcands; ++i) {
6280 // Add every sub-election of i candidates.
6381 std::vector<size_t > cands (numcands, 0 );
6482 std::iota (cands.begin (), cands.end (), 0 );
6583
6684 for_each_combination (cands.begin (), cands.begin () + i,
6785 cands.end (), this_add_subelection);
6886 }
87+
88+ // Calculate the number of distinct fingerprints
89+ // based on the number of subelections and the number
90+ // of ways candidates can be chosen within each.
91+
92+ distinct_fingerprints = 1 ;
93+
94+ for (i = 0 ; i < num_options.size (); ++i) {
95+ distinct_fingerprints *= num_options[i];
96+ }
6997}
7098
7199
@@ -80,15 +108,90 @@ class fingerprint {
80108 public:
81109 std::vector<std::vector<size_t > > above_quota;
82110
83- void decode (size_t index);
111+ void decode (const subelections & se, size_t index);
84112 size_t encode () const ;
113+ void print (const subelections & se) const ;
85114};
86115
87- int main ( ) {
116+ void fingerprint::decode ( const subelections & se, size_t index ) {
88117
89- size_t numcands = 3 ;
118+ if (index >= se.distinct_fingerprints ) {
119+ throw std::invalid_argument (" index exceeds number of fingerprints!" );
120+ }
121+
122+ for (size_t subelec_idx = 0 ; subelec_idx < se.num_options .size ();
123+ ++subelec_idx) {
124+ // Get the index to apply to this particular subelection.
125+ size_t num_options = se.num_options [subelec_idx];
126+ size_t digit = index % num_options;
127+
128+ // Then decode it.
129+ size_t num_members = se.subelection_members [subelec_idx].size ();
130+ std::vector<size_t > candidates_above_quota;
131+
132+ // Since at least one candidate must exceed the quota,
133+ // an index of zero, which would correspond to an all-false
134+ // vector, is disallowed.
135+ ++digit;
136+
137+ for (size_t member_idx = 0 ; member_idx < num_members; ++member_idx) {
138+ if (digit % 2 == 1 ) {
139+ candidates_above_quota.push_back (
140+ se.subelection_members [subelec_idx][member_idx]);
141+ }
142+ digit >>= 1 ;
143+ }
144+
145+ above_quota.push_back (candidates_above_quota);
146+
147+ std::cout << digit << " of " << num_options << " \n " ;
148+ index /= num_options;
149+ }
150+ }
90151
152+ void fingerprint::print (const subelections & se) const {
153+ size_t i;
154+
155+ for (size_t subelec_idx = 0 ; subelec_idx < se.num_options .size ();
156+ ++subelec_idx) {
157+
158+ std::cout << " Subelection {" ;
159+
160+ for (i = 0 ; i < se.subelection_members [subelec_idx].size ();
161+ ++i) {
162+ if (i != 0 ) {
163+ std::cout << " , " ;
164+ }
165+ std::cout << (char )(' A' + se.subelection_members [
166+ subelec_idx][i]);
167+ }
168+
169+ std::cout << " }: above quota: " ;
170+
171+ for (i = 0 ; i < above_quota[subelec_idx].size (); ++i) {
172+ if (i != 0 ) {
173+ std::cout << " , " ;
174+ }
175+
176+ std::cout << (char )(' A' + above_quota[subelec_idx][i]);
177+ }
178+
179+ std::cout << " \n " ;
180+ }
181+ }
182+
183+ int main () {
184+
185+ size_t numcands = 4 ;
91186 subelections se (numcands);
92187
188+ fingerprint test;
189+
190+ std::cout << " Number of distinct fingerprints: "
191+ << se.distinct_fingerprints << " \n " ;
192+
193+ test.decode (se, 19001 );
194+ test.print (se);
195+
93196 return 0 ;
94197}
0 commit comments