Skip to content

Instantly share code, notes, and snippets.

@CodeGolfScotland
Last active February 8, 2017 21:28
Show Gist options
  • Save CodeGolfScotland/3aaae4e710c74ebfc5e1750c0fed52db to your computer and use it in GitHub Desktop.
Save CodeGolfScotland/3aaae4e710c74ebfc5e1750c0fed52db to your computer and use it in GitHub Desktop.
Code Golf January 2017

January 2017 - Is it a leap year?

Task

Return a boolean true or false based on whether the given year is a leap year.

The given integer may be positive or negative.

Keep In Mind

it is a leap year on every year that is evenly divisible by 4
except every year that is evenly divisible by 100
unless the year is also evenly divisible by 400

Examples:

(2017) => false

(2016) => true

(1992) => true

(1066) => false

(-7)   => false

*^You can assume that you will always recieved valid input

About Code Golf Scotland

@icambridge
Copy link

PHP

function x($y){return !!(new DateTime($y.'-1-1'))->format('L');}

Character count 70

@briward
Copy link

briward commented Jan 5, 2017

Language: Ruby
Length: 28
Solution:

def l(y)Date.new(y).leap?end

@alessandrozucca
Copy link

Language: Golang
Length: 53
Solution:

func l(y int)bool{return!(y%4!=0||y%100==0&&y%400!=0)}

@rawkode
Copy link

rawkode commented Jan 5, 2017

Language: Python
Length: 47
Solution:

import calendar as c
def l(y): print c.isleap(y)

@ciaranmcnulty
Copy link

A novelty solution

Language: PHP

Length: 62

Solution:

function d($y){$s=strtotime;return$s("$y-2-29")==$s("$y-3-1");}

@ciaranmcnulty
Copy link

Logic solution:

Language: PHP

Length: 49

Solution:

function l($y){return!($y%4||!($y%100)&&$y%400);}

@barric0de
Copy link

Language: Perl
Length: 51
Solution:

use Date::Leapyear;sub a{isleap(@_)?'true':'false'}

@ciaranmcnulty
Copy link

ciaranmcnulty commented Jan 5, 2017

Language: Hack

Length: 35

Solution:

$l=$y==>!($y%4||!($y%100)&&$y%400);

@ciaranmcnulty
Copy link

ciaranmcnulty commented Jan 5, 2017

Language: JS

Length: 24

Solution:

y=>!(y%4|!(y%100)&y%400)

@joaquinferrero
Copy link

joaquinferrero commented Jan 5, 2017

Language: Perl 6
Length: 37
Solution:

sub l{Date.new(:$^year).is-leap-year}

Demo:

$ perl6 -e 'sub l{Date.new(:$^year).is-leap-year}; say l(2016); say l(2017); say l(2020)'
True
False
True

Copy link

ghost commented Jan 5, 2017

Language: JavaScript
Length: 19
Solution:

y=>!(y%(y%25?4:16))

@CraigMorton
Copy link

My very silly JS solution.

Language: Javascript

Length: 32

Solution:

f=y=>y%400?y%100?y%4?!1:!0:!1:!0

@HDudzus
Copy link

HDudzus commented Feb 8, 2017

I like BrianDGLS's 29 character solution very much for it's mathematical cleverness, although I have to get used to implicit type conversion. :-) It wouldn't be that short in Haskell with its strong typing (no implicit type conversions) and long keywords. The standard solution perhaps would read in Haskell:

Language: Haskell
Length: 42
Solution:

f y=y`mod`4==0&&y`mod`100/=0||y`mod`400==0

Anyway, I had the most fun solving it with a little 3 step implication checker:
The idea is the following chain of implications which is true for year x if and only if x is the number of a leap year:

divisible by 100 ==> divisible by 400 ==> divisible by 1 (ok, trivial) ==> divisible by 4

Because Bool implements an ordering of False < True implications can be checked by comparisons:

(A ==> B) <==>  !(A && !B) <==> !(A > B) <==> (A <= B)

Leap years can therefore be characterised with the following algorithm:

  1. Compute the remainders after division by 100, 400, 1, 4: mod<$>[2017]<*>[100,400,1,4] -- -> [17,17,0,1] (using lists as applicative functor, expressing 4 computations "in one", gives this solution it's beauty, doesn't it)
  2. Check if the remainders are 0: map(==0)[17,17,0,1] -- -> [False,False,True,False]
  3. Check if the list of booleans is in ascending order (a fixpoint of the sort function) (\l -> sort l == l) [False,False,True,False] -- -> False or nicer and shorter with functions as applicative functor: ((==)<*>sort) [False,False,True,False] -- -> False

That's it, a an implication checker for uniform predicate functions. Using lists as applicative functors like that is helpful everytime a problem has a number of uniform mathematical constraints. The sort function needs to be imported from Data.List, so it's a solution for the lambdabot.

Language: Haskell (Lambdabot)
Length: 50
Solution: (my favourite of those in Haskell)

f x=(==)<*>sort$map(==0)$mod<$>[x]<*>[100,400,1,4]

Mapping is enough here, saving 3 chars: Length 47

f x=(==)<*>sort$map((==0).(mod x))[100,400,1,4]

Without the sort function, step 3 is more tricky. A little too tricky to be really nice, I think, but hey, uncurrying the comparison function in order to apply it to zipped tuples of consecutive list elements!

Language: Haskell
Length: 66
Solution:

f x=all(uncurry(<=))$zip<*>tail$map(==0)$mod<$>[x]<*>[100,400,1,4]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment