summary refs log tree commit diff stats
path: root/designer.cpp
blob: 024796f6367605febbc8078c6479a92523958ee6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include "designer.h"

std::list<usage> designer::generate(std::mt19937& rng) const {
  std::list<usage> result;
  size_t cur = 0;

  while (cur < text_.length()) {
    const solution& curSol = get(cur);
    const std::vector<size_t>& posLens = curSol.lengths;

    std::uniform_int_distribution<size_t> lenDist(0, posLens.size() - 1);
    size_t len = posLens.at(lenDist(rng));

    const ps_type& prefix = curSol.prefix;
    std::uniform_int_distribution<size_t> cardDist(0, prefix.getCount() - 1);
    size_t cardIndex = cardDist(rng);
    std::tuple<size_t, size_t> pd = prefix.at(cardIndex);

    result.emplace_back(std::get<0>(pd), std::get<1>(pd), len);

    cur += len;
  }

  return result;
}

solution designer::calculate(size_t i) const {
  if (i == text_.length()) {
    return {titles_, {}, 0};
  }

  const ps_type& prefix = titles_.find(text_, i);

  bool foundScore = false;
  size_t bestScore;
  std::vector<size_t> bestLens;

  for (int j = 1; (j <= prefix.getDepth()) && (i + j <= text_.length()); j++) {
    const solution& subSol = get(i + j);

    if (subSol.score > 0 || (i + j == text_.length())) {
      size_t tempScore = subSol.score + 1;

      if (!foundScore || tempScore < bestScore) {
        foundScore = true;
        bestScore = tempScore;

        bestLens.clear();
        bestLens.push_back(j);
      } else if (tempScore == bestScore) {
        bestLens.push_back(j);
      }
    }
  }

  if (!foundScore) {
    return {titles_, {}, 0};
  } else {
    return {prefix, std::move(bestLens), bestScore};
  }
}

const solution& designer::get(size_t i) const {
  if (!solutions_.at(i)) {
    solutions_[i] = std::make_unique<solution>(calculate(i));
  }

  return *solutions_.at(i);
}