http://www.perlmonks.org?node_id=148210

With the recent passing of a 'symmetrical date' (20:02 20/02 2002) and my inability to find any related posts on here, I present the following code from a co-member of a local linux users' group to produce a list of all symmetrical dates of the form HH:MM DD/MM YYYY

By symmetrical I mean either of the following examples: We are in Australia, so we put dates in the form DD/MM .. assuming we can start with (00:00 10/01 0000) and end with (19:59 21/12 9591) - the code below produces 8640 such dates.

I'm simply curious to see the results of a few rounds of golf on this problem.
#!/usr/bin/perl -w my %symmetrical = (); my $time; my $year; my @months = ('1001', '2002', '3003', '0110', '1111', '2112'); foreach my $i (0 .. 2359) { $i = &fill($i); $i =~ m/(\d\d)(\d\d)/; if (($1 > 23) or ($2 > 59)) { next; } $time = $i; $year = reverse($i); $symmetrical{$year} = $time; } for my $i (sort(keys %symmetrical)) { my $ryear = $i; my $rtime = $symmetrical{$i}; $rtime =~ s/(\d\d)(\d\d)/$1:$2/; for my $rmonth (@months) { $rmonth =~ s/(\d\d)(\d\d)/$1\/$2/; print "$rtime\t$rmonth\t$ryear\n"; } } sub fill { my $i = shift; while (length($i) < 4) { $i = '0' . $i; } return $i; }

Replies are listed 'Best First'.
147 Chars - Re: Symmetrical Date Golf
by metadoktor (Hermit) on Feb 28, 2002 at 14:54 UTC
    A first shot though I only generated 7198 variations...I must've done something wrong or misinterpreted something in your problem statement.
    #!/usr/bin/perl -w use strict; symdate(); sub symdate{ my($h,$n,$d,$m,$y,$r);my@x=qw(1001 2002 3003 0110 1111 2112);for('0000 +10'..'195921'){$r=reverse$_;$h=substr($_,0,2);$n=substr($_,2,2);$d=su +bstr($_,4,2);$m=substr($r,0,2);$y=substr($r,2,4);for(@x){if($_ eq $d. +$m){if(($h>=0)&&($h<24)&&($n>=0)&&($n<60)){print "$h:$n $d/$m $y\n";} +}}} }
    Update:

    Fixed the logical error and shortened the code down to 179 chars.

    sub symdate { my($f,$r);for('000000'..'235930'){$f=$_.reverse;$r='(..)'x6;$f=~s/$r/$ +1:$2 $3\/$4 $5$6/g;for(qw(1001 2002 3003 0110 1111 2112)){if(( $_ eq $3.$4)&&($1<24)&&($2<60)){print"$f\n";}}} }
    Update2:

    Shortened it down to 147 chars though still not as good as chipmunk's. Btw, it generates 8,640 solutions.

    sub symdate { for(qw(01 10 20 30 11 21)){for$h('00'..'23'){for$m('00'..'59'){$s="$h$ +m$_";$r='(..)'x6;$f=$s.reverse$s;$f=~s/$r/$1:$2 $3\/$4 $5$6/;print$f, +"\n";}}} }

    metadoktor

    "The doktor is in."

Re: Symmetrical Date Golf
by dragonchild (Archbishop) on Feb 28, 2002 at 15:34 UTC
    Two solutions.
    # This is 165 characters for(grep{/(..)(..)/;$1<24&&$2<60}map{sprintf"%04d",$_}0..2359){($t=$_) +=~s/(..)(..)/$1:$2/;$y=reverse;print map{"$t\t$_\t$y\n"}qw(10/01 20/0 +2 30/03 01/10 11/11 21/12)} ---- # This is 164 characters map{($t=$_)=~s/(..)(..)/$1:$2/;$y=reverse;print map{"$t\t$_\t$y\n"}qw( +10/01 20/02 30/03 01/10 11/11 21/12)}grep{/(..)(..)/;$1<24&&$2<60}map +{sprintf"%04d",$_}0..2359
    Update: Changed || to && as per metadoktor's note. This fixes the bug found.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      I think your solutions are incomplete. They generate dates like this:
      00:90 20/02 0900
      which aren't valid since there aren't 90 minutes in an hour. ryan claims that there are 8640 solutions. I got a different number though...

      metadoktor

      "The doktor is in."

Re: Symmetrical Date Golf
by chipmunk (Parson) on Mar 01, 2002 at 03:45 UTC
    I also found 8640 matches.

    This solution is 96 characters, although it orders the results by hour and minute, rather than by year. for$h('00'..'23'){for$m('00'..'59'){print"$h:$m $_/".reverse"\n$h$m $_"for 10,20,30,'01',11,21}} Or, by not worrying about a meaningful order to the results, I can get to 94: for$h('00'..'23'){for$M(102030011121=~/../g){print"$h:$_ $M".reverse"\n$h$_ $M"for'00'..'59'}}

Re: Symmetrical Date Golf
by Anonymous Monk on Mar 01, 2002 at 00:44 UTC
    Ryan-

    I got a chain letter two weeks back that claimed that 20:02 20/02 2002 was a miraculous phenomenon that has only happened once before and won't ever happen again... not sure whether they meant simply the date being a palindrome or, more likely, the fact that the date can be split by whitespace in 3 identical palindromes. Well, I didn't believe it, so i wrote this script:

    http://www.parseerror.com/perl/date_palindrome.pl
    http://www.parseerror.com/perl/date_palindrome.txt (in case your browser doesn't like .pl files)

    Which finds a total of 1164 palindromes between 1001-3003 AD. Of these, 4 turn out to be the "three identical palindromes"...

    10:01 10/01 1001
    11:11 11/11 1111
    20:02 20/02 2002
    21:12 21/12 2112

    Anywho, all my results are included in the file and the source code is alot shorter and simpler than what you have, though it does take a while for the script to chug through all the dates from 1001-3003 AD.

    Hope someone finds this interesting... i figured i could do it with a one-liner, but was suprirsed to find out how complex this actual problem was.

    ryan aka pizza_milkshake
      Yes, I got that email too. It wrongly claimed that this event would NEVER happen again, when infact 21:12 21/12 2112 will occur in the future ... maybe not in our lifetime though :)

      It also did not explicitely specify that each component had to be symmetrical, that was at best only implied ... hence our broader interpretation of the problem.

      Thanks for the linkage.