Author Topic: Bplus will like this one...  (Read 2828 times)

0 Members and 1 Guest are viewing this topic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Bplus will like this one...
« on: December 24, 2020, 03:27:06 pm »
I was working around on working up a custom calendar for 2021, for my PC, and a light bulb lit up over my head.  Last year, when we were sorting out whether a year was a leap year, or not, me and Bplus worked for a week or more to debug the ExtendedTimer routine.

We didn't have to, thanks to already existing code which we had in our toolbox, that we were too blind to use...

/SIGH!!   It's the story of my life -- spend forever to do something the hard way, and then POOF turn around a little while later and realize it was sooooo simple to begin with.  It's like rewiring a whole house, when all you needed to do was flip on the light switch to turn on the lights in the kitchen.

I present to you, IsLeapYear, in its simplest form:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(1200, 720, 32)
  2.  
  3. FOR i = 1900 TO 2036
  4.     PRINT i, IsLeapYear(i),
  5.  
  6.  
  7.  
  8. FUNCTION IsLeapYear (yyyy) 'use 4 digit year
  9.     IF GetDay(2, 29, yyyy) <> GetDay(3, 1, yyyy) THEN IsLeapYear = -1
  10.  
  11. FUNCTION GetDay (m, d, y) 'use 4 digit year
  12.     'From Zeller's congruence: https://en.wikipedia.org/wiki/Zeller%27s_congruence
  13.     mm = m: dd = d: yyyy = y
  14.     IF mm < 3 THEN mm = mm + 12: yyyy = yyyy - 1
  15.     century = yyyy MOD 100
  16.     zerocentury = yyyy \ 100
  17.     result = (dd + INT(13 * (mm + 1) / 5) + century + INT(century / 4) + INT(zerocentury / 4) + 5 * zerocentury) MOD 7
  18.     IF result = 0 THEN
  19.         GetDay = 7
  20.     ELSE
  21.         GetDay = result
  22.     END IF
  23.     'Function changed to return a numeric value instead of a string for this program
  24.     '    SELECT CASE result
  25.     '        CASE 7: GetDay$ = "Saturday"
  26.     '        CASE 1: GetDay$ = "Sunday"
  27.     '        CASE 2: GetDay$ = "Monday"
  28.     '        CASE 3: GetDay$ = "Tuesday"
  29.     '        CASE 4: GetDay$ = "Wednesday"
  30.     '        CASE 5: GetDay$ = "Thursday"
  31.     '        CASE 6: GetDay$ = "Friday"
  32.     '    END SELECT
  33.  

We had a routine to get the day of the week, from any given date, and it's been working FOREVER AND EVER!!  As long as the 29th isn't the same day as the 1st of the next month, we have a leap year.  Otherwise, we don't...

One line logic, with no need to do math for mod 4, /400 but not 2000, except when - 29.6 or multiplied by 13.25...

Now, the question is:  Why didn't anyone point out how simple this logic is to us back then??  :P
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Bplus will like this one...
« Reply #1 on: December 24, 2020, 04:15:08 pm »
Just a comment. A completely unnecessary one, cause the code speaks for itself.

This isn't really lone-line logic, though, right? Otherwise the whole program would be one line. You still have to do the hard part of filtering out the leap year cases by *some* calculation, its just in a different function now.

Never mind me though, carry on!


You're not done when it works, you're done when it's right.

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Bplus will like this one...
« Reply #2 on: December 24, 2020, 04:20:38 pm »
This reminds me of code I had for checking the amount of days between two dates. It had a function for determining leap year as well.
EDIT: I removed the other unnecessary code because you are focusing on leap years.

Code: QB64: [Select]
  1.  
  2. DIM i
  3. FOR i = 1900 TO 2036
  4.     PRINT i, check_leap_year(i)
  5.  
  6. FUNCTION check_leap_year (year AS LONG)
  7.     IF year MOD 4 = 0 AND year MOD 100 <> 0 OR year MOD 400 = 0 THEN
  8.         check_leap_year = 1
  9.     ELSE
  10.         check_leap_year = 0
  11.     END IF

  [ You are not allowed to view this attachment ]  
« Last Edit: December 24, 2020, 04:36:02 pm by SpriggsySpriggs »
Shuwatch!

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: Bplus will like this one...
« Reply #3 on: December 24, 2020, 05:12:09 pm »
Here's a function I think I picked it up on a VB forum somewhere.  I kept it because it was a one-line method.  Just throwing it into the mix because I have nothing else to do right now... :)

- Dav

Code: QB64: [Select]
  1. FOR t = 2020 TO 2060
  2.     IF Leapyear(t) THEN PRINT t; "is a leap year"
  3.  
  4. FUNCTION Leapyear (year)
  5.     Leapyear = (year MOD 4 = 0) XOR (year MOD 100 = 0) XOR (year MOD 400 = 0) XOR (year = 4840)
  6.  
« Last Edit: December 24, 2020, 05:19:04 pm by Dav »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Bplus will like this one...
« Reply #4 on: December 24, 2020, 05:37:14 pm »
At the moment I dont have time to study this but in my recollection of that week with extended timer, we started out with something from the toolbox and it worked OK going forward in time but yours truly wanted to go back in time and that's when hell week began ;-))

I wanted to go back in time to say how long it was (in seconds?) since this or that event in human history. It was for a New Years count down app that Ron77 had started. I am trying to remember if that was last year or this?

If it was for this year then there's still time to finish that up :)