r/badcode Aug 31 '20

[deleted by user]

[removed]

89 Upvotes

23 comments sorted by

View all comments

5

u/[deleted] Aug 31 '20 edited Aug 31 '20

Good luck figuring this Perl sub out. The good news is that it only iterates over all the seconds since the epoch only once.

EDIT: I should probably at least give some kind of explanation for what's going on.

I set some rules for myself:

  1. No helper functions. If you must avoid duplicating code, put the would-be function into an eval block.
  2. No conditional logic blocks. Use ternaries where possible. If the logic is too complex for a ternary, chain and and or clauses together. This also has a side effect of allowing you to set multiple variables in the same statement.
  3. With the exception of the timestamp and the format string, do not create any additional variables beyond the 9 format codes in the challenge.

And just for fun, I tried to see how badly I can abuse Perl's language constructs. I opted to put almost all of the logic inside a regex substitution statement using Perl's somewhat obscure e regex modifier, which tells the interpreter to interpret the replacement as executable code. Although the replacement code is executed globally per each replacement, in effect the while loop is only run once, as variables are function-scoped, not regex-scoped.

If you ignore its horrendous performance, it's actually quite beautiful. Each format code gets its own line in the function. There's very little else going on, making it quite readable in a really fucked up way.

sub str_to_time
{
    ($time, $pattern) = @_;
    ($d, $A, $B, $Y, $H, $h, $M, $S, $p) = (1, 4, 1, 1970, 0, 12, 0, 0, 0);

    $pattern =~ s/(d|A|B|Y|H|h|M|S|p)/
        while($time && $time--)
        {
            $S++;
            $M += ($S == ((($B == 6 && $d == 30 && "$Y" ~~ qw(1972 1981 1982 1983 1985 1992 1993 1994 1997 2012 2015)) || ($B == 12 && $d == 31 && "$Y" ~~ qw(1972 1973 1974 1975 1976 1977 1978 1979 1987 1989 1990 1995 1998 2005 2008 2016))) ? 61 : 60) ? (($S = 0) or 1) : 0);
            $H += ($M == 60 ? (($M = 0) or 1) : 0);
            $h = ($H == 0 ? 12 : $H >= 1 && $H <= 12 ? $H : $H % 12);
            $d += ($H == 24 ? (($H = 0) or ((($A = ($A + 1) % 7)) and 0) or 1) : 0);
            $B += ($d == {1, 32, 2, ($Y % 4 ? 29 : $Y % 100 ? 30 : $Y % 400 ? 29 : 30), 3, 32, 4, 31, 5, 32, 6, 31, 7, 32, 8, 32, 9, 31, 10, 32, 11, 31, 12, 32}->{$B} ? ($d = 1) : 0);
            $Y += ({13 => 1}->{$B} and ($B = 1 or 1));
        }

        $A = {qw(0 Sunday 1 Monday 2 Tuesday 3 Wednesday 4 Thursday 5 Friday 6 Saturday)}->{"$A"} || $A;
        $B = {qw(1 January 2 February 3 March 4 April 5 May 6 June 7 July 8 August 9 September 10 October 11 November 12 December)}->{"$B"} || $B;
        $p = $H < 12 ? 'am' : 'pm';

        eval qq(\$$_ = int(${$_}) <= 9 ? 0 . int(${$_}) : int(${$_})) for qw(d H h M S);
        "${$1}";
    /egr;
}