aboutsummaryrefslogtreecommitdiff
path: root/challenge-075/mohammad-anwar/raku/ch-2.t
blob: f6e50809dae605ee960dff6487b70b636a0edee1 (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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/env raku

#
# Perl Weekly Challenge - 075
#
# Task #2: Largest Rectangle Histogram
#
# https://perlweeklychallenge.org/blog/perl-weekly-challenge-075
#

use Test;

is largest-rectangle-histogram(prepare("2, 1, 4, 5, 3, 7")), 12, "example 1";
is largest-rectangle-histogram(prepare("3, 2, 3, 5, 7, 5")), 15, "example 2";

done-testing;

#
#
# METHODS

sub largest-rectangle-histogram($list where .all ~~ Int) returns Int {

    my Int $i   = 0;
    my Int $max = 0;

    for 0 .. $list.elems-1 -> $i {

        my (Int $left, Int $right) = (0, 0);
        $left  = go-left($i, $list)  if $i > 0;
        $right = go-right($i, $list) if $i < $list.elems;

        my $heights = $list.[$i - $left .. $i + $right];
        my $size    = $heights.min * $heights.elems;

        $max = $size if $size > $max;
    }

    return $max;
}

sub go-left(Int $i is copy, $list where .all ~~ Int) returns Int {

    my $c = $list.[$i];
    my $j = 0;
    while $i > 0 {
        $i = $i - 1;
        last if $list.[$i] < $c;
        $j = $j + 1;
    }

    return $j;
}

sub go-right(Int $i is copy, $list where .all ~~ Int) returns Int {

    my $c = $list.[$i];
    my $j = 0;
    while $i < $list.elems-1 {
        $i += 1;
        last if $list.[$i] < $c;
        $j += 1;
    }

    return $j;
}

sub chart($list where .all ~~ Int) {

    my $max   = $list.max;
    my $chart = [];
    my $row   = 1;
    for 1 .. $max -> $n {
        my Str $data = "";
        for 0 .. $list.elems-1 -> $i {
            if $row <= $list.[$i] {
                $data ~= " #";
            }
            else {
                $data ~= "  ";
            }
        }

        $row += 1;

        $chart.push: sprintf("%d%s", $n, $data);
    }

    my (Str $histogram, Str $line, Str $size) = ("", "", "  ");
    $histogram = $chart.reverse.join("\n");
    $line ~= "_ " for 0 .. $list.elems;
    $size ~= $list.join(" ");

    return ($histogram, $line, $size).join("\n");
}

sub prepare(Str $list is copy) {

    return unless $list.defined;

    die "ERROR: Invalid list [$list].\n"
        unless $list ~~ /^[\s?\-?\d\,?\s?]+$/;

    $list ~~ s:g/\s//;
    return [ $list.split(',').map({ .Int }) ];
}