Task: Kolakoski sequence


C++: #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 << ", ";
  }
  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 },
    { 2, 1 },
    { 1, 3, 1, 2 },
    { 1, 3, 2, 1 }
  };
  for (const auto& s : seqs) {
    auto kol = gen_kolakoski(s, s.size() > 2 ? 30 : 20);
    std::cout << "Starting with: " << s << ": " << std::endl << "Kolakoski sequence: " 
      << kol << std::endl << "Possibly kolakoski? " << is_possible_kolakoski(kol) << std::endl;		
  }
  return 0;
}




Java: import java.util.Arrays;

public class Kolakoski {
    private static class Crutch {
        final int len;
        int[] s;
        int i;

        Crutch(int len) {
            this.len = len;
            s = new int[len];
            i = 0;
        }

        void repeat(int count) {
            for (int j = 0; j < count; j++) {
                if (++i == len) return;
                s[i] = s[i - 1];
            }
        }
    }

    private static int nextInCycle(final int[] self, int index) {
        return self[index % self.length];
    }

    private static int[] kolakoski(final int[] self, int len) {
        Crutch c = new Crutch(len);

        int k = 0;
        while (c.i < len) {
            c.s[c.i] = nextInCycle(self, k);
            if (c.s[k] > 1) {
                c.repeat(c.s[k] - 1);
            }
            if (++c.i == len) return c.s;
            k++;
        }
        return c.s;
    }

    private static boolean possibleKolakoski(final int[] self) {
        int[] rle = new int[self.length];
        int prev = self[0];
        int count = 1;
        int pos = 0;
        for (int i = 1; i < self.length; i++) {
            if (self[i] == prev) {
                count++;
            } else {
                rle[pos++] = count;
                count = 1;
                prev = self[i];
            }
        }
        
        for (int i = 0; i < pos; i++) {
            if (rle[i] != self[i]) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        int[][] ias = new int[][]{
            new int[]{1, 2},
            new int[]{2, 1},
            new int[]{1, 3, 1, 2},
            new int[]{1, 3, 2, 1}
        };
        int[] lens = new int[]{20, 20, 30, 30};

        for (int i=0; i<ias.length; i++) {
            int len = lens[i];
            int[] kol = kolakoski(ias[i], len);

            System.out.printf("First %d members of the sequence generated by %s: \n", len, Arrays.toString(ias[i]));
            System.out.printf("%s\n", Arrays.toString(kol));
            System.out.printf("Possible Kolakoski sequence? %s\n\n", possibleKolakoski(kol));
        }
    }
}