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
|
#! /usr/bin/env raku
subset HHMM where $_ ~~ /^(<[012]>)\d\:<[012345]>\d$/ && $0 <= 23;
unit sub MAIN (Str $trains = "11:20 11:50 | 14:30 15:00",
:l(:$loquacious),
:v(:$verbose) = $loquacious,
:p(:$platforms),
);
class Platform
{
has Str $.id;
has Str @.in-use is rw;
method add-if-vacant (HHMM $from, HHMM $to)
{
for @.in-use -> $interval
{
my ($start, $end) = $interval.split("-");
next if $to lt $start;
next if $end lt $from;
return False;
}
@.in-use.push: "$from-$to";
return True;
}
method Str
{
return ": - Platform: $.id: " ~ @.in-use.sort.join(", ");
}
}
class Station
{
has Str $.name;
has Platform @.platforms is rw;
method add-train (HHMM $from, HHMM $to)
{
for self.platforms -> $platform
{
return True if $platform.add-if-vacant($from, $to);
}
my $platform = Platform.new(id => (self.number-of-platforms + 1).Str);
self.platforms.push: $platform;
return $platform.add-if-vacant($from, $to);
}
method number-of-platforms
{
return @.platforms.elems;
}
method Str
{
return ": Station: $.name\n" ~ @.platforms>>.Str.join("\n");
}
}
my @trains = $trains.split(/\s\|\s+/);
my $number-of-platforms = Inf;
for @trains.permutations -> @trains-p
{
my $station = Station.new(name => 'Grand Central');
for @trains-p -> $from-to
{
my (HHMM $from, HHMM $to) = $from-to.words;
die "Train departs ($from) before it arrives ($to)" if $from gt $to;
say ": Visiting train $from -> $to" if $verbose;
$station.add-train($from, $to);
}
say $station.Str if $loquacious;
my $platform-count = $station.number-of-platforms;
$number-of-platforms = min($number-of-platforms, $platform-count);
say ": Platforms: $platforms" if $platforms;
}
say $number-of-platforms;
|