aboutsummaryrefslogtreecommitdiff
path: root/challenge-032/steven-wilson/perl5/ch-2.pl
blob: 402130a4fd117648fad29b2dcd2eddde5498e7ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/env perl
# Author: Steven Wilson
# Date: 2019-10-28
# Week: 032

# Task #2
# Contributed by Neil Bowers
# ASCII bar chart
#
# Write a function that takes a hashref where the keys are labels and
# the values are integer or floating point values. Generate a bar graph
# of the data and display it to stdout.
#
# The input could be something like:
#
# $data = { apple => 3, cherry => 2, banana => 1 };
# generate_bar_graph($data);
# And would then generate something like this:
#
#  apple | ############
# cherry | ########
# banana | ####
# If you fancy then please try this as well: (a) the function could let
# you specify whether the chart should be ordered by (1) the labels, or
# (2) the values.

# generate_bar_graph ( $data); # sort by keys
# generate_bar_graph ( $data, 'l'); # sort by keys
# output:
#  apple | ###
# banana | #
# cherry | ##

# generate_bar_graph ( $data, 'v'); # sort by values
# output:
#  apple | ###
# cherry | ##
# banana | #

use strict;
use warnings;
use feature qw/ say /;

my $data = { apple => 3, cherry => 2, banana => 1 };

generate_bar_graph( $data, 'v' );

sub generate_bar_graph {
    my $bar_graph_data_ref = shift;
    my %bar_graph_data     = %{$bar_graph_data_ref};
    my $max_length_key     = get_max_length_keys($bar_graph_data_ref);
    my $sort_by            = ( defined $_[0] and $_[0] eq 'v' ) ? 'v' : 'l';
    my @sorted_keys        = get_sorted_keys( $bar_graph_data_ref, $sort_by );
    for my $key (@sorted_keys) {
        say sprintf '%*3$s | %s',
            $key, '#' x $bar_graph_data{$key}, $max_length_key;
    }
}

sub get_sorted_keys {
    my $bar_graph_data_ref = shift;
    my %bar_graph_data     = %{$bar_graph_data_ref};
    my $sort_by            = shift;
    my @sorted_keys;
    if ( $sort_by eq 'l' ) {
        @sorted_keys = sort keys %bar_graph_data;
    }
    else {
        @sorted_keys
            = reverse sort { $bar_graph_data{$a} <=> $bar_graph_data{$b} }
            keys %bar_graph_data;
    }
    return @sorted_keys;
}

sub get_max_length_keys {
    my $bar_graph_data_ref = shift;
    my %bar_graph_data     = %{$bar_graph_data_ref};
    my $max_length_key     = 0;
    for my $key ( keys %bar_graph_data ) {
        $max_length_key = length $key if length $key > $max_length_key;
    }
    return $max_length_key;
}