Advertisement
asaelr

bottles2

May 10th, 2017
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.32 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdint>
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <random>
  6. #include <utility>
  7. #include <vector>
  8. #include <functional>
  9.  
  10. using namespace std;
  11.  
  12. const int N = 1000;
  13. typedef bool Rat[N];
  14. typedef pair<int,int> P;
  15.  
  16. const double p = 1-sqrt(0.5);
  17. void draw(Rat rat) {
  18.     static random_device rd;
  19.     static mt19937 gen(rd());
  20.     static bernoulli_distribution d(p);
  21.     for (int n=0;n<N;n++) rat[n] = d(gen);
  22. }
  23.  
  24. bool drink(Rat rat, P p) {
  25.     return rat[p.first] || rat[p.second];
  26. }
  27.  
  28. P pairs[N*(N-1)/2];
  29. vector<pair<P*,P*>> sets;
  30.  
  31. long count_remaining() {
  32.     long ret=0;
  33.     for (auto& s : sets) ret+=(s.second-s.first)*((s.second-s.first)-1)/2;
  34.     return ret;
  35. }
  36.  
  37. long count_solved(Rat rat) {
  38.     auto drinker = bind(drink,rat,placeholders::_1);
  39.     long ret=0;
  40.     for (auto& s : sets) {
  41.         long c=count_if(s.first,s.second,drinker);
  42.         ret+=c*((s.second-s.first)-c);
  43.     }
  44.     return ret;
  45. }
  46.  
  47. void split(Rat rat) {
  48.     auto drinker = bind(drink,rat,placeholders::_1);
  49.     vector<pair<P*,P*>> newSets;
  50.     for (auto& s : sets) {
  51.         P* mid = partition(s.first,s.second,drinker);
  52.         if (mid-s.first>1) newSets.push_back({s.first,mid});
  53.         if (s.second-mid>1) newSets.push_back({mid,s.second});
  54.     }
  55.     sets = newSets;
  56. }
  57.  
  58. Rat rats[100];
  59.  
  60. void init(int K=0) {
  61.     for (int t=0,i=0;i<N;i++) for (int j=0;j<i;j++) pairs[t++]=P{i,j};
  62.     sets.push_back({pairs,end(pairs)});
  63.    
  64.     for (int k=0;k<K;k++) split(rats[k]);
  65. }
  66.  
  67. int init_rats() { //some hand-written rats
  68.     for (int k=0,pow3=1;k<7;k++,pow3*=3) {
  69.         for (int n=0;n<N;n++) rats[k][n]=(n/pow3)%3==0;
  70.     }
  71.     for (int k=7,pow3=1;k<14;k++,pow3*=3) {
  72.         for (int n=0;n<N;n++) rats[k][n]=(n/pow3)%3==1;
  73.     }
  74.     for (int k=14,pow3=1;k<20;k++,pow3*=3) {
  75.         for (int n=0;n<N;n++) rats[k][n]=(n/pow3)%3==2;
  76.     }
  77.     return 20;
  78. }
  79.  
  80. void print(int K) {
  81.     for (int k=0;k<K;k++) {
  82.         for (int n=0;n<N;n++) cout<<(rats[k][n]?1:0);
  83.         cout<<endl;
  84.     }
  85. }
  86.  
  87. int main() {
  88.     int k=init_rats();
  89.     init(k);
  90.     long rem;
  91.     for (;(rem=count_remaining());k++) {
  92.         cout<<"looking for rat "<<k+1<<" with "<<rem<<" problems"<<endl;
  93.         long max=0;
  94.         Rat rat;
  95.         for (int i=0;i<1000;i++) {
  96.             draw(rat);
  97.             long s = count_solved(rat);
  98.             if (s>max) {
  99.                 max=s;
  100.                 for (int n=0;n<N;n++) rats[k][n]=rat[n];
  101.             }
  102.         }
  103.         cout<<"found a rat that can solve "<<max<<endl;
  104.         split(rats[k]);
  105.     }
  106.     print(k);
  107.     return 0;
  108. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement