Project Euler in PL/SQL: Problem 12

  • by

Problem 12 of Project Euler looks at triangle numbers and divisors.

Problem 12:

Highly Divisible Triangular Number

The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:

1, 3, 6, 10, 15, 21, 28, 36, 45, 55, …

Let us list the factors of the first seven triangle numbers:

1: 1
3: 1,3
6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28
We can see that 28 is the first triangle number to have over five divisors.

What is the value of the first triangle number to have over five hundred divisors?

The work to this problem is pretty straight-forward. A triangle number can be calculated using the formula n * (n+1)/2, and when checking for divisors (in our EULER_PKG), we only need to check up until the square root of our number and add 2 for every factor found, as there will be one more on the other side of the square root.


DECLARE
answer NUMERIC;
triangle_num NUMERIC := 0;
divisors_count PLS_INTEGER;
i PLS_INTEGER := 1;
    FUNCTION get_next_tri_num(num_in NUMERIC) RETURN NUMERIC
    AS
    BEGIN
        RETURN num_in * (num_in + 1)/2;
    END;
BEGIN
    WHILE answer IS NULL LOOP
        triangle_num := get_next_tri_num(i);
        divisors_count := EULER_PKG.get_divisors_count(triangle_num);
        
        IF divisors_count > 500 THEN
            answer := triangle_num;
        END IF;
        
        i :=  i+1;
    END LOOP;
    
    dbms_output.put_line(answer);
END;
--output: 76576500


/* EULER_PKG code added */

FUNCTION get_divisors_count(num_in NUMBER) RETURN PLS_INTEGER
IS
divisors PLS_INTEGER := 0;
BEGIN
    IF num_in > 1
    THEN
        FOR i IN 1..ROUND(SQRT(num_in),0) LOOP
            IF REMAINDER(num_in,i) = 0
            THEN
                divisors := divisors + 2;
            END IF;
        END LOOP;
    END IF;
    
    return divisors;
END get_divisors_count;

Questions or comments? Feel free to leave them below or reach out to me on Twitter!

Leave a Reply

Your email address will not be published. Required fields are marked *