# Is it a leap year?

This challenge is quite simple. You will take an input which will be a year from 1801 to 2400, and output if it is a leap year or not.

Your input will have no newlines or trailing spaces:

1954


You will output in any way that you like that clearly tells the user if it is or isn't a leap year (I will accept y or n for yes/no)

You can get a list of leap years here: http://kalender-365.de/leap-years.php I would note that leap years are not ever four years always. 1896 is a leap year, but 1900 is not. The years that follow this "skip" are:

1900
2100
2200
2300


Test cases:

1936 ->  y
1805 ->  n
1900 ->  n
2272 ->  y
2400 ->  y


EDIT: This is based on a standard Gregorian calendar: http://www.epochconverter.com/date-and-time/daynumbers-by-year.php

## The Catalogue

The Stack Snippet at the bottom of this post generates the catalogue from the answers a) as a list of shortest solution per language and b) as an overall leaderboard.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

## Language Name, N bytes


where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

## Ruby, <s>104</s> <s>101</s> 96 bytes


If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

## Perl, 43 + 2 (-p flag) = 45 bytes


You can also make the language name a link which will then show up in the snippet:

## [><>](https://esolangs.org/wiki/Fish), 121 bytes


/* Configuration */

var QUESTION_ID = 50798; // Obtain this from the url
// It will be like https://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 8478; // This should be the user ID of the challenge author.

/* App */

return "https://api.stackexchange.com/2.2/questions/" +  QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

function commentUrl(index, answers) {
return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}

jQuery.ajax({
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
data.items.forEach(function(a) {
var id = +a.share_link.match(/\d+/);
});
if (!data.has_more) more_answers = false;
comment_page = 1;
}
});
}

jQuery.ajax({
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
data.items.forEach(function(c) {
if (c.owner.user_id === OVERRIDE_USER)
});
else process();
}
});
}

var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;

var OVERRIDE_REG = /^Override\s*header:\s*/i;

function getAuthorName(a) {
return a.owner.display_name;
}

function process() {
var valid = [];

var body = a.body;
if(OVERRIDE_REG.test(c.body))
body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
});

var match = body.match(SCORE_REG);
if (match)
valid.push({
user: getAuthorName(a),
size: +match[2],
language: match[1],
});
else console.log(body);
});

valid.sort(function (a, b) {
var aB = a.size,
bB = b.size;
return aB - bB
});

var languages = {};
var place = 1;
var lastSize = null;
var lastPlace = 1;
valid.forEach(function (a) {
if (a.size != lastSize)
lastPlace = place;
lastSize = a.size;
++place;

.replace("{{NAME}}", a.user)
.replace("{{LANGUAGE}}", a.language)
.replace("{{SIZE}}", a.size)

var lang = a.language;
lang = jQuery('<a>'+lang+'</a>').text();

languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang, user: a.user, size: a.size, link: a.link};
});

var langs = [];
for (var lang in languages)
if (languages.hasOwnProperty(lang))
langs.push(languages[lang]);

langs.sort(function (a, b) {
if (a.lang_raw.toLowerCase() > b.lang_raw.toLowerCase()) return 1;
if (a.lang_raw.toLowerCase() < b.lang_raw.toLowerCase()) return -1;
return 0;
});

for (var i = 0; i < langs.length; ++i)
{
var language = jQuery("#language-template").html();
var lang = langs[i];
language = language.replace("{{LANGUAGE}}", lang.lang)
.replace("{{NAME}}", lang.user)
.replace("{{SIZE}}", lang.size)
language = jQuery(language);
jQuery("#languages").append(language);
}

}
body {
text-align: left !important;
display: block !important;
}

width: 290px;
float: left;
}

#language-list {
width: 500px;
float: left;
}

font-weight: bold;
}

