% bins.pl

% code to generate histograms. cool just for
% its succinctness

:- ensure_loaded(format).

bins(L0,L) :-
	% "sort" removes duplicates
	% "msort" keeps copies
	msort(L0,L1),
	bins(L1,[],L).

% returns a list showing how often a
% particular item appears. assumes the
% input list is sorted
bins([],X,X).
bins([H|T],[H-N0|Rest],Out) :- !,
	N is N0 + 1,
	bins(T,[H-N|Rest],Out).
bins([H|T],In,Out) :-
	bins(T,[H-1|In],Out).

dist(L) :- dist(5,5,3,L).
  
dist(W1, % width of the first "item" column
     W2, % width of the second "frequency" column
     W3, % scale factor for how much to shrink
	 % the twiddles shown in column three
     L) :-
	% sformat builds a string and binds it to "S".
	% this string stores the widths and scale factot
	% for our columns. note the use of ">" and "S"
	% which are special format commands defined in
	% format.pl
	
	sformat(S,'~~~w>  ~~~w> ~~~wS\n',[W1,W2,W3]),
	bins(L,Bins),
	nl,
	format(S,[item,frequency,0]),
	
	% so succint: just loop through the inputs, calling
	% format on each item using our special "S" string

	forall(member(What-N,Bins),format(S,[What,N,N])).