in reply to Re: Christmas Coding Blues
in thread Christmas Coding Blues

Ok. Here's the Golf. Given a 4-digit year from 1 through whenever, return 0-6 where 0 is sunday and 6 is saturday, for the day of Christmas.

I've got it at a cool 67. :-)

my @days = qw(Sunday Monday Tuesday Wednesday Thursday Friday Saturday +); my $day = f($ARGV[0] || 2001); print $days[$day], $/; sub f { #234567890#234567890#234567890#234567890#234567890#234567890#234567890 +#234567890 $b=1;for(1..pop){$b++;$b++if!$_%4;$b--if!$_%100;$b++if!$_%400}$b%=7 }

------
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.

Replies are listed 'Best First'.
Re: Golfing the day of Christmas
by japhy (Canon) on Dec 13, 2001 at 20:19 UTC
    Nice. I got 56:
    sub f { #234567890#234567890#234567890#234567890#234567890#234567890 use Time::Local;(gmtime timegm 0,0,0,25,11,-1900+pop)[6] }

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker.
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;


      55 ;-)
      sub f { use Time'Local;(gmtime timegm 0,0,0,25,11,-1900+pop)[6] }

      --
      John.

        Except that you don't handle years before 1900. The problem-statement said that it handle to handle any year in the Common Era. :-)

        ------
        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.

Re: Golfing the day of Christmas
by jmcnamara (Monsignor) on Dec 13, 2001 at 20:57 UTC

    37 chars.

    However, I would say two things about this. First using ' istead of :: is so ugly that it isn't worth the 1 stroke saving. Secondly, although Perl Golf involves bending the rules as much as possible, using modules just goes against the spirit of the game.

    # 39 sub xmas1 { use Date'Manip;Date_DayOfWeek+12,25,pop } # 41 sub xmas2 { use Date'Calc':all';Day_of_Week+pop,12,25 }
    Update: I saved 2 chars by using May Day instead of Christmas. The politics of that may appeal to someone. :-)
    # 37 sub xmas3 { use Date'Manip;Date_DayOfWeek+5,1,pop } # 39 sub xmas4 { use Date'Calc':all';Day_of_Week+pop,5,1 }

    --
    John.

Re: Golfing the day of Christmas
by Masem (Monsignor) on Dec 13, 2001 at 20:45 UTC
    Some simple squishing down to 49 char:
    sub f { #234567890#234567890#234567890#234567890#234567890# $b=1;$b+=1+!$_%4-!$_%100+!$_%400for(1..pop);$b%=7 }
    UPDATE - I was just compression what the parent post had, making sure my answer gave the same as that one, but not looking at the real answer. As pointed out below, '!' binds higher than '%', and thus the answer this gives is wrong. Adding parens, and the fix that japhy adds brings this to 53:
    sub f { #234567890#234567890#234567890#234567890#234567890#23 $b=1;$b+=1+!($_%4)-!($_%100)+!($_%400)for 1..pop;$b%7 }

    -----------------------------------------------------
    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
    "I can see my house from here!"
    It's not what you know, but knowing how to find it if you don't know that's important

      Sorry, Masem. I trimmed it down to 47. Hey! 47!
      sub f { #234567890#234567890#234567890#234567890#234567890# $b=1;$b+=1+!$_%4-!$_%100+!$_%400for 1..pop;$b%7 }

      _____________________________________________________
      Jeff[japhy]Pinyan: Perl, regex, and perl hacker.
      s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: Golfing the day of Christmas
by runrig (Abbot) on Dec 13, 2001 at 22:28 UTC
    What are the golfing rules on modules? I always thought modules were kind of cheating, but then I saw a couple of them in the thread here. So I thought of using Date::Christmas, but that leads to an answer well over 60 characters, but then you could really cheat and release the same module with a shorter module and function name and easily beat anything here. Which is why I always thought using modules was sort of cheating (of course if you could sneak in a 'christmasday' function into perl's internals, that'd be cheating also, but impressive :-)
      Unofficially, you shouldn't use modules in perl golf unless specifically called for or given as an option in the problem. (Hypothetically, you could write a module that does the bulk of the work though still be of utility to others outside of the golf, release it to CPAN, then use that module in your golf to crush the other players). Typically golfs with 70 or more characters will be benefitted by a module use, while for golfs less than that, the module might be more trouble (as you have to add 5 + lenght(module name) automatically to use the module.

      -----------------------------------------------------
      Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
      "I can see my house from here!"
      It's not what you know, but knowing how to find it if you don't know that's important

Re: Golfing the day of Christmas
by Sidhekin (Priest) on Dec 13, 2001 at 22:42 UTC

    Are you guys using another version of perl than I am? At least here, the !-operator binds more tightly than the %-operator, so that (!$_%4 &c) just won't work.

    ... or am I just giving away your joke now ... ?

    Anyway, I guess this would work (checking the calendar). 65 chars; based on yours:

    sub f { #234567890#234567890#234567890#234567890#234567890#234567890#234567890 +#234567890 for(1..($b=pop)++){$b++;$b--if$_%4;$b++if$_%100;$b--if$_%400}$b%7 }
    ... or my best, so far, at 52:
    sub f { #234567890#234567890#234567890#234567890#234567890#2 $b+=$_%400?$_%100?$_%4?0:1:0:1for 1..($b=pop)++;$b%7 }

    Update: Checking the calendar again ...

    The Sidhekin
    print "Just another Perl ${\(trickster and hacker)},"


      This has a Golf Style Question attached to it...

      Your answer can be trimmed down to 47 characters:

      sub f { #23456789_123456789_123456789_123456789_123456789_12 $b+=$_%400?$_%100?$_%4?1:2:1:2for 1..pop;$b%7+1 }
      But this begs the question, should it be immediately reusable? My guess is yes, in which case this is a non-answer. The problem is that $b doesn't get reinitialized at the start of the sub so you have to either zero it or undef it in between every call.

      It returns correctly the first time, but incorrectly after that; is this ok for a golf? Or should it return correctly every time?

      jynx

        jynx, your sub does not even return the correct answer the first time, if $b has been set elsewhere -- you rely on it to be numerically zero initially. Moreover, you will get a 7, not a 0, for Sundays ... so on the whole, I can't say I like it.

        That is not to say my answer cannot be trimmed down. Indeed, I just did. And just so as not to leave your suggestion as the best (sorry; I really don't like it), I trimmed it to 46 chars:

        sub f { # 1 2 3 4 5 #234567890#234567890#234567890#234567890#234567890#23 $b+=!($_%4||/00$/&&$_%400)for 0..($b=pop);$b%7 }
        Comparing that to my first suggestion ... can you tell I really like the ternary operator? ;-)

        The Sidhekin
        print "Just another Perl ${\(trickster and hacker)},"

Re: Golfing the day of Christmas
by blakem (Monsignor) on Dec 14, 2001 at 06:11 UTC
    It comes in at 66 and cheats by using a module... but it was really just so I could take Time::Piece for a spin... I *really* like it! Perhaps this snippet doesn't highlight its strong points, but you should take a look at it. I will probably be cutting way down on my Date::Manip/Date::Calc/Time::Local/POSIX::strftime usage, in favor of Time::Piece.
    sub f{ #234567890#234567890#234567890#234567890#234567890#234567890#23456 use Time'Piece;(Time'Piece->strptime("25Dec".pop,"%d%b%Y"))->_wday }

    -Blake