БлогNot. Последовательности Колакоски

Последовательности Колакоски

Последовательности Колакоски похожи на тайну зарождения жизни, то есть, просты ровно настолько, чтобы быть самогенерирующимися и неповторимыми.

"Вики" может покинуть нас, на всех страницах энциклопедии
"Вики" может покинуть нас, на всех страницах энциклопедии

Задача состояла в том, чтобы реализовать метод, вычисляющий следующее значение из последовательности Колакоски, порождённой заданным исходным множеством натуральных значений, а также сделать некую проверку длин серий, позволяющую ответить на вопрос, является ли полученная последовательность "настоящей Колакоски".

Консольное приложение на C++ проверялось в пустом проекте актуальной сборки Visual Studio 2019.

#include <iostream>
#include <vector>

using Sequence = std::vector<int>;

std::ostream& operator << (std::ostream& os, const Sequence& v) {
 //Вывод последовательности в поток
 os << "[ ";
 for (const auto& e : v) {
  std::cout << e;
  if (&e != &v.back()) std::cout << ", ";
 }
 os << "]";
 return os;
}

int next_in_cycle(const Sequence& s, size_t i) {
 return s[i % s.size()];
}

Sequence gen_kolakoski(const Sequence& s, int n) {
 //Генерация последовательности
 Sequence seq;
 for (size_t i = 0; seq.size() < n; ++i) {
  const int next = next_in_cycle(s, i);
  Sequence nv(i >= seq.size() ? next : seq[i], next);
  seq.insert(std::end(seq), std::begin(nv), std::end(nv));
 }
 return { std::begin(seq), std::begin(seq) + n };
}

bool is_possible_kolakoski(const Sequence& s) {
 //Проверка последовательности
 Sequence r;
 for (size_t i = 0; i < s.size();) {
  int count = 1;
  for (size_t j = i + 1; j < s.size(); ++j) {
   if (s[j] != s[i]) break;
   ++count;
  }
  r.push_back(count);
  i += count;
 }
 for (size_t i = 0; i < r.size(); ++i) if (r[i] != s[i]) return false;
 return true;
}

int main() {
 //Тесты и вывод результатов
 std::vector<Sequence> seqs = {
   { 1, 2 }, //1
   { 1, 3 }, //1
   { 1, 2, 3 }, //1
   { 1, 3, 2, 1 }, //0
   { 0, 1 } //0
 };
 for (const auto& s : seqs) {
  auto kol = gen_kolakoski(s, 100);
  std::cout << "Starting set: " << s << ": " << std::endl << "Kolakoski sequence: "
   << kol << std::endl << "Is it kolakoski? " << is_possible_kolakoski(kol) 
   << std::endl << std::endl;
 }
 return 0;
}

02.03.2022, 23:36 [797 просмотров]


теги: числа c++ алгоритм математика

К этой статье пока нет комментариев, Ваш будет первым