2020.01.06
Source: adopted from here
Introduction¶
Year 2020 is a leap year. The algorithm to determine whether a year is leap year is as follows:
Definition of Leap Year
Every year that is exactly divisible by four is a leap year, except for years that are exactly divisible by 100, but these centurial years are leap years if they are exactly divisible by 400.
For example, the years 1800 and 1900 were not leap years, but the years 2000 and 2020 were.
Question¶
Write a function isLeapYear
to determine whether a given year is leap year.
isLeapYear 1800 / 0b
isLeapYear 1900 / 0b
isLeapYear 2000 / 1b
isLeapYear 2020 / 1b
Answer¶
The following implementation of isLeapYear
is borrowed from the official documentation side of Kx Systems.
isLeapYear:{mod[;2] sum 0=x mod\: 4 100 400};
isLeapYear 1800 / 0b
isLeapYear 1900 / 0b
isLeapYear 2000 / 1b
isLeapYear 2020 / 1b
Detailed explanations on above implementation:
- For any given year
x
, calculate the remainder ofx
divided by 4, 100 and 400, respectively.
x mod\: 4 100 400
- This gives a boolean to indicate whether the year
x
is exactly divisible by 4, 100 and 400, respectively.
0=x mod\: 4 100 400
- It shows
x
is exactly divisible by how many numbers among 4, 100 and 400. The result has a range of 0 to 3.
sum 0=x mod\: 4 100 400
-
mod[;2]
is a function projection, i.e. converting a two-parameter function to a single-parameter function. Let's defines:sum 0=x mod\: 4 100 400
ands
has values from 0 to 3:s=0
: It means thatx
is exactly divisible by none of 4, 100 and 400. In this case,mod[;2] s
is 0.s=1
: It means thatx
is only exactly divisible by 4. In this case,mod[;2] s
is 1.s=2
: It means thatx
is only exactly divisible by 4 and 100. In this case,mod[;2] s
is 0.s=3
: It means thatx
is exactly divisible by each of 4, 100 and 400. In this case,mod[;2] s
is 1.
What a clever implementation!
Alternatives¶
- Use vector operation and function application (the dot)
isLeapYear1:{{x;y;z} . 0=x mod\: 100 400 4};
- This implementation is also very efficient but it is more like Python style
isLeapYear2:{$[0=x mod 100;0=x mod 400;0=x mod 4]};
- Use vector operation and functional evaluation
isLeapYear3:{eval enlist[$],0=x mod\: 100 400 4};
- Use logic operator
isLeapYear4:{(0=x mod 400)| (0=x mod 4) & (0=x mod 100)};
Performance¶
Use the following command to run each function 100000 times and record the running time:
\t:100000 func each 1800 1900 2000 2020
Function | Run Time (ms) |
---|---|
isLeapYear1 |
348 |
isLeapYear2 |
390 |
isLeapYear3 |
398 |
isLeapYear4 |
563 |
isLeapYear |
572 |