How to resolve the algorithm Find the last Sunday of each month step by step in the JavaScript programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Find the last Sunday of each month step by step in the JavaScript programming language

Table of Contents

Problem Statement

Write a program or a script that returns the last Sundays of each month of a given year. The year may be given through any simple input method in your language (command line, std in, etc). Example of an expected output:

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Find the last Sunday of each month step by step in the JavaScript programming language

Javascript:

The three provided JavaScript snippets achieve a similar goal: determining the last Sunday of each month in a given year. They use different approaches and syntaxes, but the basic principle remains the same. Here's a detailed explanation of each snippet:

First Snippet:

function lastSundayOfEachMonths(year) {
 var lastDay = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
 var sundays = [];
 var date, month;
 if (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) {
   lastDay[2] = 29;
 }
 for (date = new Date(), month = 0; month < 12; month += 1) {
   date.setFullYear(year, month, lastDay[month]);
   date.setDate(date.getDate() - date.getDay());
   sundays.push(date.toISOString().substring(0, 10));
 }
 return sundays;
}

console.log(lastSundayOfEachMonths(2013).join('\n'));
  • This snippet defines a function lastSundayOfEachMonths that takes a year as input and returns an array of the last Sunday of each month in that year.
  • It uses an array called lastDay to represent the number of days in each month, with the special case of February being adjusted for leap years.
  • It iterates through each month of the given year and sets the date object to the last day of the month.
  • It then subtracts the day of the week (0 for Sunday) from the date to get the last Sunday of the month.
  • Finally, it pushes the ISO date string (YYYY-MM-DD) of the last Sunday into the sundays array.
  • The snippet then logs the resulting array, which contains the last Sunday of each month in the year 2013.

Second Snippet:

(function () {
 'use strict';

 // lastSundaysOfYear :: Int -> [Date]
 function lastSundaysOfYear(y) {
   return lastWeekDaysOfYear(y, days.sunday);
 }

 // lastWeekDaysOfYear :: Int -> Int -> [Date]
 function lastWeekDaysOfYear(y, iWeekDay) {
   return [
     31,
     0 === y % 4 && 0 !== y % 100 || 0 === y % 400 ? 29 : 28,
     31,
     30,
     31,
     30,
     31,
     31,
     30,
     31,
     30,
     31,
   ].map(function (d, m) {
     var dte = new Date(Date.UTC(y, m, d));

     return new Date(Date.UTC(
       y,
       m,
       d - (
         (dte.getDay() + (7 - iWeekDay)) % 7
       )
     ));
   });
 }

 // isoDateString :: Date -> String
 function isoDateString(dte) {
   return dte.toISOString()
     .substr(0, 10);
 }

 // range :: Int -> Int -> [Int]
 function range(m, n) {
   return Array.apply(null, Array(n - m + 1))
     .map(function (x, i) {
       return m + i;
     });
 }

 // transpose :: [[a]] -> [[a]]
 function transpose(lst) {
   return lst[0].map(function (_, iCol) {
     return lst.map(function (row) {
       return row[iCol];
     });
   });
 }

 var days = {
   sunday: 0,
   monday: 1,
   tuesday: 2,
   wednesday: 3,
   thursday: 4,
   friday: 5,
   saturday: 6,
 };

 // TEST

 return transpose(
   range(2012, 2016)
     .map(lastSundaysOfYear)
 )
 .map(function (row) {
   return row
     .map(isoDateString)
     .join('\t');
 })
 .join('\n');

})();
  • This snippet uses functional programming techniques to achieve the same goal as the first snippet.
  • It defines a series of functions, including lastSundaysOfYear, lastWeekDaysOfYear, isoDateString, range, and transpose.
  • lastSundaysOfYear takes a year and returns the last Sunday of each month in that year.
  • lastWeekDaysOfYear takes a year and a day of the week and returns the last occurrence of that day in each month of the year.
  • isoDateString converts a Date object to an ISO date string.
  • range creates a range of numbers.
  • transpose transposes a 2D array (swaps rows and columns).
  • The snippet then uses these functions to generate the last Sunday of each month for the years 2012 to 2016.
  • Finally, the results are printed in a tab-separated format.

