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;
}



Go: package main

import "fmt"

func nextInCycle(c []int, index int) int {
    return c[index % len(c)]
}

func kolakoski(c []int, slen int) []int {
    s := make([]int, slen)
    i, k := 0, 0
    for {
        s[i] = nextInCycle(c, k)
        if s[k] > 1 {
            for j := 1; j < s[k]; j++ {
                i++
                if i == slen {
                    return s
                }
                s[i] = s[i - 1]
            }
        }
        i++
        if i == slen {
            return s
        }
        k++
    }
}

func possibleKolakoski(s []int) bool {
    slen := len(s)
    rle := make([]int, 0, slen)
    prev := s[0]
    count := 1
    for i := 1; i < slen; i++ {
        if s[i] == prev {
            count++
        } else {
            rle = append(rle, count)
            count = 1
            prev = s[i]
        }
    }
    
    for i := 0; i < len(rle); i++ {
        if rle[i] != s[i] {
            return false
        }
    }
    return true
}

func printInts(ia []int, suffix string) {
    fmt.Print("[")
    alen := len(ia)
    for i := 0; i < alen; i++ {
        fmt.Print(ia[i])
        if i < alen - 1 {
            fmt.Print(", ")
        }
    }
    fmt.Printf("]%s\n", suffix)
}

func main() {
    ias := make([][]int, 4)
    ias[0] = []int{1, 2}
    ias[1] = []int{2, 1}
    ias[2] = []int{1, 3, 1, 2}
    ias[3] = []int{1, 3, 2, 1}
    slens := []int{20, 20, 30, 30}
    for i, ia := range ias {
        slen := slens[i]
        kol := kolakoski(ia, slen)
        fmt.Printf("First %d members of the sequence generated by ", slen)
        printInts(ia, ":")
        printInts(kol, "")
        p := possibleKolakoski(kol)
        poss := "Yes"
        if !p {
            poss = "No"
        }
        fmt.Println("Possible Kolakoski sequence?", poss, "\n")
    }
}