### Thread: Leap-Year, no upper limit

1. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Jan 2013
Posts
3
Rep Power
0

#### Leap-Year, no upper limit

Hi guys,

My task is to write a regular expression which accept leap-year only, and the first year have to be 1584 without upper limit. Could someone help me with redo this expr. ?
Code:
`(15(8[48]|9[26]))|((1[6-9]|[2-9]\d)(0[48]|[13579][26]|[2468][048]))|(([2468][048]|16|3579[26])00)`
2. And you can't do it in code? It would be much, much easier to do it in some code than in a regular expression.
3. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Jan 2013
Posts
3
Rep Power
0
Originally Posted by requinix
And you can't do it in code? It would be much, much easier to do it in some code than in a regular expression.
That's the point to do this by regular expression, it is my homework.
4. I tend to think of the problem going from generic to specific:
* Anything with five or more digits is valid
* If the first digit is 2-9 and there are three more digits then it's valid
* If the first is 1, second is 6-9, and there are two more digits then it's valid
* If the first is 1, second is 5, third is 9-9 (=9), and there is another digit then it's valid
* If the first is 1, second is 5, third is 8, and fourth is 4-9 then it's valid

You can just as easily reverse those. Probably more efficient to do so, actually.

 That only meets the "after 1584" and not the "only leap years" requirements. I'm just demonstrating how I would go about solving the problem.
Last edited by requinix; January 25th, 2013 at 12:41 PM.
5. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Jan 2013
Posts
3
Rep Power
0
Is it good ?
Code:
`[1-9][0-9]{4,}|[2-9][0-9]{3,}|1[6-9][0-9]{2}|159[0-9]|158[4-9]`
6. No Profile Picture
Contributing User
Devshed Novice (500 - 999 posts)

Join Date
Jun 2012
Location
Paris area, France
Posts
846
Rep Power
496
No time to do the full thing right now, but a quick try, limiting the range from 1600 to 2999, but it could be adapted quite easily to the full range:

Code:
`(16|20|28)00|\d\d[1-9]([02468][048]|[13579][26])|0[48]`
I've tried it with about 30 miscellaneous values, it seems to be working.
7. But it permits 1900. (Also has a couple typos.)

Here's a similar version for 1000-2999:
Code:
`(1[26]|2[048])00|[12]\d(0[48]|[13579][26]|[2468][048])`
Last edited by requinix; January 25th, 2013 at 05:03 PM.
8. No Profile Picture
Contributing User
Devshed Novice (500 - 999 posts)

Join Date
Jun 2012
Location
Paris area, France
Posts
846
Rep Power
496
My proposal does qualify 1600, 2000 or 1904 as leap years, but does not consider 1700, 1800 or 1900 as leap years. Which is correct. A straight copy and past under Perl works not so bad, as shown in the following debug session:

Code:
```  DB<1> print "leap" if 1600 =~ /(16|20|28)00|\d\d[1-9]([02468][048]|[13579][26])|0[48]/
leap
DB<2> print "leap" if 1700 =~ /(16|20|28)00|\d\d[1-9]([02468][048]|[13579][26])|0[48]/

DB<3> print "leap" if 1800 =~ /(16|20|28)00|\d\d[1-9]([02468][048]|[13579][26])|0[48]/

DB<4> print "leap" if 1900 =~ /(16|20|28)00|\d\d[1-9]([02468][048]|[13579][26])|0[48]/

DB<5> print "leap" if 1904 =~ /(16|20|28)00|\d\d[1-9]([02468][048]|[13579][26])|0[48]/
leap
DB<6> print "leap" if 2000 =~ /(16|20|28)00|\d\d[1-9]([02468][048]|[13579][26])|0[48]/
leap
DB<7> print "leap" if 2004 =~ /(16|20|28)00|\d\d[1-9]([02468][048]|[13579][26])|0[48]/
leap```
Having said that, I just did it for the fun in less than 5 minutes, looking back to it, there are some parenthesis errors or missing characters compared to what I was really thinking about, so probably some errors on some other cases. After a few more minutes, the following is closer to what I had in mind:

Code:
`/(16|20|24|28)00|\d\d([2468][048])|(\d\d[13579][26])|(\d\d0[48])/`
As I said, it is designed to work from 1600 to 2999. Actually, thinking about it, it should probably be good from 1204 to 3196, unless no years before 1584 should never be leap. What needs to be changed if the first part ((16|20|24|28)00|), to make it more general in the management of centuries. No big deal to find if MC can be divided by 4, just the same logic as what is used if DU is a multiple of 4 later in the regex will do it. But since this is a homework, I'll leave it to the OP to complete this.

Managing dates before 1584 can be a bit trickier, but we don't really know what exact rules should apply for them or whether they should even be considered. Just as a reminder, there were leap years before 1584, the Julian calendar has leap years every 4 years, it is just that, for example, 1000, 1100, 1300, 1400 and 1500 would not have been leap in the rules of the Gregorian calendar, while they were leap in the Julian calendar. If we don't have to worry about years before 1584, then there is nothing to change for years before 1600, the only change left to be made is to make the rule more general for years after 3196, as described above.