:- module bug362.
:- interface.
:- import_module io.

:- pred main(io::di, io::uo) is det.

:- implementation.
:- import_module bool, int, list.

main(!IO) :- 
    print_line(get_n_happy_numbers(8, 1), !IO).

:- func get_n_happy_numbers(int, int) = list(int).

get_n_happy_numbers(NumToFind, N) =
    ( if NumToFind > 0 then
       ( if is_happy(N, yes)
       then [N | get_n_happy_numbers(NumToFind - 1, N + 1)]
       else get_n_happy_numbers(NumToFind, N + 1)
       )
    else
       []
    ).

:- pragma minimal_model(is_happy/2).
:- pred is_happy(int::in, bool::out) is nondet.

is_happy(N, Result) :-
   ( if N = 1 then Result = yes else is_happy(sum_sqr_digits(N), Result) ).

:- func sum_sqr_digits(int) = int.

sum_sqr_digits(N) =
   ( if N < 10 then sqr(N) else sqr(N mod 10) + sum_sqr_digits(N div 10) ).

:- func sqr(int) = int.

sqr(X) = X * X.
