Task: Ludic numbers

C: #include <stdio.h>
#include <stdlib.h>

typedef unsigned uint;
typedef struct { uint i, v; } filt_t;


uint* ludic(uint min_len, uint min_val, uint *len)
{
	uint cap, i, v, active = 1, nf = 0;
	filt_t *f = calloc(cap = 2, sizeof(*f));
	f[1].i = 4;

	for (v = 1; ; ++v) {
		for (i = 1; i < active && --f[i].i; i++);

		if (i < active)
			f[i].i = f[i].v;
		else if (nf == f[i].i)
			f[i].i = f[i].v, ++active;  
		else {
			if (nf >= cap)
				f = realloc(f, sizeof(*f) * (cap*=2));
			f[nf] = (filt_t){ v + nf, v };
			if (++nf >= min_len && v >= min_val) break;
		}
	}

	
	
	uint *x = (void*) f;
	for (i = 0; i < nf; i++) x[i] = f[i].v;
	x = realloc(x, sizeof(*x) * nf);

	*len = nf;
	return x;
}

int find(uint *a, uint v)
{
	uint i;
	for (i = 0; a[i] <= v; i++)
		if (v == a[i]) return 1;
	return 0;
}

int main(void)
{
	uint len, i, *x = ludic(2005, 1000, &len);

	printf("First 25:");
	for (i = 0; i < 25; i++) printf(" %u", x[i]);
	putchar('\n');

	for (i = 0; x[i] <= 1000; i++);
	printf("Ludics below 1000: %u\n", i);

	printf("Ludic 2000 to 2005:");
	for (i = 2000; i <= 2005; i++) printf(" %u", x[i - 1]);
	putchar('\n');

	printf("Triples below 250:");
	for (i = 0; x[i] + 6 <= 250; i++)
		if (find(x, x[i] + 2) && find(x, x[i] + 6))
			printf(" (%u %u %u)", x[i], x[i] + 2, x[i] + 6);

	putchar('\n');

	free(x);
	return 0;
}











Ada: with Ada.Text_IO;
with Ada.Containers.Vectors;

procedure Ludic_Numbers is

   package Lucid_Lists is
      new Ada.Containers.Vectors (Positive, Natural);
   use Lucid_Lists;

   List : Vector;

   procedure Fill is
      use type Ada.Containers.Count_Type;
      Vec   : Vector;
      Lucid : Natural;
      Index : Positive;
   begin
      Append (List, 1);

      for I in 2 .. 22_000 loop
         Append (Vec, I);
      end loop;

      loop
         Lucid := First_Element (Vec);
         Append (List, Lucid);

         Index := First_Index (Vec);
         loop
            Delete (Vec, Index);
            Index := Index + Lucid - 1;
            exit when Index > Last_Index (Vec);
         end loop;

         exit when Length (Vec) <= 1;
      end loop;

   end Fill;

   procedure Put_Lucid (First, Last : in Natural) is
      use Ada.Text_IO;
   begin
      Put_Line ("Lucid numbers " & First'Image & " to " & Last'Image & ":");
      for I in First .. Last loop
         Put (Natural'(List (I))'Image);
      end loop;
      New_Line;
   end Put_Lucid;

   procedure Count_Lucid (Below : in Natural) is
      Count : Natural := 0;
   begin
      for Lucid of List loop
         if Lucid <= Below then
            Count := Count + 1;
         end if;
      end loop;
      Ada.Text_IO.Put_Line ("There are " & Count'Image & " lucid numbers <=" & Below'Image);
   end Count_Lucid;

   procedure Find_Triplets (Limit : in Natural) is

      function Is_Lucid (Value : in Natural) return Boolean is
      begin
         for X in 1 .. Limit loop
            if List (X) = Value then
               return True;
            end if;
         end loop;
         return False;
      end Is_Lucid;

      use Ada.Text_IO;
      Index : Natural;
      Lucid : Natural;
   begin
      Put_Line ("All triplets of lucid numbers <" & Limit'Image);
      Index := First_Index (List);
      while List (Index) < Limit loop
         Lucid := List (Index);
         if Is_Lucid (Lucid + 2) and Is_Lucid (Lucid + 6) then
            Put ("(");
            Put (Lucid'Image);
            Put (Natural'(Lucid + 2)'Image);
            Put (Natural'(Lucid + 6)'Image);
            Put_Line (")");
         end if;
         Index := Index + 1;
      end loop;
   end Find_Triplets;

begin
   Fill;
   Put_Lucid (First => 1,
              Last  => 25);
   Count_Lucid (Below => 1000);
   Put_Lucid (First => 2000,
              Last  => 2005);
   Find_Triplets (Limit => 250);
end Ludic_Numbers;