Task: Ludic numbers



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


Go: package main

import "fmt"




func Ludic(n int, max int) []uint32 {
	const maxInt32 = 1<<31 - 1 
	if max > 0 && n < 0 {
		n = maxInt32
	}
	if n < 1 {
		return nil
	}
	if max < 0 {
		max = maxInt32
	}
	sieve := make([]uint32, 10760) 
	sieve[0] = 1
	sieve[1] = 2
	if n > 2 {
		
		for i, j := 2, uint32(3); i < len(sieve); i, j = i+1, j+2 {
			sieve[i] = j
		}
		
		
		for k := 2; k < n; k++ {
			l := int(sieve[k])
			if l >= max {
				n = k
				break
			}
			i := l
			l--
			
			last := k + i - 1
			for j := k + i + 1; j < len(sieve); i, j = i+1, j+1 {
				last = k + i
				sieve[last] = sieve[j]
				if i%l == 0 {
					j++
				}
			}
			
			if last < len(sieve)-1 {
				sieve = sieve[:last+1]
			}
		}
	}
	if n > len(sieve) {
		panic("program error") 
	}
	return sieve[:n]
}

func has(x []uint32, v uint32) bool {
	for i := 0; i < len(x) && x[i] <= v; i++ {
		if x[i] == v {
			return true
		}
	}
	return false
}

func main() {
	
	fmt.Println("First 25:", Ludic(25, -1))
	fmt.Println("Numner of Ludics below 1000:", len(Ludic(-1, 1000)))
	fmt.Println("Ludic 2000 to 2005:", Ludic(2005, -1)[1999:])

	fmt.Print("Tripples below 250:")
	x := Ludic(-1, 250)
	for i, v := range x[:len(x)-2] {
		if has(x[i+1:], v+2) && has(x[i+2:], v+6) {
			fmt.Printf(", (%d %d %d)", v, v+2, v+6)
		}
	}
	fmt.Println()
}