table td {
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/codegolf/all.css?v=ffb5d0584c5f">
<div id="language-list">
<h2>Shortest Solution by Language</h2>
<table class="language-list">
<tr><td>Language</td><td>User</td><td>Score</td></tr>
<tbody id="languages">

</tbody>
</table>
</div>
<tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr>

</tbody>
</table>
</div>
<table style="display: none">
</tbody>
</table>
<table style="display: none">
<tbody id="language-template">
</tbody>
</table>

• You should be more clear: A given year is a leap year if and only if it is (divisible by 4)∧((divisible by 100)→(divisible by 400)). May 26 '15 at 11:34
• Your input will have no newlines or trailing spaces. Dang it, that would have saved me 2 bytes... May 26 '15 at 17:10
• You should extend the accepted input range to AD 1601 thru 2400. This covers two 400-year Gregorian cycles (which proleptically start on Monday). May 26 '15 at 18:17
• Does falsy if leap year and truthy if not a leap year count as "clearly tells the user if it is or isn't"? May 28 '15 at 21:27
• @lirtosiast I think so. A lot of user assume so. Jul 20 '16 at 13:58

# PowerShell, 31 bytes

I am excited to say that I golfed this shorter than the builtin!

param($a)!($a%(4,16)[!($a%25)])  Outputs true for leap years and false otherwise. Builtin: [datetime]::IsLeapYear($args[0])


Though, if I wanted to stretch the statement 'clearly tells the user if it is or isn't a leap year' and do something non-standard, I could save 3 bytes and use:

param($a)$a%(4,16)[!($a%25)]  This outputs 0 for leap years and 1 or higher for non-leap years, which I don't like since I'd prefer to return a more standard truthy value for leap years. ## LOLCODE, 228202 159 bytes HOW IZ I f YR a MOD OF a AN 100 O RLY? YA RLY MOD OF a AN 4 O RLY? YA RLY b R 1 OIC NO WAI MOD OF a AN 400 O RLY? YA RLY b R 0 NO WAI b R 1 OIC OIC IF U SAY SO  Ungolfed: HAI 1.3 BTW "HAI" does nothing functionally in current versions and does not throw an error if you omit it. HOW IZ I leap YR input I HAS A output DIFFRINT MOD OF input AN 100 AN 0 BTW Thanks @LeakyNun, In LOLCODE any non-empty values, i.e. 0, "", etc. default to WIN. O RLY? YA RLY BOTH SAEM MOD OF a AN 4 AN 0 O RLY? YA RLY output R WIN BTW "WIN" is true, but in the actual program I used 1 as a truthy value because it's shorter. OIC NO WAI DIFFRINT MOD OF a AN 400 AN 0 O RLY? YA RLY output R FAIL BTW "Fail" is false, but in the actual program I used 0 as a falsy value. NO WAI output R WIN OIC OIC FOUND YR output BTW This statement is implied in the golfed version. IF U SAY SO BTW "KTHXBYE", just like "HAI" has no functional purpose and throws no error on omission. KTHXBYE  In Python ungolfed, because LOLCODE is confusing: def leap: if(year % 100 != 0): if(year % 4 == 0): output = true else: if(year % 400 != 0): output = false else: output = true return(output)  • Would it be shorter to define a function? Jul 22 '16 at 16:55 • probably, but I will edit it later. Jul 22 '16 at 16:59 • You have updated the main code to be a function, but not the ungolfed code? Jul 23 '16 at 2:25 • I thought LOLCODE has automatic type coercion, meaning that any non-zero value is equivalent to WIN.. Jul 23 '16 at 2:38 • It is, but how could I use that? I don't think I am doing any casting. Jul 23 '16 at 2:41 # Mathematica, 15 bytes LeapYearQ@*List  Mathematica has a built-in for everything. List is there to make the integer input into a compact DateList object. Returns True or False. • LeapYearQ@{#}& for 14 – att Aug 15 '19 at 6:39 # PHP, 28 bytes Why calculate when there´s a builtin? <?=checkdate(2,29,$argv[1]);


prints 1 for leap year, empty string for no leap year.
Add + after <?= for 1/0.

INPUT Y?0DTREAD STR$(Y)+"/02/29"OUT,,,?1  Prints 0 1 if it's a leap year, otherwise prints 0 and errors. DTREAD parses a date string in the form of YYYY/MM/DD and gives the year, month, and day. It can also return the day of the week, and trying to get the day of the week of a day that doesn't exist (Feb. 29 of a non-leap year) will cause an error. This is shorter than the obvious answer using mod, because SB uses MOD instead of %, which takes up 3-5 characters. # PHP, 34 30 bytes echo+!($argn%($argn%25?4:16));  I'm using the + sign to convert false (which would normally be converted to an empty string) to 0, because that seems to comply closer to the "clearness" requirement (maybe not?). With standard truthy/falsy rules, 1 byte can be saved. Note: I shamelessly implemented the divisibility by 25 trick from @David Hammen. Without his algorithm it would be 37 bytes: <?=+!(($b=$argv[1])%400^$b%100^$b%4);  Run like this: echo 1900 | php -nR 'echo+!($argn%($argn%25?4:16));';echo  # Tweaks • Saved 4 bytes by using $argn
• Save one more byte on standard truthy/falsy with <1 instead of !() Feb 2 '17 at 2:45

# Haskell, 4341 39 bytes

l x=mod x(if mod x 25<1then 16else 4)<1


If x is divisible by 25, check if it is also divisible by 16, making it divisible by the least common multiple of 25 and 16, which is 400.
If x is not divisible by 25, check if it is divisible by 4.

Inspired by @David Hammen's answer in JavaScript.

• I don't know Haskell, but can ==0 be <1? May 28 '15 at 21:13
• You are right, it can. May 29 '15 at 9:04
• You can drop the spaces before then and else. Mar 1 '19 at 7:38
• The conditional can be equivalently expressed as (4+sum[12|mod x 25<1]) for a total of 33 bytes: Try it online! Mar 3 '19 at 9:24

# 05AB1E, 9 7 bytes

т‰0Kθ4Ö


Explanation:

т‰         # Divmod the (implicit) input by 100
#  i.e. 1900 → [19,00]
#  i.e. 1936 → [19,36]
#  i.e. 1991 → [19,91]
#  i.e. 2000 → [20,00]
0K       # Remove all 0s
#  i.e. [19,00] → [19]
#  i.e. [19,36] → [19,36]
#  i.e. [19,91] → [19,91]
#  i.e. [20,00] → [20]
θ      # Pop and get the last item
#  i.e. [19] → 19
#  i.e. [19,36] → 36
#  i.e. [19,91] → 91
#  i.e. [20] → 20
4Ö    # Check if it's divisible by 4 (and output the result implicitly)
#  i.e. 19 → 0 (falsey)
#  i.e. 36 → 1 (truthy)
#  i.e. 91 → 0 (falsey)
#  i.e. 20 → 1 (truthy)


# x86 machine code, 14 bytes

00000000: adfd ad2d 3030 74fa 86c4 d50a a803       ...-00t.......


Unassembled

AD         LODSW           ; SI += 2 to start with last two digits
FD         STD             ; set direction for LODSW to decrement
AD         LODSW           ; load two ASCII digit chars into AX
2D 3030    SUB  AX, '00'   ; convert to decimal, test if year ends in 00?
74 FA      JZ   -6         ; if so, look at the first two digits instead
86 C4      XCHG AL, AH     ; endian convert
D5 0A      AAD             ; base convert from 10 to binary
A8 03      TEST AL, 3      ; mod 4 = 0?


Input string in SI, output is ZF if is a leap year.

Explanation

If the year does not end in 00, it is a leap year if last two digits mod 4 is 0. If it does end in 00, it will be a leap year if the first two digits mod 4 is 0. Example:

Leap year:

• 1936: 36 mod 4 == 0
• 2400: 24 mod 4 == 0

NOT leap year:

• 1805: 05 mod 4 == 1
• 1900: 19 mod 4 == 3

Test Program Output

# Excel, 30 25 bytes

Because of an intentional bug in Excel to maintain compatibility with Lotus 1-2-3 the year 1900 is treated as a leap year. We can however shift the year by 400 before doing the calculation. The leap year bug then occurs in 1500, which we don't care about anyway. For the following formula A1 serves as input.

=DAY(DATE(A1+400,2,29))>1


# SpecBAS - 77

Not the shortest (but not the longest either).

1 INPUT y: PRINT y;"->";"ny"((y MOD 4=0 AND (y MOD 100<>0) OR y MOD 400=0)+1)


Uses the standard formula, then prints "n" or "y" based on return value (the final +1 at the end is due to strings being 1-based).

• I don't know the language, but based the fact that there are no booleans, you may be able to save some characters by using something like y MOD (4+12*(y MOD 100=0))=0. May 28 '15 at 22:49

# Python, 50 48 bytes

import calendar as y
def a(b):print(y.isleap(b))


# C#, 26 bytes

y=>DateTime.IsLeapYear(y);


C# lambda (Predicate) where the input is a int and the output is a bool. I use a builtin.

• You don't really need the lambda here, and I would argue the answer is more valid without it. Jan 13 '17 at 9:26
• @VisualMelon In the meta section, they ask for a function. (If I remember) Jan 14 '17 at 15:24
• Aye, but DateTime.IsLeapYear is a function ;) generally the rule is that it has to evaluate to a function if it isn't named, and strictly your current submission is meaningless (join the argument here!), while System.DateTime.IsLeapYear is fully typed (System.Func<int,bool>A=System.DateTime.IsLeapYear compiles fine) without demanding any user inference (or indeed the text in your answer which specifies the input and output types). Jan 14 '17 at 17:22

