int main(){
    
    const int N = 26;

    std::string a; getline(std::cin, a);
    std::string b; getline(std::cin, b);
    std::string c; getline(std::cin, c);

    std::vector<size_t> acount(N, 0);
    for(size_t p = 0; p < a.size(); p++){++acount[a[p] - 'a'];}

    std::vector<size_t> bcount(N, 0);
    for(size_t p = 0; p < b.size(); p++){++bcount[b[p] - 'a'];}

    std::vector<size_t> ccount(N, 0);
    for(size_t p = 0; p < c.size(); p++){++ccount[c[p] - 'a'];}

    long maxB(a.size());
    for(size_t p = 0; p < N; p++){if(bcount[p] > 0 && (acount[p] / bcount[p]) < maxB){maxB = (acount[p] / bcount[p]);}}

    long maxSum(maxB), optB(maxB), optC(0);
    for(size_t b = 0; b <= maxB; b++){
        size_t candC(a.size());
        for(size_t p = 0; p < N; p++){if(ccount[p] > 0 && ((acount[p] - b * bcount[p])/ ccount[p]) < candC){candC = (acount[p] - b * bcount[p])/ccount[p];}}
        if(b + candC > maxSum){maxSum = b + candC; optB = b; optC = candC;}
    }

    for(int p = 0; p < optB; p++){std::cout << b;}
    for(int p = 0; p < optC; p++){std::cout << c;}
    for(int p = 0; p < N; p++){
        size_t rem = acount[p] - optB * bcount[p] - optC * ccount[p];
        while(rem--){std::cout << char('a' + p);}
    }
    std::cout << std::endl;

    return 0;
}
Beispiel #2
0
  /** 
   * calc distance between two items.
   * Let a be all the users rated item 1
   * Let b be all the users rated item 2
   * Let intersection (a,b) be the number of users rated both items
   * Let size(a) be the number of users rated item 1
   * Let size(b) be the number of users rated item 2
   * 
   * Only for prob similarity:
   * Let M be the total number of users
   * Let N be the total number of iterms
   * Let L be the total number of training ratings
   *
   * 0) Using Jackard index:
   *      Dist_12 = intersection(a,b) / (size(a) + size(b) - size(intersection(a,b))
   *
   * 1) Using AA index:
   *      Dist_12 = sum_user k in intersection(a,b) [ 1 / log(degree(k)) ] 
   *
   * 2) Using RA index:
   *      Dist_12 = sum_user k in intersection(a,b) [ 1 / degree(k) ] 
   *
   * 3) Using Asym Cosine:
   *      Dist_12 = intersection(a,b) / size(a)^alpha * size(b)^(1-alpha)
   * 
   * 4) Using prob similarity:
   *      Dist_12 = intersection(a,b) / [ sum(user k  in b) p(k,1) ]
   *      where p(k,1) = 1 / [ 1 + (L / (MN-L)) ((N - degree(k))/degree(K)) * ((M - degree(1)) / degree(1)) ]
   *                                    
   */
  double calc_distance(graphchi_vertex<uint32_t, uint32_t> &v, vid_t pivot, int distance_metric) {
    //assert(is_pivot(pivot));
    //assert(is_item(pivot) && is_item(v.id()));
    dense_adj &pivot_edges = adjs[pivot - pivot_st];
    int num_edges = v.num_edges();
    //if there are not enough neighboring user nodes to those two items there is no need
    //to actually count the intersection
    if (num_edges < min_allowed_intersection || pivot_edges.count < min_allowed_intersection)
      return 0;

    std::vector<vid_t> edges;
    edges.resize(num_edges);
    for(int i=0; i < num_edges; i++) {
      vid_t other_vertex = v.edge(i)->vertexid;
      edges[i] = other_vertex;
    }
    sort(edges.begin(), edges.end());
    
    std::set<vid_t> intersection;
    std::set_intersection(
        pivot_edges.adjlist, pivot_edges.adjlist + pivot_edges.count, 
        edges.begin(), edges.end(), 
        std::inserter(intersection, intersection.begin()));
      
    double intersection_size = (double)intersection.size();
    //not enough user nodes rated both items, so the pairs of items are not compared.
    if (intersection_size < (double)min_allowed_intersection)
        return 0;
  
    if (distance_metric == JACCARD){
      uint set_a_size = v.num_edges(); //number of users connected to current item
      uint set_b_size = acount(pivot); //number of users connected to current pivot
      return intersection_size / (double)(set_a_size + set_b_size - intersection_size); //compute the distance
    }
    else if (distance_metric == AA){
       double dist = 0;
       for (std::set<vid_t>::iterator i= intersection.begin() ; i != intersection.end(); i++){
         vid_t user = *i;
         assert(latent_factors_inmem.size() == M && is_user(user));
         assert(latent_factors_inmem[user].degree > 0);
         dist += 1.0 / log(latent_factors_inmem[user].degree);
       }
       return dist;
    }
    else if (distance_metric == RA){
       double dist = 0;
       for (std::set<vid_t>::iterator i= intersection.begin() ; i != intersection.end(); i++){
         vid_t user = *i;
         assert(latent_factors_inmem.size() == M && is_user(user));
         assert(latent_factors_inmem[user].degree > 0);
         dist += 1.0 / latent_factors_inmem[user].degree;
       }
       return dist;
    }
  /* 3) Using Asym Cosine:
   *      Dist_12 = intersection(a,b) / size(a)^alpha * size(b)^(1-alpha)
   */
     else if (distance_metric == ASYM_COSINE){
      uint set_a_size = v.num_edges(); //number of users connected to current item
      uint set_b_size = acount(pivot); //number of users connected to current pivot
      return intersection_size / (pow(set_a_size,asym_cosine_alpha) * pow(set_b_size,1-asym_cosine_alpha));
    }
    /* 4) Using prob similarity:
    *      Dist_12 = intersection(a,b) / [ sum(user k  in b) p(k,1) ]
    *      where p(k,1) = 1 / [ 1 + (L / (MN-L)) ((N - degree(k))/degree(K)) * ((M - degree(1)) / degree(1)) ]
    */
     else if (distance_metric == PROB){
      double sum = 0;
      for(int i=0; i<pivot_edges.count; i++) {
        int node_k = pivot_edges.adjlist[i];
        int degree_k = latent_factors_inmem[node_k].degree;
        assert(degree_k > 0);
        double p_k_1 = 1.0 / ( 1.0 + prob_sim_normalization_constant * ((N - degree_k)/(double)degree_k) * ((M - num_edges) / (double)num_edges));
        assert(p_k_1 > 0 && p_k_1 <= 1.0);
        sum += p_k_1;
      }
      return intersection_size / sum;
   }
   else { 
     assert(false);
   }

   return -1; //just to avoid warning
  }
