1 #!/usr/bin/perl
 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-206/#TASK1
 3 #
 4 # Task 1: Shortest Time
 5 # =====================
 6 #
 7 # You are given a list of time points, at least 2, in the 24-hour clock format HH:MM.
 8 #
 9 # Write a script to find out the shortest time in minutes between any two time points.
10 #
11 ## Example 1
12 ##
13 ## Input: @time = ("00:00", "23:55", "20:00")
14 ## Output: 5
15 ##
16 ## Since the difference between "00:00" and "23:55" is the shortest (5 minutes).
17 #
18 ## Example 2
19 ##
20 ## Input: @array = ("01:01", "00:50", "00:57")
21 ## Output: 4
22 #
23 ## Example 3
24 ##
25 ## Input: @array = ("10:10", "09:30", "09:00", "09:55")
26 ## Output: 15
27 #
28 ############################################################
29 ##
30 ## discussion
31 ##
32 ############################################################
33 #
34 # Basically we have to walk the array with two variables, and
35 # for all combinations of time points calculate the minimum
36 # difference (basically from a to b and from b to a for all
37 # combinations of two time points, and the minimum of all those
38 # values).
39 
40 use strict;
41 use warnings;
42 
43 shortest_time("00:00", "23:55", "20:00");
44 shortest_time("01:01", "00:50", "00:57");
45 shortest_time("10:10", "09:30", "09:00", "09:55");
46 
47 sub shortest_time {
48    my @time_points = @_;
49    die "Not enough timepoints!" unless @time_points > 1;
50    foreach my $t (@time_points) {
51       die "Invalid time format for $t!\n" unless $t =~ m/^\d\d:\d\d/;
52    }
53    print "Input: (" . join(", ", @time_points) . ")\n";
54    my $minimum = 1440; # let's start with 24 hours as the initial value
55    foreach my $first (0..$#time_points) {
56       foreach my $second ($first+1..$#time_points) {
57          my ($A, $B) = ($time_points[$first], $time_points[$second]);
58          # we calculate the diff in both directions and search the
59          # minimum along the way
60          my $diff = time_diff($A, $B);
61          $minimum = $diff if $diff < $minimum;
62          $diff = time_diff($B, $A);
63          $minimum = $diff if $diff < $minimum;
64       }
65    }
66    print "Output: $minimum\n";
67 }
68 
69 sub time_diff {
70    my ($A, $B) = @_;
71    # let's calculate the times as minutes since 00:00
72    my $minutes_a = to_minutes($A);
73    my $minutes_b = to_minutes($B);
74    if($minutes_b >= $minutes_a) {
75       return $minutes_b - $minutes_a;
76    }
77    # the second time point is before the first time point,
78    # so let's calculate the time diff by wrapping around
79    # 00:00 once
80    return 1440 + $minutes_b - $minutes_a;
81 }
82 
83 # helper function to turn a time point into minutes since 00:00
84 sub to_minutes {
85    my $time = shift;
86    die "Invalid time format for $time!\n" unless $time =~ m/^\d\d:\d\d/;
87    my ($h, $m) = split /:/, $time;
88    $h =~ s/^0//;
89    $m =~ s/^0//;
90    return $h * 60 + $m;
91 }