## BASH, 68 bytes

((!(y % 4) && ( y % 100 || !(y % 400)))) &&  echo "leap" || echo "no"


## Retina, 24 bytes

[^04]00$.+$*
....

^$ Try it online! # PHP, 45 bytes <?=date_create($argv[1].'-1-1')->format('L');


Not the shortest, but using built in functions. Totally not code-golf.

# Jelly, 8 bytes

ȷ2*ḍ¥×4ḍ


Try it online!

# Bash, 14 bytes

date -d$1/2/29  Try it online! Outputs via exit code, 0 for leap year and 1 otherwise. date -d STRING will display the date indicated by STRING. $1/2/29 represents February 29th of $1, the argument. If STRING is not valid, i.e. Feb 29 does not exist, then date errors out. # Ruby, 22 bytes ->n{1>n%(n%25<1?16:4)}  Try it online! The challenge is quite old, but I noticed there was no valid Ruby answer yet. Nothing particularly original, anyway. # D, 43 42 bytes T l(T)(T y){return!(y%4)&&y%100+!(y%400);}  Try it online! Another port of @HatsuPointerKun's C++ answer. ## C++, 50 43 bytes -7 bytes thanks to Zacharý int l(int y){return!(y%4)&&y%100+!(y%400);}  And the test code is : auto t = { 1936,1805,1900,2272,2400 }; for (auto&a : t) { std::cout << "Year : " << a << " is " << (l(a) ? "" : "NOT") << " a leap year\n"; }  • You can make it int l(int y){return(y%4==0&&y%100)+(y%400==0);} to save a few bytes Mar 29 '18 at 13:49 • I think making +(y%400==0) +!(y%400) might work as well. Apr 1 '18 at 18:54 • int l(int y){return!(y%4)&&y%100+!(y%400);} Nov 10 '18 at 20:21 # Kotlin, 30 bytes {it%4<1&&(it%100>0||it%400>0)}  Try it online! # Common Lisp, 46 bytes (=(mod(setq x(read))(if(>(mod x 25)0)4 16))0)  Try it online! Based on the David Hammen’s method. # MathGolf, 9 bytes 4♀*]÷~≤*  Try it online! ## Explanation 4 Push 4 ♀ Push 100 * Duplicate top two elements of stack and multiply (400) ] Wrap stack in array ([4, 100, 400]) ÷ Check input for divisibility with all array items ~ Dump array onto stack ≤ Check if divisibility by 100 is <= than divisibility with 400 * Multiply with the divisibility bool for 4, works like logical and  The trick is that ≤ ensures that if a number is divisible by 100, it must also be divisible by 400, but if it's not divisible by 100, anything goes. # Clam, 33 31 bytes =a*rp|e%a*"400"0&%a*"100"e%a*40  Try it online! -2 bytes thanks to ASCII-only Outputs true for leap years. Outputs false for other years ## Explanation =a*rp|e%a*"400"0&%a*"100"e%a*40 =a*r read input and store in a* p Print.. %a*"400" a* % 400 e == 0 0 | OR %a*"100" a* % 100 & AND %a*4 a* % 4 e == 0 0  Very awkward explanation, but basically what it does is this: print(year % 400 == 0 || (year % 100 && year % 4 == 0))  Clam follows JS rules for truthy and falsey values, meaning year % 100 is true if it does not equal 0 (and it's shorter than adding an e before it and an 0 after it) Resulting JS: myVar = read(); console.log(year % 400 == 0 || (year % 100 && year % 4 == 0));  • ew 8552. use something nicer like 4545 pls Jan 8 '19 at 6:18 • jk, 31 Jan 8 '19 at 6:19 • also pls fix your indentation in the explanation :| Jan 8 '19 at 6:27 • fixed that year % 100 thing Jan 8 '19 at 6:42 # Japt-h!, 8 bytes Input is taken as a string. k0 ò o%4  Try it online! # Haskell, 35 bytes l x|x!25<1=x!16<1 l x=x!4<1 (!)=mod  Try it online! # PHP, 35 34 bytes -1 byte thanks to 640KB <?=date(L,strtotime($argv[1].-1));


Try it online!

Came across the L option in the PHP date formatter, which returns if the year of the date is a leap year. After that, it was just a matter of trying to get the timestamp of the year in the shortest way (though I'm not too confident this is the shortest)

## Reg, 14 bytes

1¿:%[4|]%[;]


Try it online!

How it works (because it contains unprintable characters)

• Maybe leave a note as to why you've spelt it Reg when the link goes to Keg, so people like me don't think you've just made a typo.
– Jo King
Aug 15 '19 at 7:20
• Okay. We have decided to rename "Unofficial Keg" as "Reg."
– user85052
Aug 15 '19 at 7:33

## Wd, 10 8 bytes

Ö♦Ç⌂╬§Γ


## Explanation:

Uncompressed:

25m4&16|m!

25m        % If the input is modulo-able by 25:
4&      % Return 4
16|   % Otherwise, return 16
m! % Modulo input by the value. Negate the value.
`