RosettaCodeData/Task/Stem-and-leaf-plot/Prolog/stem-and-leaf-plot.pro

38 lines
1.3 KiB
Prolog

:- initialization(main, main).
:- use_module(library(dcg/basics), [blanks/2, eol/2, integer/3]).
:- use_module(library(dcg/high_order), [sequence/4, sequence/5]).
%! numbers_to_stem_leaves(+Numbers, -StemLeaves) is det.
% Converts a list of Numbers to a list of Stem-Leaves pairs.
numbers_to_stem_leaves(Numbers, StemLeaves) :-
findall(Stem - Leaves, (
group_by(Stem, Leaf, (
member(Number, Numbers),
divmod(Number, 10, Stem, Leaf)
), Leaves0),
msort(Leaves0, Leaves)
), StemLeaves).
stem_leaf_plot(StemLeaves) --> sequence(stem_leaves, StemLeaves).
stem_leaves(Stem - Leaves) --> rpad_integer(4, Stem), " | ", sequence(integer, " ", Leaves), "\n".
rpad_integer(Pad, N) -->
( { Pad0 is Pad - 1, N < 10 ^ Pad0, \+ ( Pad = 1, N = 0 ) }
-> " ", rpad_integer(Pad0, N)
; integer(N)
).
%! display_stem_leaf_plot(Numbers) is det.
% Prints the stem-and-leaf plot of a list of Numbers.
display_stem_leaf_plot(Numbers) :-
numbers_to_stem_leaves(Numbers, StemLeaves),
once(phrase(stem_leaf_plot(StemLeaves), Codes)),
format("~s", [Codes]).
int(N) --> integer(N), blanks.
main([Filename]) :-
phrase_from_file((blanks, sequence(int, Numbers)), Filename),
display_stem_leaf_plot(Numbers).