Beispiel #3
0
  /** 
   * calc distance between two items.
   * Let a be all the users rated item 1
   * Let b be all the users rated item 2
   *
   * 1) Using Jackard index:
   *      Dist_ab = intersection(a,b) / (size(a) + size(b) - size(intersection(a,b))
   *
   * 2) Using AA index:
   *      Dist_ab = sum_user k in intersection(a,b) [ 1 / log(degree(k)) ] 
   *
   * 3) Using RA index:
   *      Dist_ab = sum_user k in intersection(a,b) [ 1 / degree(k) ] 
   *
   * 4) Using Asym Cosine:
   *      Dist_ab = intersection(a,b) / size(a)^alpha * size(b)^(1-alpha)
   */
  double calc_distance(graphchi_vertex<uint32_t, uint32_t> &v, vid_t pivot, int distance_metric) {
    //assert(is_pivot(pivot));
    //assert(is_item(pivot) && is_item(v.id()));
    dense_adj &pivot_edges = adjs[pivot - pivot_st];
    int num_edges = v.num_edges();
    //if there are not enough neighboring user nodes to those two items there is no need
    //to actually count the intersection
    if (num_edges < min_allowed_intersection || pivot_edges.count < min_allowed_intersection)
      return 0;

    std::vector<vid_t> edges;
    edges.resize(num_edges);
    for(int i=0; i < num_edges; i++) {
      vid_t other_vertex = v.edge(i)->vertexid;
      edges[i] = other_vertex;
    }
    sort(edges.begin(), edges.end());
    
    std::set<vid_t> intersection;
    std::set_intersection(
        pivot_edges.adjlist, pivot_edges.adjlist + pivot_edges.count, 
        edges.begin(), edges.end(), 
        std::inserter(intersection, intersection.begin()));
      
    double intersection_size = (double)intersection.size();
    //not enough user nodes rated both items, so the pairs of items are not compared.
    if (intersection_size < (double)min_allowed_intersection)
        return 0;
  
    if (distance_metric == JACCARD){
      uint set_a_size = v.num_edges(); //number of users connected to current item
      uint set_b_size = acount(pivot); //number of users connected to current pivot
      return intersection_size / (double)(set_a_size + set_b_size - intersection_size); //compute the distance
    }
    else if (distance_metric == AA){
       double dist = 0;
       for (std::set<vid_t>::iterator i= intersection.begin() ; i != intersection.end(); i++){
         vid_t user = *i;
         assert(latent_factors_inmem.size() == M && is_user(user));
         assert(latent_factors_inmem[user].degree > 0);
         dist += 1.0 / log(latent_factors_inmem[user].degree);
       }
       return dist;
    }
    else if (distance_metric == RA){
       double dist = 0;
       for (std::set<vid_t>::iterator i= intersection.begin() ; i != intersection.end(); i++){
         vid_t user = *i;
         assert(latent_factors_inmem.size() == M && is_user(user));
         assert(latent_factors_inmem[user].degree > 0);
         dist += 1.0 / latent_factors_inmem[user].degree;
       }
       return dist;
    }
    else if (distance_metric == ASYM_COSINE){
      uint set_a_size = v.num_edges(); //number of users connected to current item
      uint set_b_size = acount(pivot); //number of users connected to current pivot
      return intersection_size / (pow(set_a_size,asym_cosine_alpha) * pow(set_b_size,1-asym_cosine_alpha));
    }

    return 0;
  }