Task: Intersecting number wheels


C++: #include <initializer_list>
#include <iostream>
#include <map>
#include <vector>

struct Wheel {
private:
    std::vector<char> values;
    size_t index;

public:
    Wheel() : index(0) {
        
    }

    Wheel(std::initializer_list<char> data) : values(data), index(0) {
        
        if (values.size() < 1) {
            throw new std::runtime_error("Not enough elements");
        }
    }

    char front() {
        return values[index];
    }

    void popFront() {
        index = (index + 1) % values.size();
    }
};

struct NamedWheel {
private:
    std::map<char, Wheel> wheels;

public:
    void put(char c, Wheel w) {
        wheels[c] = w;
    }

    char front(char c) {
        char v = wheels[c].front();
        while ('A' <= v && v <= 'Z') {
            v = wheels[v].front();
        }
        return v;
    }

    void popFront(char c) {
        auto v = wheels[c].front();
        wheels[c].popFront();

        while ('A' <= v && v <= 'Z') {
            auto d = wheels[v].front();
            wheels[v].popFront();
            v = d;
        }
    }
};

void group1() {
    Wheel w({ '1', '2', '3' });
    for (size_t i = 0; i < 20; i++) {
        std::cout << ' ' << w.front();
        w.popFront();
    }
    std::cout << '\n';
}

void group2() {
    Wheel a({ '1', 'B', '2' });
    Wheel b({ '3', '4' });

    NamedWheel n;
    n.put('A', a);
    n.put('B', b);

    for (size_t i = 0; i < 20; i++) {
        std::cout << ' ' << n.front('A');
        n.popFront('A');
    }
    std::cout << '\n';
}

void group3() {
    Wheel a({ '1', 'D', 'D' });
    Wheel d({ '6', '7', '8' });

    NamedWheel n;
    n.put('A', a);
    n.put('D', d);

    for (size_t i = 0; i < 20; i++) {
        std::cout << ' ' << n.front('A');
        n.popFront('A');
    }
    std::cout << '\n';
}

void group4() {
    Wheel a({ '1', 'B', 'C' });
    Wheel b({ '3', '4' });
    Wheel c({ '5', 'B' });

    NamedWheel n;
    n.put('A', a);
    n.put('B', b);
    n.put('C', c);

    for (size_t i = 0; i < 20; i++) {
        std::cout << ' ' << n.front('A');
        n.popFront('A');
    }
    std::cout << '\n';
}

int main() {
    group1();
    group2();
    group3();
    group4();

    return 0;
}



Go: package main

import (
    "fmt"
    "sort"
    "strconv"
)

type wheel struct {
    next   int
    values []string
}

type wheelMap = map[string]wheel

func generate(wheels wheelMap, start string, maxCount int) {
    count := 0
    w := wheels[start]
    for {
        s := w.values[w.next]
        v, err := strconv.Atoi(s)
        w.next = (w.next + 1) % len(w.values)
        wheels[start] = w
        if err == nil {
            fmt.Printf("%d ", v)
            count++
            if count == maxCount {
                fmt.Println("...\n")
                return
            }
        } else {
            for {
                w2 := wheels[s]
                ss := s
                s = w2.values[w2.next]
                w2.next = (w2.next + 1) % len(w2.values)
                wheels[ss] = w2
                v, err = strconv.Atoi(s)
                if err == nil {
                    fmt.Printf("%d ", v)
                    count++
                    if count == maxCount {
                        fmt.Println("...\n")
                        return
                    }
                    break
                }
            }
        }
    }
}

func printWheels(wheels wheelMap) {
    var names []string
    for name := range wheels {
        names = append(names, name)
    }
    sort.Strings(names)
    fmt.Println("Intersecting Number Wheel group:")
    for _, name := range names {
        fmt.Printf("  %s: %v\n", name, wheels[name].values)
    }
    fmt.Print("  Generates:\n    ")
}

func main() {
    wheelMaps := []wheelMap{
        {
            "A": {0, []string{"1", "2", "3"}},
        },
        {
            "A": {0, []string{"1", "B", "2"}},
            "B": {0, []string{"3", "4"}},
        },
        {
            "A": {0, []string{"1", "D", "D"}},
            "D": {0, []string{"6", "7", "8"}},
        },
        {
            "A": {0, []string{"1", "B", "C"}},
            "B": {0, []string{"3", "4"}},
            "C": {0, []string{"5", "B"}},
        },
    }
    for _, wheels := range wheelMaps {
        printWheels(wheels)
        generate(wheels, "A", 20)
    }
}