How to resolve the algorithm Hamming numbers step by step in the Prolog programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Hamming numbers step by step in the Prolog programming language

Table of Contents

Problem Statement

Hamming numbers are numbers of the form   Hamming numbers   are also known as   ugly numbers   and also   5-smooth numbers   (numbers whose prime divisors are less or equal to 5).

Generate the sequence of Hamming numbers, in increasing order.   In particular:

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Hamming numbers step by step in the Prolog programming language

Source code in the prolog programming language

%% collect N elements produced by a generator in a row
 
take( 0, Next, Z-Z, Next).
take( N, Next, [A|B]-Z, NZ):- N>0, !, next(Next,A,Next1),
  N1 is N-1,
  take(N1,Next1,B-Z,NZ).
 
%% a generator provides specific {next} implementation
 
next( hamm( A2,B,C3,D,E5,F,[H|G] ), H, hamm(X,U,Y,V,Z,W,G) ):- 
  H is min(A2, min(C3,E5)),
  (   A2 =:= H -> B=[N2|U],X is N2*2 ; (X,U)=(A2,B) ),
  (   C3 =:= H -> D=[N3|V],Y is N3*3 ; (Y,V)=(C3,D) ),
  (   E5 =:= H -> F=[N5|W],Z is N5*5 ; (Z,W)=(E5,F) ).
 
mkHamm( hamm(1,X,1,X,1,X,X) ).       % Hamming numbers generator init state

main(N) :- 
    mkHamm(G),take(20,G,A-[],_),           write(A), nl, 
    take(1691-1,G,_,G2),take(2,G2,B-[],_),     write(B), nl,  
    take(  N  -1,G,_,G3),take(2,G3,[C1|_]-_,_),   write(C1), nl.

hamming(N) :-
     % to stop cleanly
     nb_setval(go, 1),

     % display list
     (	 N = 20 -> watch_20(20, L); watch(1,N,L)),

     % go
     L=[1|L235],
     multlist(L,2,L2),
     multlist(L,3,L3),
     multlist(L,5,L5),
     merge_(L2,L3,L23),
     merge_(L5,L23,L235).


%% multlist(L,N,LN)
%% multiply each element of list L with N, resulting in list LN
%% here only do multiplication for 1st element, then use multlist recursively
multlist([X|L],N,XLN) :-
	% the trick to stop
	nb_getval(go, 1) ->

	% laziness flavor	
	when(ground(X),
	     (	 XN is X*N,
		 XLN=[XN|LN],
		 multlist(L,N,LN)));

	true.

merge_([X|In1],[Y|In2],XYOut) :-
	% the trick to stop
	nb_getval(go, 1) ->

	% laziness flavor
	(   X < Y -> XYOut = [X|Out], In11 = In1, In12 = [Y|In2]
	;   X = Y -> XYOut = [X|Out], In11 = In1, In12 = In2
	;            XYOut = [Y|Out], In11 = [X | In1], In12 = In2),
	freeze(In11,freeze(In12, merge_(In11,In12,Out)));

	true.

%% display nth element
watch(Max, Max, [X|_]) :-
	% laziness flavor
	when(ground(X),
	     (format('~w~n', [X]),

	      % the trick to stop
	      nb_linkval(go, 0))).


watch(N, Max, [_X|L]):-
	 N1 is N + 1,
	 watch(N1, Max, L).


%% display nth element
watch_20(1, [X|_]) :-
	% laziness flavor
	when(ground(X),
	     (format('~w~n', [X]),

	      % the trick to stop
	      nb_linkval(go, 0))).


watch_20(N, [X|L]):-
	% laziness flavor
	when(ground(X),
	     (format('~w ', [X]),
	      N1 is N - 1,
	      watch_20(N1, L))).

  

You may also check:How to resolve the algorithm Read entire file step by step in the OCaml programming language
You may also check:How to resolve the algorithm Empty program step by step in the SQL PL programming language
You may also check:How to resolve the algorithm Luhn test of credit card numbers step by step in the EchoLisp programming language
You may also check:How to resolve the algorithm Price fraction step by step in the Clipper programming language
You may also check:How to resolve the algorithm Consecutive primes with ascending or descending differences step by step in the J programming language