Task: Ludic numbers


C++: #include <vector>
#include <iostream>
using namespace std;

class ludic
{
public:
    void ludicList()
    {
        _list.push_back( 1 );

        vector<int> v;
        for( int x = 2; x < 22000; x++ )
            v.push_back( x );

        while( true )
        {
            vector<int>::iterator i = v.begin();
            int z = *i;
            _list.push_back( z );

            while( true )
            {
                i = v.erase( i );
                if( distance( i, v.end() ) <= z - 1 ) break;
                advance( i, z - 1 );
            }
            if( v.size() < 1 ) return;
        }
    }

    void show( int s, int e )
    {
        for( int x = s; x < e; x++ )
            cout << _list[x] << " ";
    }

    void findTriplets( int e )
    {
        int lu, x = 0;
        while( _list[x] < e )
        {
            lu = _list[x];
            if( inList( lu + 2 ) && inList( lu + 6 ) )
                cout << "(" << lu << " " << lu + 2 << " " << lu + 6 << ")\n";
            x++;
        }
    }

    int count( int e )
    {
        int x = 0, c = 0;
        while( _list[x++] <= 1000 ) c++;
        return c;
    }

private:
    bool inList( int lu )
    {
        for( int x = 0; x < 250; x++ )
            if( _list[x] == lu ) return true;
        return false;
    }

    vector<int> _list;
};

int main( int argc, char* argv[] )
{
    ludic l;
    l.ludicList();
    cout << "first 25 ludic numbers:" << "\n";
    l.show( 0, 25 );
    cout << "\n\nThere are " << l.count( 1000 ) << " ludic numbers <= 1000" << "\n";
    cout << "\n2000 to 2005'th ludic numbers:" << "\n";
    l.show( 1999, 2005 );
    cout << "\n\nall triplets of ludic numbers < 250:" << "\n";
    l.findTriplets( 250 );
    cout << "\n\n";
    return system( "pause" );
}


C#: using System;
using System.Linq;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("First 25 ludic numbers:");
        Console.WriteLine(string.Join(", ", LudicNumbers(150).Take(25)));
        Console.WriteLine();
        
        Console.WriteLine($"There are {LudicNumbers(1001).Count()} ludic numbers below 1000");
        Console.WriteLine();
        
        foreach (var ludic in LudicNumbers(22000).Skip(1999).Take(6)
                .Select((n, i) => $"#{i+2000} = {n}")) {
            Console.WriteLine(ludic);
        }
        Console.WriteLine();
        
        Console.WriteLine("Triplets below 250:");
        var queue = new Queue<int>(5);
        foreach (int x in LudicNumbers(255)) {
            if (queue.Count == 5) queue.Dequeue();
            queue.Enqueue(x);
            if (x - 6 < 250 && queue.Contains(x - 6) && queue.Contains(x - 4)) {
                Console.WriteLine($"{x-6}, {x-4}, {x}");
            }
        }
    }
    
    public static IEnumerable<int> LudicNumbers(int limit) {
        yield return 1;
        
        
        
        Entry[] values = Enumerable.Range(0, limit + 1).Select(n => new Entry(n)).ToArray();
        for (int i = 2; i < limit; i = values[i].Next) {
            yield return values[i].N;
            int start = i;
            while (start < limit) {
                Unlink(values, start);
                for (int step = 0; step < i && start < limit; step++)
                    start = values[start].Next;
            }
        }
    }
    
    static void Unlink(Entry[] values, int index) {
        values[values[index].Prev].Next = values[index].Next;
        values[values[index].Next].Prev = values[index].Prev;
    }
    
}

struct Entry
{
    public Entry(int n) : this() {
        N = n;
        Prev = n - 1;
        Next = n + 1;
    }
    
    public int N { get; }
    public int Prev { get; set; }
    public int Next { get; set; }
}