#1
  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. #2
  3. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,070
    Rep Power
    9398
    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.
  4. #3
  5. 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.
  6. #4
  7. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,070
    Rep Power
    9398
    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.

    [edit] 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.
  8. #5
  9. 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]
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Posts
    832
    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.
  12. #7
  13. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,070
    Rep Power
    9398
    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.
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Posts
    832
    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.

    Comments on this post

    • requinix agrees : ah, I misread it is a couple of typos. you are right
  16. #9
  17. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,070
    Rep Power
    9398
    And my comment got lost.
    Originally Posted by requinix
    requinix agrees: ah, I misread it is a couple of typos. you are right

IMN logo majestic logo threadwatch logo seochat tools logo