131 lines
4.1 KiB
Erlang
131 lines
4.1 KiB
Erlang
%%% ============================================================
|
|
%%% Stem-and-Leaf Plot in Erlang
|
|
%%% ============================================================
|
|
%%% - Pure functions
|
|
%%% - No mutation
|
|
%%% - Deterministic transformations
|
|
%%% - Explicit functional pipeline
|
|
%%% ============================================================
|
|
|
|
-module(stem_leaf).
|
|
-export([main/0]).
|
|
|
|
%%% ============================================================
|
|
%%% 1. Mathematical Helpers (Pure Functions)
|
|
%%% ============================================================
|
|
|
|
%% expand_number/1
|
|
%% Conceptually expands single digit numbers to two-digit
|
|
%% (e.g., 7 -> 07). Numerically unchanged, but included
|
|
%% for semantic clarity.
|
|
expand_number(N) ->
|
|
N.
|
|
|
|
%% stem/1
|
|
%% Returns the stem (all but the last digit).
|
|
%% Example: 127 -> 12
|
|
stem(N) ->
|
|
N div 10.
|
|
|
|
%% leaf/1
|
|
%% Returns the leaf (last digit).
|
|
%% Example: 127 -> 7
|
|
leaf(N) ->
|
|
N rem 10.
|
|
|
|
%% range/2
|
|
%% Returns a list of integers from From to To (inclusive).
|
|
%% Used to guarantee stems 0..14 are always present.
|
|
range(From, To) when From =< To ->
|
|
lists:seq(From, To).
|
|
|
|
%%% ============================================================
|
|
%%% 2. Data Transformation Pipeline
|
|
%%% ============================================================
|
|
|
|
%% build_stem_leaf/1
|
|
%% Takes raw data and returns a list of:
|
|
%% [{Stem, [SortedLeaves]}, ...]
|
|
%%
|
|
%% Steps:
|
|
%% 1. Expand numbers
|
|
%% 2. Sort entire dataset
|
|
%% 3. Generate all stems 0..14
|
|
%% 4. Collect and sort leaves for each stem
|
|
build_stem_leaf(Data) ->
|
|
Expanded = [expand_number(N) || N <- Data],
|
|
Sorted = lists:sort(Expanded),
|
|
Stems = range(0, 14),
|
|
[{S, sorted_leaves(S, Sorted)} || S <- Stems].
|
|
|
|
%% sorted_leaves/2
|
|
%% Filters all numbers matching a given stem
|
|
%% Extracts leaves
|
|
%% Sorts leaves
|
|
sorted_leaves(StemValue, Data) ->
|
|
Leaves =
|
|
[leaf(N) || N <- Data, stem(N) =:= StemValue],
|
|
lists:sort(Leaves).
|
|
|
|
%%% ============================================================
|
|
%%% 3. Formatting Functions (Pure Rendering Layer)
|
|
%%% ============================================================
|
|
|
|
%% format_stem/1
|
|
%% Formats stem as two digits (leading zero if needed).
|
|
%% Example: 7 -> "07"
|
|
format_stem(S) ->
|
|
io_lib:format("~2..0B", [S]).
|
|
|
|
%% format_leaves/1
|
|
%% Converts list of integers into space-separated string.
|
|
%% Example: [1,3,7] -> "1 3 7"
|
|
format_leaves([]) ->
|
|
"";
|
|
format_leaves(Leaves) ->
|
|
string:join([integer_to_list(L) || L <- Leaves], " ").
|
|
|
|
%% render_line/1
|
|
%% Converts {Stem, Leaves} into formatted line.
|
|
%% Example:
|
|
%% {12, [3,4,7]} -> "12 | 3 4 7"
|
|
render_line({StemValue, Leaves}) ->
|
|
lists:flatten(
|
|
io_lib:format("~s | ~s",
|
|
[format_stem(StemValue), format_leaves(Leaves)])
|
|
).
|
|
|
|
%% render_plot/1
|
|
%% Converts full stem-leaf structure into multi-line string.
|
|
render_plot(StemLeafPairs) ->
|
|
Lines = [render_line(Pair) || Pair <- StemLeafPairs],
|
|
string:join(Lines, "\n").
|
|
|
|
%%% ============================================================
|
|
%%% 4. Program Entry Point
|
|
%%% ============================================================
|
|
|
|
main() ->
|
|
%% --------------------------------------------------------
|
|
%% Raw Dataset
|
|
%% --------------------------------------------------------
|
|
Data = [
|
|
12,127,28,42,39,113,42,18,44,118,44,37,113,124,37,48,127,36,29,31,
|
|
125,139,131,115,105,132,104,123,35,113,122,42,117,119,58,109,23,
|
|
105,63,27,44,105,99,41,128,121,116,125,32,61,37,127,29,113,121,
|
|
58,114,126,53,114,96,25,109,7,31,141,46,13,27,43,117,116,27,7,
|
|
68,40,31,115,124,42,128,52,71,118,117,38,27,106,33,117,116,111,
|
|
40,119,47,105,57,122,109,124,115,43,120,43,27,27,18,28,48,125,
|
|
107,114,34,133,45,120,30,127,31,116,146
|
|
],
|
|
|
|
%% --------------------------------------------------------
|
|
%% Functional Processing Pipeline
|
|
%% --------------------------------------------------------
|
|
StemLeafStructure = build_stem_leaf(Data),
|
|
Plot = render_plot(StemLeafStructure),
|
|
|
|
%% --------------------------------------------------------
|
|
%% Output
|
|
%% --------------------------------------------------------
|
|
io:format("~s~n", [Plot]).
|