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