perl logo Perl logo (Thanks to Olaf Alders)

The weekly challenge 366 - Task 2: Valid Times

  1 #!/usr/bin/env perl
  2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-366/#TASK2
  3 #
  4 # Task 2: Valid Times
  5 # ===================
  6 #
  7 # You are given a time in the form ‘HH:MM’. The earliest possible time is
  8 # ‘00:00’ and the latest possible time is ‘23:59’. In the string time, the
  9 # digits represented by the ‘?’ symbol are unknown, and must be replaced with a
 10 # digit from 0 to 9.
 11 #
 12 # Write a script to return the count different ways we can make it a valid
 13 # time.
 14 #
 15 ## Example 1
 16 ##
 17 ## Input: $time = "?2:34"
 18 ## Output: 3
 19 ##
 20 ## 0 -> "02:34" valid
 21 ## 1 -> "12:34" valid
 22 ## 2 -> "22:34" valid
 23 #
 24 ## Example 2
 25 ##
 26 ## Input: $time = "?4:?0"
 27 ## Output: 12
 28 ##
 29 ## Hours: tens digit ?, ones digit 4 -> can be 04, and 14 (2 possibilities)
 30 ## Minutes: tens digit ?, ones digit 0 -> tens can be 0-5 (6 possibilities)
 31 ##
 32 ## Total: 2 × 6 = 12
 33 #
 34 ## Example 3
 35 ##
 36 ## Input: $time = "??:??"
 37 ## Output: 1440
 38 ##
 39 ## Hours: from 00 to 23 -> 24 possibilities
 40 ## Minutes: from 00 to 59 -> 60 possibilities
 41 ##
 42 ## Total: 24 × 60 = 1440
 43 #
 44 ## Example 4
 45 ##
 46 ## Input: $time = "?3:45"
 47 ## Output: 3
 48 ##
 49 ## If tens digit is 0 or 1 -> any ones digit works, so 03 and 13 are valid
 50 ## If tens digit is 2 -> ones digit must be 0-3, but here ones digit is 3, so 23 is valid
 51 ##
 52 ## Therefore: 0,1,2 are all valid -> 3 possibilities
 53 #
 54 ## Example 5
 55 ##
 56 ## Input: $time = "2?:15"
 57 ## Output: 4
 58 ##
 59 ## Tens digit is 2, so hours can be 20-23
 60 ## Ones digit can be 0,1,2,3 (4 possibilities)
 61 ##
 62 ## Therefore: 4 valid times
 63 #
 64 ############################################################
 65 ##
 66 ## discussion
 67 ##
 68 ############################################################
 69 #
 70 # If there are no "?" in $time, we check, if it is valid.
 71 # If there are "?" in $time, we count all possible times that we
 72 # get if we replace "?" for each possible digit 0..9 (recursively,
 73 # so we catch all "?" in $time).
 74 # There is no short circuit in case we use invalid digits in some places.
 75 # The whole thing is not time critical enough to complicate the algorithm
 76 # by optimizing.
 77 
 78 use v5.36;
 79 
 80 valid_times("?2:34");
 81 valid_times("?4:?0");
 82 valid_times("??:??");
 83 valid_times("?3:45");
 84 valid_times("2?:15");
 85 
 86 sub valid_times($time) {
 87     say "Input: $time";
 88     my $count = 0;
 89     if($time =~ m/\?/) {
 90         foreach my $d (0..9) {
 91             $count += find_valid($time, $d);
 92         }
 93         say "Output: $count";
 94     } else {
 95         say is_valid($time) ? "Output: 1" : "Output: 0";
 96     }
 97 }
 98 
 99 sub find_valid($time, $d) {
100     $time =~ s/\?/$d/;
101     my $count = 0;
102     if($time =~ m/\?/) {
103         foreach my $d2 (0..9) {
104             $count += find_valid($time, $d2);
105         }
106         return $count;
107     } else {
108         return is_valid($time);
109     }
110 }
111 
112 sub is_valid($time) {
113     my ($h, $m) = split /:/, $time;
114     return 1 if ($h >= 0 && $h <= 23 && $m >= 0 && $m <= 59);
115     return 0;
116 }