Third Snippet:

(() => {
 'use strict'

 // MAIN -----------------------------------------------
 // main :: IO ()
 const main = () =>
   console.log(unlines(
     map(
       compose(
         intercalate('\t'),
         map(isoDateString)
       )
     )(
       transpose(
         map(lastWeekDaysOfYear(days.sunday))(
           enumFromTo(2019)(2022)
         )
       )
     )
   ));

 // WEEKDAYS -------------------------------------------

 // lastWeekDaysOfYear :: Int -> Int -> [Date]
 const lastWeekDaysOfYear = iWeekDay =>
   y => map((d, m) =>
     new Date(Date.UTC(
       y, m, d - ((new Date(Date.UTC(y, m, d))
         .getDay() + (7 - iWeekDay)) % 7))))([
     31,
     0 === y % 4 && 0 !== y % 100 || 0 === y % 400 ? 29 : 28,
     31, 30, 31, 30, 31, 31, 30, 31, 30, 31
   ]);

 const days = {
   sunday: 0,
   monday: 1,
   tuesday: 2,
   wednesday: 3,
   thursday: 4,
   friday: 5,
   saturday: 6
 };

 // GENERIC FUNCTIONS-----------------------------------

 // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
 const compose = (...fs) =>
   x => fs.reduceRight((a, f) => f(a), x);

 // enumFromTo :: Int -> Int -> [Int]
 const enumFromTo = m => n =>
   Array.from({
     length: 1 + n - m
   }, (_, i) => m + i);

 // intercalate :: String -> [String] -> String
 const intercalate = s => xs =>
   xs.join(s);

 // isoDateString :: Date -> String
 const isoDateString = dte =>
   dte.toISOString()
   .substr(0, 10);

 // map :: (a -> b) -> [a] -> [b]
 const map = f => xs =>
   (Array.isArray(xs) ? (
     xs
   ) : xs.split('')).map(f);

 // If some of the rows are shorter than the following rows, 
 // their elements are skipped:
 // > transpose [[10,11],[20],[],[30,31,32]] == [[10,20,30],[11,31],[32]]

 // transpose :: [[a]] -> [[a]]
 const transpose = xss => {
   const go = xss =>
     0 < xss.length ? (() => {
       const
         h = xss[0],
         t = xss.slice(1);
       return 0 < h.length ? (
         [
           [h[0]].concat(t.reduce(
             (a, xs) => a.concat(
               0 < xs.length ? (
                 [xs[0]]
               ) : []
             ),
             []
           ))
          
<div id="sourcecode"/>

## Source code in the javascript programming language
{% raw %}
```javascript  
function lastSundayOfEachMonths(year) {
   var lastDay = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
   var sundays = [];
   var date, month;
   if (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) {
   	lastDay[2] = 29;
   }
   for (date = new Date(), month = 0; month < 12; month += 1) {
   	date.setFullYear(year, month, lastDay[month]);
   	date.setDate(date.getDate() - date.getDay());
   	sundays.push(date.toISOString().substring(0, 10));
   }
   return sundays;
}

console.log(lastSundayOfEachMonths(2013).join('\n'));


(function () {
   'use strict';

   // lastSundaysOfYear :: Int -> [Date]
   function lastSundaysOfYear(y) {
       return lastWeekDaysOfYear(y, days.sunday);
   }

   // lastWeekDaysOfYear :: Int -> Int -> [Date]
   function lastWeekDaysOfYear(y, iWeekDay) {
       return [
               31,
               0 === y % 4 && 0 !== y % 100 || 0 === y % 400 ? 29 : 28,
               31, 30, 31, 30, 31, 31, 30, 31, 30, 31
           ]
           .map(function (d, m) {
               var dte = new Date(Date.UTC(y, m, d));

               return new Date(Date.UTC(
                   y, m, d - (
                       (dte.getDay() + (7 - iWeekDay)) % 7
                   )
               ));
           });
   }

   // isoDateString :: Date -> String
   function isoDateString(dte) {
       return dte.toISOString()
           .substr(0, 10);
   }

   // range :: Int -> Int -> [Int]
   function range(m, n) {
       return Array.apply(null, Array(n - m + 1))
           .map(function (x, i) {
               return m + i;
           });
   }

   // transpose :: [[a]] -> [[a]]
   function transpose(lst) {
       return lst[0].map(function (_, iCol) {
           return lst.map(function (row) {
               return row[iCol];
           });
       });
   }

   var days = {
       sunday: 0,
       monday: 1,
       tuesday: 2,
       wednesday: 3,
       thursday: 4,
       friday: 5,
       saturday: 6
   }

   // TEST

   return transpose(
           range(2012, 2016)
           .map(lastSundaysOfYear)
       )
       .map(function (row) {
           return row
               .map(isoDateString)
               .join('\t');
       })
       .join('\n');

})();


(() => {
   'use strict'

   // MAIN -----------------------------------------------
   // main :: IO ()
   const main = () =>
       console.log(unlines(
           map(
               compose(
                   intercalate('\t'),
                   map(isoDateString)
               )
           )(
               transpose(
                   map(lastWeekDaysOfYear(days.sunday))(
                       enumFromTo(2019)(2022)
                   )
               )
           )
       ));

   // WEEKDAYS -------------------------------------------

   // lastWeekDaysOfYear :: Int -> Int -> [Date]
   const lastWeekDaysOfYear = iWeekDay =>
       y => map((d, m) =>
           new Date(Date.UTC(
               y, m, d - ((new Date(Date.UTC(y, m, d))
                   .getDay() + (7 - iWeekDay)) % 7))))([
           31,
           0 === y % 4 && 0 !== y % 100 || 0 === y % 400 ? 29 : 28,
           31, 30, 31, 30, 31, 31, 30, 31, 30, 31
       ]);

   const days = {
       sunday: 0,
       monday: 1,
       tuesday: 2,
       wednesday: 3,
       thursday: 4,
       friday: 5,
       saturday: 6
   };

   // GENERIC FUNCTIONS-----------------------------------

   // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
   const compose = (...fs) =>
       x => fs.reduceRight((a, f) => f(a), x);

   // enumFromTo :: Int -> Int -> [Int]
   const enumFromTo = m => n =>
       Array.from({
           length: 1 + n - m
       }, (_, i) => m + i);

   // intercalate :: String -> [String] -> String
   const intercalate = s => xs =>
       xs.join(s);

   // isoDateString :: Date -> String
   const isoDateString = dte =>
       dte.toISOString()
       .substr(0, 10);

   // map :: (a -> b) -> [a] -> [b]
   const map = f => xs =>
       (Array.isArray(xs) ? (
           xs
       ) : xs.split('')).map(f);

   // If some of the rows are shorter than the following rows, 
   // their elements are skipped:
   // > transpose [[10,11],[20],[],[30,31,32]] == [[10,20,30],[11,31],[32]]

   // transpose :: [[a]] -> [[a]]
   const transpose = xss => {
       const go = xss =>
           0 < xss.length ? (() => {
               const
                   h = xss[0],
                   t = xss.slice(1);
               return 0 < h.length ? (
                   [
                       [h[0]].concat(t.reduce(
                           (a, xs) => a.concat(
                               0 < xs.length ? (
                                   [xs[0]]
                               ) : []
                           ),
                           []
                       ))
                   ].concat(go([h.slice(1)].concat(
                       t.map(xs => xs.slice(1))
                   )))
               ) : go(t);
           })() : [];
       return go(xss);
   };

   // unlines :: [String] -> String
   const unlines = xs => xs.join('\n');

   // MAIN ---
   return main();
})();


 

{% endraw %}


You may also check:How to resolve the algorithm Greyscale bars/Display step by step in the C programming language
You may also check:How to resolve the algorithm Caesar cipher step by step in the GFA Basic programming language
You may also check:How to resolve the algorithm Function composition step by step in the D programming language
You may also check:How to resolve the algorithm Towers of Hanoi step by step in the ALGOL 68 programming language
You may also check:How to resolve the algorithm Pinstripe/Printer step by step in the Go programming language