Solution of Peculiar Times

The regular solution (Sergiu Puscas)

This is a straightforward implementation problem and does not require any algorithmic knowledge. For any given time, each of the criteria can be easily verified. Also, no integer manipulation is required, especially for the last two conditions, considering the small set of times that validate them:

  • The only valid times that have consecutive digits are 01:23, 12:34 and 23:45;
  • The only valid times that make up a number which is a power of two are 10:24 and 20:48 (the next one, 40:96, is already too large).

C++ solution

    1 #include <iostream>
    2 using namespace std;
    3 
    4 int t;
    5 bool peculiar, valid;
    6 char X, Y, Z, T, separator;
    7 string fullTime, hour, minutes;
    8 
    9 int main() {
   10     cin>>t;
   11     while(t--) {
   12         cin>>X>>Y>>separator>>Z>>T;
   13         fullTime.clear();
   14         fullTime.push_back(X);
   15         fullTime.push_back(Y);
   16         fullTime.push_back(Z);
   17         fullTime.push_back(T);
   18 
   19         hour.clear();
   20         hour.push_back(X);
   21         hour.push_back(Y);
   22 
   23         minutes.clear();
   24         minutes.push_back(Z);
   25         minutes.push_back(T);
   26 
   27         peculiar = false;
   28         if(Z == '0' && T == '0') peculiar = true;
   29         if(X == Z && Y == T) peculiar = true;
   30         if(X == T && Y == Z) peculiar = true;
   31         if(fullTime == "0123" || fullTime == "1234" || fullTime == "2345") peculiar = true;
   32         if(fullTime == "1024" || fullTime == "2048") peculiar = true;
   33 
   34         valid = true;
   35         if(hour < "00" || hour >= "24") valid = false;
   36         if(minutes < "00" || minutes >= "60") valid = false;
   37 
   38         cout<<(valid && peculiar? "YES\n":"NO\n");
   39     }
   40 
   41     return 0;
   42 }

Python solution

    1 for _ in range(0, input()):
    2     a, b = raw_input().split(':')
    3     print ['NO', 'YES'][(b=='00' or a==b or a==b[::-1] or a+b in '0123 1234 2345 1024 2048'.split()) and a < '24' and b <= '60']

A regex solution (Marius Gavrilescu)

This problem can also be solved using regular expressions, as seen in the following solution.
    1 #!/usr/bin/perl
    2 use v5.14;
    3 use warnings;
    4 
    5 <>;
    6 my $hour  = qr/(?:[01]\d|2[0-3])/;      # Matches a valid hour (00 - 23)
    7 my $min   = qr/[0-5]\d/;                # Matches valid minutes (00 - 59)
    8 my $time  = qr/$hour:$min/;             # Matches a valid time
    9 my $exact = qr/\d\d:00/;                # Matches exact hours (XY:00)
   10 my $same  = qr/(\d)(\d):(?:\1\2|\2\1)/; # Matches XY:XY and XY:YX
   11 my $cons  = qr/01:23|12:34|23:45/;      # Matches consecutive digits
   12 my $pow2  = qr/10:24|20:48/;            # Matches a power of 2
   13 
   14 my $peculiar = qr/(?:$exact|$same|$cons|$pow2)/; # Matches peculiar times
   15 
   16 my $re = qr/(?=$time)$peculiar/; # Matches valid peculiar times
   17 say m/$re/ ? 'YES' : 'NO' while <>;
A typical way of writing the above:
    1 #!/usr/bin/perl
    2 use v5.14;
    3 use warnings;
    4 
    5 <>;
    6 say /(?:[01]\d|2[0-3]):[0-5]\d/ && /:00|(\d)(\d):(?:\1\2|\2\1)|01:23|12:34|23:45|10:24|20:48/ ? 'YES' : 'NO' while <>;
This solution can be golfed further if necessary.
    1 <>;CORE::say/(?:[01]\d|2[0-3]):[0-5]\d/&&/:00|(\d)(\d):(?:\1\2|\2\1)|01:23|12:34|23:45|10:24|20:48/?YES:NO while<>;
Questions?

Sponsors Gold