Hacker News new | ask | show | jobs
by klibertp 608 days ago
> But it is suboptimal in the sense that it uses for loops

Looking at https://news.ycombinator.com/item?id=41897526 caused me to try asking for a solution in a language that doesn't have `for` loops. Since SQL was taken, I tried Prolog:

    % Define a predicate to find all positive divisors of N
    divisors(N, Divisors) :-
        findall(D, (between(1, N, D), N mod D =:= 0), Divisors).

    % Define a predicate to generate all combinations of three distinct elements from a list
    combination3(List, X, Y, Z) :-
        select(X, List, Rest1),
        select(Y, Rest1, Rest2),
        select(Z, Rest2, _),
        X < Y, Y < Z.

    % Define a predicate to find triplets (X, Y, Z) such that X*Y*Z = N
    find_triplets(N, X, Y, Z) :-
        divisors(N, Divisors),
        combination3(Divisors, X, Y, Z),
        X * Y * Z =:= N.

    % Define a predicate to list all the triplets
    list_triplets(N) :-
        findall((X, Y, Z), find_triplets(N, X, Y, Z), Triplets),
        writeln(Triplets).
Run:

    ?- [a]. list_triplets(108).
    [(1,2,54),(1,3,36),(1,4,27),(1,6,18),(1,9,12),(2,3,18),(2,6,9),(3,4,9)]
I'm in love. I both understand what is happening (I think I would understand it even if I didn't know the task description!) and could easily port optimizations from the previous solution.

Maybe this is the point when being a polyglot developer - knowing tens of programming languages and their characteristics - will finally start paying off.