| Bytes | Lang | Time | Link |
|---|---|---|---|
| 179 | Hatchback | 241211T201259Z | madeforl |
| 027 | AWK | 241206T205855Z | xrs |
| 006 | 05AB1E | 181205T130636Z | Kevin Cr |
| 006 | Vyxal | 241204T042215Z | emanresu |
| 034 | Regex any | 240421T111126Z | emanresu |
| nan | 230914T210509Z | RARE Kpo | |
| 016 | x86 machine code | 181221T214239Z | 640KB |
| 006 | Thunno 2 t | 230610T134617Z | The Thon |
| 005 | Arturo | 221111T211247Z | chunes |
| 047 | Go | 221111T210152Z | bigyihsu |
| nan | Fig | 221111T204927Z | Seggan |
| 010 | Vyxal | 220107T131212Z | SjoerdPe |
| 100 | Pascal | 221110T132011Z | Kai Burg |
| 037 | Python2 | 150528T030606Z | mathmand |
| 125 | Python | 220110T160553Z | Mr.McNug |
| 028 | Ruby | 220106T173003Z | wteuber |
| 039 | Forth gforth | 201113T090918Z | Razetime |
| 026 | Python 3 | 201113T123858Z | Jitse |
| 005 | Japt ! | 190108T145713Z | Shaggy |
| 025 | Excel | 190402T160708Z | orthople |
| 226 | Stackylogic | 160722T121519Z | Destruct |
| 108 | W d | 200101T104217Z | user8505 |
| 014 | Reg | 190815T044602Z | user8505 |
| 034 | PHP | 190314T233127Z | Jo King |
| 019 | Haskell | 190402T115038Z | primo |
| 039 | Haskell | 150528T204913Z | AplusKmi |
| 082 | Swift | 190301T191418Z | onnoweb |
| 035 | Haskell | 190301T075839Z | dfeuer |
| 008 | Japt h! | 190205T162112Z | Oliver |
| 020 | Java 8 | 160720T142516Z | Kevin Cr |
| 019 | JavaScript | 190109T222440Z | Oliver |
| 022 | TSQL | 160902T120839Z | S.Karras |
| 031 | Clam | 190108T014620Z | Mayube |
| 009 | MathGolf | 190108T074257Z | maxb |
| 046 | Common Lisp | 181222T114225Z | Renzo |
| 012 | APL | 150526T114942Z | FUZxxl |
| 033 | C gcc | 181205T114857Z | bznein |
| 007 | Jelly | 181205T020935Z | Dennis |
| 030 | Kotlin | 181205T011429Z | snail_ |
| 021 | Javascript ES6 | 150528T145954Z | David Ha |
| 043 | C++ | 180326T072749Z | HatsuPoi |
| 042 | D | 181110T201900Z | Adalynn |
| 022 | Ruby | 180509T070410Z | G B |
| 049 | ActionScript 2.0 | 180327T103717Z | Jhynjhir |
| 103 | Whitespace | 180327T100240Z | Kevin Cr |
| 014 | Bash | 180325T123715Z | user4180 |
| 009 | MATLAB + Aerospace Toolbox | 171018T200322Z | Tom Carp |
| 008 | Jelly | 171018T194110Z | Erik the |
| 030 | PHP | 160720T140056Z | aross |
| 040 | SmileBASIC | 170202T140131Z | 12Me21 |
| 028 | PHP | 170202T023453Z | Titus |
| 045 | PHP | 170113T123057Z | Dexa |
| 030 | C | 160718T195408Z | user5634 |
| 015 | Mathematica | 161221T220323Z | JungHwan |
| 024 | Retina | 161221T163711Z | Martin E |
| 081 | C | 150527T175803Z | Toby Spe |
| 068 | BASH | 160902T170759Z | michael5 |
| 023 | C# | 160902T083949Z | adrianmp |
| 159 | LOLCODE | 160722T154049Z | AAM111 |
| 031 | PowerShell | 160720T154238Z | ThePoShW |
| 026 | C# | 160720T135336Z | aloisdg |
| 048 | Python | 160720T055503Z | Daniel |
| 037 | Python | 160720T052040Z | Destruct |
| 011 | Pyth | 150526T185044Z | Dennis |
| 012 | CJam | 150526T170924Z | Dennis |
| 045 | PHP | 150604T100519Z | NorthBri |
| 056 | IBM System Z assembler | 150527T083613Z | Steve Iv |
| 013 | TIBASIC | 150526T152106Z | lirtosia |
| 027 | JavaScript ES6 | 150526T130148Z | edc65 |
| 057 | C | 150528T164949Z | Andrea B |
| 038 | Regex | 150527T072201Z | rr- |
| 028 | Julia | 150527T221109Z | Alex A. |
| 029 | R | 150527T204157Z | MickyT |
| 055 | sed | 150527T170112Z | Toby Spe |
| 041 | Befunge98 | 150527T164518Z | MegaTom |
| 077 | SpecBAS | 150527T092622Z | Brian |
| 027 | KDBQ | 150527T084635Z | WooiKent |
| 026 | Javascript ES6 | 150526T212527Z | Qwertiy |
| 014 | Pyth | 150526T105750Z | Jakube |
| 013 | Pip | 150526T175919Z | DLosc |
| 027 | Mathematica | 150526T112514Z | LegionMa |
| 016 | CJam | 150526T114044Z | Martin E |
Hatchback, 179 bytes
0 0 121 16 1 0 2 4 0 3 100 0 4 400 0 5 1 0 7 2400 10 6 1 15 6 2 6 6 0 110 10 6 1 15 6 3 9 6 5 6 6 0 110 10 6 1 15 6 4 9 6 5 6 6 0 110 10 6 1 8 6 7 6 6 0 121 13 0 0 0 10 13 0 65535
AWK, 27 bytes
$0=$1%4<1&&$1%100||$1%400<1
Prints 1 if leap year or nothing.
Raku (Perl 6) (rakudo), 47 bytes
My first attempt at Raku, a simple port:
say (my$x=@*ARGS[0])%4 <1&&$x%100 >1||$x%400 <1
But ATO doesn't seem to like it. Some test cases:
raku -e 'say (my$x=@*ARGS[0])%4 <1&&$x%100 >1||$x%400 <1' 1800
False
raku -e 'say (my$x=@*ARGS[0])%4 <1&&$x%100 >1||$x%400 <1' 1900
False
raku -e 'say (my$x=@*ARGS[0])%4 <1&&$x%100 >1||$x%400 <1' 2000
True
raku -e 'say (my$x=@*ARGS[0])%4 <1&&$x%100 >1||$x%400 <1' 199900
False
raku -e 'say (my$x=@*ARGS[0])%4 <1&&$x%100 >1||$x%400 <1' 1999000
False
raku -e 'say (my$x=@*ARGS[0])%4 <1&&$x%100 >1||$x%400 <1' 19990000
05AB1E, 9 7 6 bytes
тÖoooÖ
-1 byte porting @emanresuA's Vyxal answer, so make sure to upvote that answer as well!
Try it online or verify all test cases.
Original 9 7 bytes approach:
т‰0Kθ4Ö
Try it online or verify all test cases.
Explanation:
тÖ # Check whether the (implicit) input is divisible by 100
# i.e. 1900 → 1
# i.e. 1936 → 0
# i.e. 1991 → 0
# i.e. 2000 → 1
ooo # Take 2 to the power that three times
# i.e. 1 → 2 → 4 → 16
# i.e. 0 → 1 → 2 → 4
Ö # Check whether the (implicit) input is divisible by that
# (and output the result implicitly)
# i.e. 1900 and 16 → 0 (falsey)
# i.e. 1936 and 4 → 1 (truthy)
# i.e. 1991 and 4 → 0 (falsey)
# i.e. 2000 and 16 → 1 (truthy)
т‰ # 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)
Vyxal, 6 bytes
₁Ḋ›E²Ḋ
Try it Online! Shorter version of SjoerdPenning's answer.
₁Ḋ # Divisible by 100? yes -> 1, no -> 0
› # increment - yes -> 2, no -> 1
E² # 4 to the power of that - yes -> 16, no -> 4
Ḋ # Check if the input is divisible by that - 16 if divisible by 100, 4 otherwise
Regex (any), 34 bytes
([13579][26]|[2468][048]|0[48])0*$
The ([13579][26]|[2468][048]|0[48]) matches two-digit strings that are multiples of 4 and aren't 00. The 0* extends that to potential matches of multiples of 40 or 400, both of which are necessarily leap years. This actually fails on inputs like 10000, but that's fine because it's out of the input range.
A leap year ERE is not a "language" per se but it should be easily adaptable to any flavor of regex
(I think it should work for any year, including negative years and also waaaaaaay in the future, assuming proleptic Gregorian calendar)
ereLEAP := /(([2468][048]|[13579][26]|(^|[0+-])[48])(00)?|0000|^[+-]?0*)$/
so an awk solution using it would be like
awk 'function leap(_) {
return _~"(([2468][048]|[13579][26]|(^|[0+-])" \
"[48])(00)?|0000|^[+-]?0*)$" ? "y" : "n" } ($2 = leap($1))^_'
and it properly captures the special edge cases, including strangely formatted inputs like negative zero :
-2400
-2000
-1600
-1200
-800
-400
-0
0
400
800
1200
1600
2000
2400
777778000
777778400
777778800
777779200
777779600
777780000
777780400
777780800
777781200
777781600
777782000
777782400
or ultra extreme inputs, like the year
9745314011399999080353382387875188310876226857595007526867
9064572129486907664261024656150658820102592253049162314086
6818345916986520309404657798729631265341953127769995647302
9870789655490053648352799593479218378873685597925394874945
746363615468965612827738803104277547081828589991914111200
x86 machine code, 16 bytes
00000000: fcad fdad 2d30 3074 fa86 c4d5 0aa8 03c3 ...-00t.........
Listing
FC CLD ; set direction for LODSW to increment
AD LODSW ; SI += 2 to start with last two digits
FD STD ; set direction for LODSW to decrement
LD:
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 LD ; if so, look at the first two digits instead
86 C4 XCHG AL, AH ; endian convert
D5 0A AAD ; base convert from 10 to word
A8 03 TEST AL, 3 ; mod 4 = 0?
C3 RET ; return to caller
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
Thunno 2 t, 6 bytes
ɦḋ0o4Ḋ
Port of Kevin Cruijssen's 05AB1E answer.
Explanation
ɦḋ0o4Ḋ # Implicit input
ɦḋ # Divmod by 100
0o # Remove 0s
4Ḋ # Divisible by 4?
# Implicit output
# of last item
Fig, \$11\log_{256}(96)\approx\$ 9.054 bytes
?%25x%4x%16
Port of Vyxal. Outputs 0 for truthy, positive numbers for falsey.
?%25x%4x%16
?%25x # If mod 25 is > 0
%4x # Print mod 4
%16 # Else print mod 16
Vyxal, 13 10 bytes
-3 bytes Thanks to Kevin Cruijssen
25Ḋ[16|4]Ḋ
Outputs 1 for truthy, 0 for falsy
Explanation
25Ḋ - is it divisible by 25?
[16 Ḋ - if so: check if its divisible by 16
|4]Ḋ - if not: check if its divisible by 4
Vyxal, 7 bytes
A port of Kevin Cruijssen's answer
₁ḋ0ot4Ḋ
Explanation
₁ḋ - divmod the input by 100
0o - remove all instances of 0 from the result
t4Ḋ - grab the tail of the divmod result and check if it's divisible by 4
Pascal, 100 B
This is a complete program according to and requiring a processor complying to ISO standard 7185 “Pascal” (level 0 sufficient).
It demonstrates the importance of sets in Pascal.
Note, + and − are left-associative thus the following is guaranteed to yield the expected result.
program p(input,output);var y:integer;begin read(y);write(0 in[y mod 4]-[y mod 100]+[y mod 400])end.
For the standard non-golfed version using Boolean operators and/or see RosettaCode.
Delphi/Free Pascal, 62 B
The .toInt64 “type helper” requires at least FPC version 3.0.0.
In FPC, {$mode Delphi} or {$mode objFPC} have to be selected so paramStr returns “long strings”.
Evidently, input is specified as the first argument on the command line.
{$mode Delphi}
uses sysUtils;begin write(isLeapYear(paramStr(1).toInt64))end.
This is pretty much the same as the RosettaCode implementation.
Python2 - 37 bytes
g=lambda x:(x%4or x%400and x%100<1)<1
Note that if a is a nonnegative integer, then a<1 is a short way of writing not bool(a). The last <1 thus effectively converts the expression in the parentheses to a boolean and negates the result.
Applying the function g to an integer n between 1801 and 2400 will return True if n is a leap year, and False otherwise.
Python, 125 bytes
y=int(input(""))
if y%100==0 and y!=2400:
print("n")
else:
if y%4==0:
print("y")
else:
print("n")
Ruby, 28 bytes
The lambda takes an Integer y representing the year and returns true or false.
->y{y%4<1&&y%100>0||y%400<1}
Use like this:
f=->y{y%4<1&&y%100>0||y%400<1}
f[2004]
# => true
or this:
f=->y{y%4<1&&y%100>0||y%400<1}
[1936,1805,1900,2272,2400].map(&f)
# => [true, false, false, true, true]
Explanation
y%4<1&&y%100>0- Years that are divisible by 4 but not by 100 are leap years, e.g. 2004
- Years that are divisible by 4 and also by 100 are not leap years, e.g. 1700
y%400<1- Years that are divisible by 400 are leap years, e.g. 1600
Forth (gforth), 48 39 bytes
: f 'd /mod over if d>s then 4 mod 0= ;
Same as Kevin Cruijssen's 05AB1E answer.
-9 bytes from Bubbler.
Python 3, 26 bytes
lambda n:n%4**-~(n%25<1)<1
Using Kevin Cruijssen's Java approach.
Python 3, 28 bytes
lambda n:(n%100or n/100)%4<1
Using Kevin Cruijssen's 05AB1E approach.
Japt -!, 8 5 bytes
Locale dependent; in my locale the timezone offset is GMT+0000 for leap years and GMT-0025 for all others.
ÐUT k
ÐUT k :Implicit input of integer U
Ð :Create Date object from (defaulting to the first day of the month)
U : The year U
T : The month 0 (months are 0-indexed in JS)
k :Get timezone offset as an absolute integer (0 or 25)
:Implicit output of logical NOT of result
And here's my original 8-byte solution, which isn't locale dependent and outputs 1 or 0 for true & false:
ÐUT#< Îu
Try it (includes all test cases)
ÐUT#< Îu :Implicit input of integer U
ÐUT :As above but ...
#< : With the date set to 60 (dates wrap over to the next month in JS, so this will give us either 29/02 or 01/03)
Î :Get 0-based index of month (1 or 2)
u :Modulo 2
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
Stackylogic, 226 bytes
Yes, that is right. I made a program in Stackylogic (non-TC), which was invented by Helka Homba, for the challenge found here.
Stackylogic has only binary input, so 10 (or more, any more digits will be ignored) bit binary must be used (least significant bit inputted first). Any dates outside the specified range might fail, as it simply checks what the inputted number is: it doesn't cover unnecessary dates
Not only is this my first challenge with stackylogic, but the first challenge with stackylogic at all.
Get ready for this mess:
1
0
1?
010
1?0
010
1?10
?1010
001010
?1010
?1010
?010
?10
?0
0
?
110
?10
11010
?010
11010
?1010
001010
?1010
?1010
?1010
?1010
?010
?0
110
?10
11010
?010
1010
01010
01010
?010
?0
110
?0
110
?0
110
1?0
?10
0?10
?10
?0
01
?
?<
0
This took me so long to make, because Stackylogic is the most confusing language I have encountered, and extremely unreadable: you have to know how the rest of the program has executed before you can read the current section being edited. I even had to add spaces for readability while creating it.
Meagre explanation
This is a simple explanation of what it does.
Stackylogic does not have any mathematical functions, so that made this harder. I had to hardcode most of it, to check if it was a specific number.
First, this program will do a NOR of the least significant bits, discarding them in the process. this means that if it is divisible by 4, it will proceed to the main part of the program, otherwise output 0.
Second, the pointer is carried over to the labyrinth of stackylogic, from here, if the next two bits are zero, it will instantly output 1 (as then it is divisible by 16, and so a leap year despite any other conditions), other wise it will check if it is not any of the numbers that is divisible by 4 but not a leap year, between 1801 and 2400.
To explain in detail, would involve making this post many times longer than it already is
W d, 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.
PHP, 35 34 bytes
-1 byte thanks to 640KB
<?=date(L,strtotime($argv[1].-1));
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)
Haskell, 43 41 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.
Swift, 82 bytes
func l(y:Int){y%4==0 && (y%100 != 0 || y%400==0) ?print("Y"):print("N")}
l(y:1936)
Java 8, 49 45 22 20 bytes
n->n%(n%25<1?16:4)<1
-2 bytes thanks to @OlivierGrégoire.
Some 22 bytes solutions:
n->n%25<1?n%16<1:n%4<1
n->(n%25<1?n%16:n%4)<1
java.time.Year::isLeap
Explanation:
n-> // Method with integer parameter and boolean return-type
n% <1 // Return whether the integer is divisible by:
(n%25<1? // If the input is divisible by 25:
16 // Check if its divisible by 16
: // Else:
4) // Check if its divisible by 4 instead
T-SQL 37 22 bytes
Saved 15 bytes thanks to BradC's comment.
The usual hardcoded variable for lack of a stdin.
e.g.
DECLARE @ NVARCHAR(4) = '2016'
Then the solution is:
PRINT ISDATE(@+'0229')
Clam, 33 31 bytes
=a*rp|e%a*"400"0&%a*"100"e%a*40
-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));
MathGolf, 9 bytes
4♀`*]÷~≤*
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.
Common Lisp, 46 bytes
(=(mod(setq x(read))(if(>(mod x 25)0)4 16))0)
Based on the David Hammen’s method.
APL, 16 14 12 characters
Returns 0 for a leap year, 1 for a non-leap year.
≥/⌽×4 25 4⊤⎕
Try this solution on tryapl.org. Note that I have changed the solution to the dfn {≥/⌽×4 25 4⊤⍵} as tryapl.com does not support ⎕ (take user input). Note that ⎕ is an empty box, not a missing character.
The same solution in J:
4 25 4>:/@|.@:*@#:]
Explanation
Dyadic ⊤ (encode) represents its right argument in the base specified by its left argument. I use base 4 25 4 in this solution. This represents the year y as a polynomial
y mod 400 = 100 a + 4 b + c where b < 100 and c < 4.
Let propositions α, β, and γ represent if a, b, and c are non-zero: Proposition γ is false if y is dividable by 4, β ∧ γ is false if y is dividable by 100 and α ∧ β ∧ γ is false if y is dividable by 400.
A truth table (* representing “don't care”) were proposition Δ represents if y is a leap-year obtains:
α β γ | Δ
0 0 0 | 1
1 0 0 | 0
* 1 0 | 1
* * 1 | 0
The following statement expresses Δ in α, β, and γ:
Δ = ¬((α → β) → γ)).
Due to the structure of this statement, one can express ¬Δ as the reduction ≥/⌽α β γ where ≥ implements ←. This leads to the answer I am explaining right now.
Jelly, 7 bytes
ọ4,25>/
How it works
ọ4,25>/ Main link. Argument: n (1801 - 2400)
ọ4,25 Test how many times n is divisible by 4 and 25.
>/ Verify that the order of 4 is higher than the order of 25.
Javascript (ES6), 21 characters
The standard rule is that y is a leap year if 4 divides y and if either 100 doesn't divide y or 400 does divide y. In code,
y%4 == 0 && (y%100 != 0 || y%400 == 0)
There's no need for that 100 and 400. Instead it suffices to check whether 16 or 4 divides y, with 16 chosen if 25 divides y, 4 otherwise. Golfed, this becomes
!(y%(y%25?4:16))
A javascript function that implements this is 21 characters long:
l=y=>!(y%(y%25?4:16))
Perl, 28 26 characters
Same idea, but in perl.
$_=$_%($_%25?4:16)?"n":"y"
Run using the -lp options. For example,
perl -lpe '$_=$_%($_%25?4:16)?"n":"y"'
With the test set as input, this produces
1936
y
1805
n
1900
n
2272
y
2400
y
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";
}
D, 43 42 bytes
T l(T)(T y){return!(y%4)&&y%100+!(y%400);}
Another port of @HatsuPointerKun's C++ answer.
Ruby, 22 bytes
->n{1>n%(n%25<1?16:4)}
The challenge is quite old, but I noticed there was no valid Ruby answer yet. Nothing particularly original, anyway.
ActionScript 2.0, 49 bytes
function a(b){trace(!(b%4)&&b%100+!(b%400)?1:0);}
function a(b){ } - define a function
trace( ); - that outputs
? - if
!(b%4) - the input divides by 4
&& - and
b%100 - doesn't divide by 100
+ - plus
!(b%400) - does divide by 400
1:0 - 1, else 0
Not a very good explanation, and I might have swapped some stuff, but this still confuses me, so this is the best you're going to get.
Whitespace, 103 bytes
[S S S N
_Push_0][S N
S _Duplicate_0][S N
S _Duplicate_0][T N
T T _Read_STDIN_as_integer][T T T _Retrieve][S N
S _Duplicate_input][S S S T T S S T N
_Push_25][T S T T _Modulo][N
T S T N
_If_0_jump_to_Label_TRUE][S S S T S S N
_Push_4][T S T T _Modulo][N
T S S N
_If_0_jump_to_Label_LEAP][N
S N
N
_Jump_to_Label_PRINT][N
S S T N
_Create_Label_TRUE][S S S T S S S S N
_Push_16][T S T T _Modulo][N
T S S N
_If_0_jump_to_Label_LEAP][N
S N
N
_Jump_to_Label_PRINT][N
S S S N
_Create_Label_LEAP][S S S T N
_Push_1][N
S S N
_Create_Label_PRINT][T N
S T _Print_as_integer]
Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.
Explanation in pseudo-code:
Integer i = STDIN-input as integer
If i modulo-25 is 0:
If i modulo-16 is 0:
Print 1
Else:
Print 0
Else-if i modulo-4 is 0:
Print 1
Else:
Print 0
Example runs:
Input: 1936
Command Explanation Stack Heap STDIN STDOUT STDERR
SSSN Push 0 [0] {}
SNS Duplicate top (0) [0,0] {}
SNS Duplicate top (0) [0,0,0] {}
TNTT Read STDIN as integer [0,0] {0:1936} 1936
TTT Retrieve at heap 0 [0,1936] {0:1936}
SNS Duplicate top (1936) [1936,1936] {0:1936}
SSSTTSSTN Push 25 [1936,1936,25] {0:1936}
TSTT Modulo [1936,11] {0:1936}
NTSTN If 0: Jump to Label_TRUE [1936] {0:1936}
SSSTSSN Push 4 [1936,4] {0:1936}
TSTT Modulo [0] {0:1936}
NTSSN if 0: Jump to Label_LEAP [] {0:1936}
NSSSN Create Label_LEAP [] {0:1936}
SSSTN Push 1 [1] {0:1936}
NSSN Create Label_PRINT [1] {0:1936}
TNST Print top as integer [] {0:1936} 1
error
Program stops with an error: No exit defined.
Try it online (with raw spaces, tabs and new-lines only).
Input: 2400
Command Explanation Stack Heap STDIN STDOUT STDERR
SSSN Push 0 [0] {}
SNS Duplicate top (0) [0,0] {}
SNS Duplicate top (0) [0,0,0] {}
TNTT Read STDIN as integer [0,0] {0:2400} 2400
TTT Retrieve at heap 0 [0,2400] {0:2400}
SNS Duplicate top (2400) [2400,2400] {0:2400}
SSSTTSSTN Push 25 [2400,2400,25] {0:2400}
TSTT Modulo [2400,0] {0:2400}
NTSTN If 0: Jump to Label_TRUE [2400] {0:2400}
NSSTN Create Label_TRUE [2400] {0:2400}
SSSTSSSSN Push 16 [2400,16] {0:2400}
TSTT Modulo [0] {0:2400}
NTSSN If 0: Jump to Label_LEAP [] {0:2400}
NSSSN Create Label_LEAP [] {0:2400}
SSSTN Push 1 [1] {0:2400}
NSSN Create Label_PRINT [1] {0:2400}
TNST Print top as integer [] {0:2400} 1
error
Program stops with an error: No exit defined.
Try it online (with raw spaces, tabs and new-lines only).
Input: 1991
Command Explanation Stack Heap STDIN STDOUT STDERR
SSSN Push 0 [0] {}
SNS Duplicate top (0) [0,0] {}
SNS Duplicate top (0) [0,0,0] {}
TNTT Read STDIN as integer [0,0] {0:1991} 1991
TTT Retrieve at heap 0 [0,1991] {0:1991}
SNS Duplicate top (1991) [0,1991,1991] {0:1991}
SSSTTSSTN Push 25 [0,1991,1991,25] {0:1991}
TSTT Modulo [0,1991,16] {0:1991}
NTSTN If 0: Jump to Label_TRUE [0,1991] {0:1991}
SSSTSSN Push 4 [0,1991,4] {0:1991}
TSTT Modulo [0,3] {0:1991}
NTSSN if 0: Jump to Label_LEAP [0] {0:1991}
NSSN Create Label_PRINT [0] {0:1991}
TNST Print top as integer [] {0:1991} 0
error
Program stops with an error: No exit defined.
Try it online (with raw spaces, tabs and new-lines only).
Bash, 14 bytes
date -d$1/2/29
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.
MATLAB + Aerospace Toolbox, 9 bytes
@leapyear
Anonymous function that determines if the passed year is a leap year, returning 1 for leap and 0 for not.
Ok so MATLAB has a built-in... But there we are.
Octave, 13 bytes
@is_leap_year
Octave also has a built-in... cost's 4 more bytes than MATLAB though.
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
SmileBASIC, 40 bytes
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, 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.
PHP, 45 bytes
<?=date_create($argv[1].'-1-1')->format('L');
Not the shortest, but using built in functions. Totally not code-golf.
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.
C, 81
I can do shorter, but this one neatly sticks to 'char' types, without parsing the argument (e.g. with atoi):
main(c,v)char**v;{char*p=*v+9;p-=2*(96==*p+p[1]);putchar("ynnn"[(2**p^p[1])&3]);}
It must be invoked with a name 4 characters long, because it makes the standard assumption that arguments immediately follow the program name, separated by NULs. Furthermore, it assumes that the single argument is encoded in ASCII and has no leading space.
Explanation:
main(c,v)
char**v;
{
char *p = *v+9;
if (p[0] + p[1] == '0'+'0')
p -= 2;
putchar("ynnn"[((*p << 1) ^ p[1])&3]);
}
*v+9 is the position of the 'tens' digit in v[1]+2.
If the 'tens' and 'units' characters add to 96, we end in 00, so back up two characters, so that 'tens' and 'units' point to the century number.
Now xor 'units' with twice the 'tens', mod 4. This works because 10==±2 mod 4, so the lower bit of the 'tens' can just toggle bit 1 of the 'units'. We use the result as an index into our remainders table, printing y only if the modular result is zero.
BASH, 68 bytes
((!(y % 4) && ( y % 100 || !(y % 400)))) && echo "leap" || echo "no"
C#, 23 bytes
y=>y%25<1?y%16<1:y%4<1;
Full source, including test cases:
using System;
namespace CountingLeapYears
{
class Program
{
static void Main(string[] args)
{
Func<int,bool>s=y=>y%25<1?y%16<1:y%4<1;
Console.WriteLine(s(1936)); //y
Console.WriteLine(s(1805)); //n
Console.WriteLine(s(1900)); //n
Console.WriteLine(s(2272)); //y
Console.WriteLine(s(2400)); //y
}
}
}
LOLCODE, 228 202 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)
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.
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.
Python, 50 48 bytes
import calendar as y
def a(b):print(y.isleap(b))
Python, 37 bytes
def c(s):return s%16*(s%25<1)<(s%4<1)
Pyth, 11 bytes
!%|F_jQ*TT4
This full program read from STDIN and prints True for leap years and False otherwise.
Thanks to @Jakube for suggesting Pyth and basically porting my CJam code.
Verify the test cases yourself in the Pyth Compiler/Executor.
How it works
jQ*TT Returns the evaluated input in base 10 × 10.
|F_ Swaps the digit order and reduces using logical OR.
So far, we've achieved 1954 -> [19, 54] -> 54 || 19.
!% 4 Returns the logical NOT of the result modulo 4.
This prints True for multiples of 4 and False otherwise.
CJam, 12 bytes
rS+2m<~e|4%!
This full program read from STDIN and prints 1 for leap years and 0 otherwise.
Verify the test cases yourself in the CJam interpreter.
How it works
r e# Read from STDIN.
S+ e# Append a space.
2m< e# Rotate two characters to the left.
~ e# Evaluate.
e# So far, we achieved "1954" -> "54 19" -> 54 19.
e| e# Logical OR; keep the leftmost non-zero integer.
4%! e# Logical NOT of the kept integer modulo 4.
e# This pushes 1 for multiples of 4 and 0 otherwise.
PHP - 45 bytes
$b=$argv[1]%400;echo !$b|!($b%4)&!!($b%100);
Nothing that special really, just abusing type-juggling.
IBM System Z assembler - 56 bytes.
(96 bytes of source. Previously 712 384 202 bytes of source, 168 byte executable).
Smaller version still. No longer saves caller's registers, changes to literal storage, changed addressing mode.
l CSECT
using l,15
l 5,y
n 5,f
bnz r
xr 4,4
l 5,y
d 4,c
ch 4,i
bne i
n 5,f
bnz r
i dc h'0'
r b *
y dc f'2004'
f dc f'3'
c dc f'100'
end
New version. This will ABEND with a S0C1 if it's a leap year, and loop if it isn't. Hopefully that fulfils the requirement of indicating the result.
l CSECT
ASMDREG
SYSSTATE archlvl=2
IEABRCX DEFINE
save (14,12)
larl r9,s
using s,r9
st 13,w+4
la 13,w
st 13,w+8
la 5,2004
st 5,y
n 5,=f'3'
bnz r
xr r4,r4
l 5,y
d r4,=f'100'
ch r4,=h'0'
bne i
n 5,=f'3'
bnz r
i dc h'0'
r b 0
s dc 0d'0'
y ds f
w ds 18f
ltorg
end
OK, so not the shortest (although it might be once we look at the actual executed code plus the interpreter size...)
leapyear CSECT
ASMDREG
SYSSTATE archlvl=2
IEABRCX DEFINE
save (14,12)
larl r9,staticArea
using staticArea,r9
st r13,w_savea+4 .Save callers savearea
la r13,w_savea .Address my savearea
st r13,w_savea+8 . and save it
open (O,OUTPUT) .open file
la r5,1936 .r5 = input year
st r5,years .Save year
cvd r5,double .Convert year to p-decimal
mvc edarea,=xl8'4020202020202120' .Move in edit mask
ed edarea,double+4 .Make packed decimal year printable
mvc outrec(4),edarea+4 .Move year string to output area
bas r10,isitleap .Call leap year routine
close (O) .Close files
b return .Branch to finish
isitleap ds 0h
mvi outrec+5,c'N' .Set default value
n r5,=f'3' .Are last 2 bits 0 (Divisible by 4)?
bnz notleap .No - not leap
xr r4,r4 .Clear R4
l r5,years .Reload r5 with year
d r4,=f'100' .divide r4/r5 pair by 100
ch r4,=h'0' .Remainder 0?
bne isleap .No - leap year
n r5,=f'3' .Quotient divisible by 4?
bnz notleap .No - not leap
isleap ds 0h
mvi outrec+5,c'Y' .Move in leap year indicator
notleap ds 0h
put O,outrec .Print output record
br r10 .Return to caller
* Program termination
return ds 0h
l r13,w_savea+4 .Restore callers savearea
return (14,12),,rc=0 .Restore registers and return
* storage areas
staticarea dc 0d'0'
outrec ds cl10
years ds f
w_savea ds 18f save area
edarea ds cl8 .edit area
double ds d
* Macros and literals
print nogen
O dcb recfm=F,lrecl=6,dsorg=PS,ddname=O,macrf=PM
print gen
*
ltorg literal storage
end
Output:
ABEND S0C1 for a leap year, S222 (when the CPU time has run out) if not.
1936 Y
1805 N
1900 N
2272 Y
2400 Y
(when run multiple times)
TI-BASIC, 20 17 16 13
Because it is tokenized, TI-BASIC is often competitive at simple math challenges, but not this one since there is no "divisible" command. Maybe it is after all, but this is still longer than CJam and Pyth.
This uses David Hammond's method.
not(fPart(Ans/4/4^not(fPart(sub(Ans
Old code at 16 bytes:
not(fPart(Ans/16not(fPart(sub(Ansnot(fPart(Ans/4
Ungolfed:
not(fPart(Ans/16) and not(fPart(Ans/100) and not(fPart(Ans/4))))
fPart( is "fractional part"; exponentiation has higher precedence than division. In TI-BASIC, close-parens are optional.
I use undocumented behavior of the sub( command, usually used to get a substring: when its argument is a number instead of a string, it divides the number by 100. It will work on a TI-83 or 84 series calculator.
20 -> 17 by rearranging code to allow removal of close-parens; 17 -> 16 by replacing 400 with 16; 16 -> 13 by using David Hammond's idea.
JavaScript (ES6) 27
The rule: (y%4==0) && (y%100!=0 || y%400==0)
Golfed: !(y%100<1&&y%400||y%4) (mainly using De Morgans's law)
A function implementing the rule:
l=y=>!(y%100<1&&y%400||y%4)
A test (run in Firefox) just to be sure:
l=y=>!(y%100<1&&y%400||y%4)
for(o=[],i=0;i<700;i++)
y=i+1800,
x=l(y),
o[i/100|0]=(o[i/100|0]||'')+y+(x?' <b>Y</b>':' <i>N</i>')+'\n'
R.innerHTML='<td>'+o.join('</td><td>')+'</td>'
console.log(o[1])
td { white-space: pre; font-family: monospace; padding: 8px}
b { color: red; }
i { color: blue; }
<table>
<tr id=R></tr>
</table>
C, 57 bytes
Takes the input from stdin, with or without trailing spaces/newline. Only works on little endian machines (yeah, like everyone is on BE these days). Outputs Y or N.
main(y){scanf("%d",&y);y=y%(y%100?4:400)?78:89;puts(&y);}
Explanation
Ungolfed:
int main(int y) {
scanf("%d", &y);
y = y % (y % 100 ? 4 : 400) ? 'N' : 'Y';
puts(&y);
}
First, scanf reads the year as an integer in y. Then, y is modulo'ed with 4 or 400 depending on whether the year is divisible by 100. If the remainder is zero, the ASCII code for Y is assigned to y, otherwise it gets the ASCII code for N. The value of y is now 0x000000??, where 0x?? is the assigned character. Being on a little-endian machine, in memory this is stored as ?? 00 00 00. This is a NULL-terminated C string, containing only the assigned characters. The address of y is passed to puts and the char is printed (with a trailing newline).
Regex, 83 62 38
Thanks to Toby for tips about combining both halves of the regex.
If we focus on 1801..2400 range only and assume input are integers:
(?!00)([02468][048]|[13579][26])(00)?$
Test in Ruby (^ = \A and $ = \Z because Ruby) for the desired range:
r = /(?!00)([02468][048]|[13579][26])(00)?\Z/
(1801..2401).each do |year|
leap = year % 4 == 0 && ((year % 100 != 0) || (year % 400 == 0))
leap_regex = !year.to_s[r].nil?
if leap != leap_regex
print 'Assertion broken:', year, " ", leap, " ", leap_regex, "\n"
end
end
(Bonus) for something that should work not only for 1801..2400, but for any non-negative year:
^\d*(0000|(?!00)([13579][26]|(^|[02468])[048])(00)?)$
Test in Ruby (^ = \A and $ = \Z because Ruby) for first 100000 years:
r = /\A\d*(0000|(?!00)([13579][26]|(\A|[02468])[048])(00)?)\Z/
100000.times do |year|
leap = year % 4 == 0 && ((year % 100 != 0) || (year % 400 == 0))
leap_regex = !year.to_s[r].nil?
if leap != leap_regex
print 'Assertion broken:', year, " ", leap, " ", leap_regex, "\n"
end
end
Julia, 30 28 bytes
y->(y%4<1&&y%100>0)||y%400<1
This creates an unnamed function that accepts an integer argument and returns a boolean value. To call it, give it a name, e.g. f=y->....
Ungolfed:
function f(y)
(y % 4 == 0 && y % 100 != 0) || y % 400 == 0
end
Example:
julia> for y in [1936, 1805, 1900, 2272, 2400] println(f(y)) end
true
false
false
true
true
true
R, 29
!(Y=scan())%%4&Y%%100|!Y%%400
Test run
> !(Y=scan())%%4&Y%%100|!Y%%400
1: 1936
2: 1805
3: 1900
4: 2272
5: 2400
6: 2200
7:
Read 6 items
[1] TRUE FALSE FALSE TRUE TRUE FALSE
sed, 55
s/00$//
y/0123456789/yNnNyNnNyN/
/N.$/y/ny/yn/
s/.\B//g
- First line divides exact centuries by 100.
- Second line gives 'N' to odd digits, 'y' to 4s, and 'n' to non-4s.
- Third line swaps 'y' and 'n' if there's an odd penultimate digit (because 10 is 2 mod 4)
- Final line deletes all but the last character
Note that non-leap years may be printed as n or N depending on whether they are even or odd. I consider this a creative interpretation of the rule which allows alternatives to 'yes' and 'no' without specifying that they have to be consistent.
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).
KDB(Q), 27 bytes
{0=x mod(4 400)0=x mod 100}
Explanation
0=x mod 100 / boolean of 100 divisibility
(4 400) / 0b -> 4, 1b -> 400
0=x mod / boolean of 4/400 divisibility
{ } / lambda
Test
q){0=x mod(4 400)0=x mod 100}1936 1805 1900 2272 2400
10011b
Javascript ES6, 32, 29, 26
Any of following lines works:
f=y=>new Date(y,2,0).getDate()&1
g=y=>!(y&3)^!(y%100)>!(y%400)
h=y=>!(y&3|y%100<1&&y%400)
Pyth, 19 15 14 bytes
xFm!%Q^d2[2TyT
Way too easy. Try it online: Demonstration or Test harness
edit: Missed, that you can print Truthy/Falsy values, instead of n/y. -4 byte
edit 2: Used the square root idea of Martin. -1 byte
Explanation
implicit: Q = input number
[ generate a list with the numbers:
2 2
T 10
yT 2*10 = 20
m map each number d to:
!%Q^d2 not(Q mod d^2) // True if Q % d^2 == 0 otherwise False
xF fold by xor
Pip, 13 bytes
This one was more interesting than it at first appeared. It took some finagling, but I was finally able to replace those lengthy references to 400 with 4 and the h variable (=100).
!(a%h?aa/h)%4
Outputs 1 for leap year, 0 for non-leap year. Explanation:
a is command-line argument (implicit)
a%h?aa/h If a is divisible by 100, divide it by 100; otherwise, leave it alone
( )%4 The result mod 4 is 0 if it's a leap year, nonzero otherwise
! Negate and (implicitly) print
Mathematica, 40 27 bytes, 17 chars
#∣4∧(#∣100<U+F523>#∣400)
Uses 17 chars, but 27 bytes. Thanks to @alephalpha for the tip. Note that the vertical bars are actually U+2223 for divides. The <U+F523> should be replaced with the corresponding character.
CJam, 18 16 bytes
q~[YAK]f{2#%!}:^
Gives 1 (truthy) for leap years and 0 (falsy) otherwise.
Explanation
q~ e# Read and eval input.
[YAK] e# Push an array containing 2, 10, 20 (the square roots of the
e# relevant divisors).
f{ } e# Map this block onto that array, also passing in the input year.
2# e# Square the divisor.
%! e# Modulo followed by logical negation. Gives 1 if the year is divisible
e# by the given divisor and 0 otherwise.
e# At this point we have one of the following arrays:
e# [0 0 0] - not a leap year
e# [1 0 0] - a leap year
e# [1 1 0] - not a leap year
e# [1 1 1] - a leap year
:^ e# Reduce XOR onto this array, which gives 1 if there is an odd number
e# of 1s and 0 if there's an even number.
