Ludic numbers   are related to prime numbers as they are generated by a sieve quite like the Sieve of Eratosthenes is used to generate prime numbers.

The first ludic number is   1.

To generate succeeding ludic numbers create an array of increasing integers starting from   2.

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ...
(Loop)

 Take the first member of the resultant array as the next ludic number   2.
 Remove every   2nd   indexed item from the array (including the first).
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ...
 (Unrolling a few loops...)
 Take the first member of the resultant array as the next ludic number   3.
 Remove every   3rd   indexed item from the array (including the first).
3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 ...
 Take the first member of the resultant array as the next ludic number   5.
 Remove every   5th   indexed item from the array (including the first).
5 7 11 13 17 19 23 25 29 31 35 37 41 43 47 49 53 55 59 61 65 67 71 73 77 ...
 Take the first member of the resultant array as the next ludic number   7.
 Remove every   7th   indexed item from the array (including the first).
7 11 13 17 23 25 29 31 37 41 43 47 53 55 59 61 67 71 73 77 83 85 89 91 97 ...
  ... 
 Take the first member of the current array as the next ludic number   L.
 Remove every   Lth   indexed item from the array (including the first).
  ... 


Task

 Generate and show here the first 25 ludic numbers.
 How many ludic numbers are there less than or equal to 1000?
 Show the 2000..2005th ludic numbers.


Stretch goal

Show all triplets of ludic numbers < 250.

 A triplet is any three numbers     



x
,


{\displaystyle x,}

   



x
+
2
,


{\displaystyle x+2,}

   



x
+
6


{\displaystyle x+6}

      where all three numbers are also ludic numbers. 


SET SERVEROUTPUT ON
DECLARE
  c_limit CONSTANT PLS_INTEGER := 25000;
  TYPE t_nums IS TABLE OF PLS_INTEGER INDEX BY PLS_INTEGER;
  v_nums t_nums;
  v_ludic t_nums;
  v_count_ludic PLS_INTEGER;
  v_count_pos PLS_INTEGER;
  v_pos PLS_INTEGER;
  v_next_ludic PLS_INTEGER;
 
  FUNCTION is_ludic(p_num PLS_INTEGER) RETURN BOOLEAN IS
  BEGIN
    FOR i IN 1..v_ludic.COUNT LOOP
      EXIT WHEN v_ludic(i) > p_num;
      IF v_ludic(i) = p_num THEN
        RETURN TRUE;
      END IF;
    END LOOP;
    RETURN FALSE;
  END;
 
BEGIN
  FOR i IN 1..c_limit LOOP
    v_nums(i) := i;
  END LOOP;
 
  v_count_ludic := 1;
  v_next_ludic := 1;
  v_ludic(v_count_ludic) := v_next_ludic;
  v_nums.DELETE(1);
 
  WHILE v_nums.COUNT > 0 LOOP
    v_pos := v_nums.FIRST;
    v_next_ludic := v_nums(v_pos);
    v_count_ludic := v_count_ludic + 1;
    v_ludic(v_count_ludic) := v_next_ludic;
    v_count_pos := 0;
    WHILE v_pos IS NOT NULL LOOP
      IF MOD(v_count_pos, v_next_ludic) = 0 THEN
        v_nums.DELETE(v_pos);
      END IF;
      v_pos := v_nums.NEXT(v_pos);
      v_count_pos := v_count_pos + 1;
    END LOOP;
  END LOOP;
 
  DBMS_OUTPUT.put_line('Generate and show here the first 25 ludic numbers.');
  FOR i IN 1..25 LOOP
    DBMS_OUTPUT.put(v_ludic(i) || ' ');
  END LOOP;
  DBMS_OUTPUT.put_line('');
 
  DBMS_OUTPUT.put_line('How many ludic numbers are there less than or equal to 1000?');
  v_count_ludic := 0;
  FOR i IN 1..v_ludic.COUNT LOOP
    EXIT WHEN v_ludic(i) > 1000;
    v_count_ludic := v_count_ludic + 1;
  END LOOP;
  DBMS_OUTPUT.put_line(v_count_ludic);
 
  DBMS_OUTPUT.put_line('Show the 2000..2005''th ludic numbers.');
  FOR i IN 2000..2005 LOOP
    DBMS_OUTPUT.put(v_ludic(i) || ' ');
  END LOOP;
  DBMS_OUTPUT.put_line('');
 
  DBMS_OUTPUT.put_line('A triplet is any three numbers x, x + 2, x + 6 where all three numbers are also ludic numbers.');
  DBMS_OUTPUT.put_line('Show all triplets of ludic numbers < 250 (Stretch goal)');
  FOR i IN 1..v_ludic.COUNT LOOP
    EXIT WHEN (v_ludic(i)+6) >= 250;
    IF is_ludic(v_ludic(i)+2) AND is_ludic(v_ludic(i)+6) THEN
      DBMS_OUTPUT.put_line(v_ludic(i) || ', ' || (v_ludic(i)+2) || ', ' || (v_ludic(i)+6));
    END IF;
  END LOOP;
 
END;
/
 