diff --git a/exercises/practice/leap/.approaches/boolean-chain/content.md b/exercises/practice/leap/.approaches/boolean-chain/content.md new file mode 100644 index 00000000..4447f8be --- /dev/null +++ b/exercises/practice/leap/.approaches/boolean-chain/content.md @@ -0,0 +1,22 @@ +# Using `Boolean` chain + +```powershell +function Test-Leap([int] $year) { + $year % 4 -eq 0 -and $year % 100 -ne 0 -or $year % 400 -eq 0 +} +``` + +One of the most common approach to solve this exercise based on the given information. +First we test if the year is divisible by 4 using modulus, if it return `false` here then the chain is short circuit and return `false`. +If the year is indeed divisible by 4, then we test whether it can't divisible by 100 or can divisible by 400. +If one of those condition return `true` then our chain will return `true`, but if both return `false` then our chain here will return `false`. + +You can visualize the chain like this: + +|divisible by 4 | not divisible by 100 | divisible by 400 | | +|------------------------|----------------------|--------------------|----------| +|false (short circuit) | | | => false | +|true |either this is true | or this to be true | => true | +|true | false | false | => false | + +[Arithmetic operators](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_arithmetic_operators) \ No newline at end of file diff --git a/exercises/practice/leap/.approaches/boolean-chain/snippet.txt b/exercises/practice/leap/.approaches/boolean-chain/snippet.txt new file mode 100644 index 00000000..9a8a3aae --- /dev/null +++ b/exercises/practice/leap/.approaches/boolean-chain/snippet.txt @@ -0,0 +1,3 @@ +function Test-Leap([int] $year) { + $year % 4 -eq 0 -and $year % 100 -ne 0 -or $year % 400 -eq 0 +} \ No newline at end of file diff --git a/exercises/practice/leap/.approaches/built-in-method/content.md b/exercises/practice/leap/.approaches/built-in-method/content.md new file mode 100644 index 00000000..a9f277ee --- /dev/null +++ b/exercises/practice/leap/.approaches/built-in-method/content.md @@ -0,0 +1,12 @@ +# Using `IsLeapYear` method + +```powershell +function Test-Leap([int] $year) { + [DateTime]::IsLeapYear($year) +} +``` + +Utilizing the `DateTime` class from .NET, you can determine if a year is a leap year or not by passing it into the `IsLeapYear` static method. +This might not be the intended approach for learning, but it is an idiomatic way to check if a year is leap or not. + +[IsLeapYear](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.isleapyear) method. \ No newline at end of file diff --git a/exercises/practice/leap/.approaches/built-in-method/snippet.txt b/exercises/practice/leap/.approaches/built-in-method/snippet.txt new file mode 100644 index 00000000..96cedd27 --- /dev/null +++ b/exercises/practice/leap/.approaches/built-in-method/snippet.txt @@ -0,0 +1,3 @@ +function Test-Leap([int] $year) { + [DateTime]::IsLeapYear($year) +} \ No newline at end of file diff --git a/exercises/practice/leap/.approaches/config.json b/exercises/practice/leap/.approaches/config.json new file mode 100644 index 00000000..5022d4c8 --- /dev/null +++ b/exercises/practice/leap/.approaches/config.json @@ -0,0 +1,29 @@ +{ + "introduction": { + "authors": ["glaxxie"], + "contributors": [] + }, + "approaches": [ + { + "uuid": "2d286acf-dc3c-493d-839e-45ca17e2112a", + "slug": "boolean-chain", + "title": "Boolean chain", + "blurb": "Use a chain of boolean expressions.", + "authors": ["glaxxie"] + }, + { + "uuid": "9456f386-9355-4c77-b222-5cc3441a8d00", + "slug": "datetime-object", + "title": "datetime object", + "blurb": "Use datetime object and its property.", + "authors": ["glaxxie"] + }, + { + "uuid": "4716c9ec-ad99-46fa-bf73-1332c648f1b4", + "slug": "built-in-method", + "title": "built-in method", + "blurb": "Use IsLeapYear method of the DateTime class.", + "authors": ["glaxxie"] + } + ] + } \ No newline at end of file diff --git a/exercises/practice/leap/.approaches/datetime-object/content.md b/exercises/practice/leap/.approaches/datetime-object/content.md new file mode 100644 index 00000000..4c502ed7 --- /dev/null +++ b/exercises/practice/leap/.approaches/datetime-object/content.md @@ -0,0 +1,14 @@ +# Using `DateTime` object + +```powershell +function Test-Leap([int] $year) { + (Get-Date -Year $year -Month 2 -Day 29).Month -eq 2 +} +``` + +The main characteristic of a leap year is the second month (February) has 29 days instead of 28. +In this approach we will use `Get-Date` with : $year for `Year` parameter, 2 for `Month` Parameter, and 29 for `Day` parameter, and this will give us a `DateTime` object. +Next we access the `Month` property of this object and compare it with 2, if they are equal then the year is a leap year. +In the event of a year is not a leap year, `Get-Date` for Month 2 and Day 29 in fact return a `DateTime` object of March the 1st, which mean the `Month` property now has the value of 3. + +[Get-Date](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-date) cmdlet. \ No newline at end of file diff --git a/exercises/practice/leap/.approaches/datetime-object/snippet.txt b/exercises/practice/leap/.approaches/datetime-object/snippet.txt new file mode 100644 index 00000000..b0a077cd --- /dev/null +++ b/exercises/practice/leap/.approaches/datetime-object/snippet.txt @@ -0,0 +1,3 @@ +function Test-Leap([int] $year) { + (Get-Time -Year $year -Month 2 -Day 29).Month -eq 2 +} \ No newline at end of file diff --git a/exercises/practice/leap/.approaches/introduction.md b/exercises/practice/leap/.approaches/introduction.md new file mode 100644 index 00000000..e3a21e58 --- /dev/null +++ b/exercises/practice/leap/.approaches/introduction.md @@ -0,0 +1,59 @@ +# Introduction + +There are various ways to solve **leap**. +You can use a chain of Boolean expressions to tests for conditions. +You can use a datetime object and test for condition of the month. +Or you can "cheat" and use the built-in function. + + +## General guidance + +The goal of this exercise is to check if a year is a leap year by testing if it is divisible by `4`, `100` and `400`. + + +## Approach: Using `Boolean` chain + +This is the most common approach to solve this exercise, based exactly on the conditions to validate a leap year. +It utilize chaining `Boolean` values from tesing the divisibility of the year by `4`, `100` and `400` using modulus operator (`%`). + +```powershell +function Test-Leap([int] $year) { + $year % 4 -eq 0 -and $year % 100 -ne 0 -or $year % 400 -eq 0 +} +``` + +For more information, check the [`Boolean` chain approach][approach-boolean-chain]. + + +## Approach: Using `DateTime` object + +We know for a fact that in a leap year, the second month (February) has 29 days. +For this approach we leverage this fact along with the cmdlet `Get-Date` to interact with a datetime object. + +```powershell +function Test-Leap([int] $year) { + (Get-Date -Year $year -Month 2 -Day 29).Month -eq 2 +} +``` + +For more information, check the [`DateTime` object approach][approach-datetime-object]. + + +## Approach: Using `IsLeapYear` method + +Using the `DateTime` class, we can just utilize the built-in `IsLeapYear` static method and check if a year is leap or not. + +```powershell +function Test-Leap([int] $year) { + [DateTime]::IsLeapYear($year) +} +``` + +For more information, check the [`IsLeapYear` method approach][approach-built-in-method]. + + +## Which approach to use? + +- The chain of boolean expressions should be the most efficient, as it proceeds from the most to least likely conditions and takes advantage of short-circuiting. It has a maximum of three checks. It is the fastest approach when testing a year that is not evenly divisible by 100 that is not a leap year. Since most years fit those conditions, it is overall the most efficient approach. + +- For idiomatic and convenience while coding, consider using the built-int `IsLeapYear` method despite it seems to be a "cheat" for the purpose of learning here. \ No newline at end of file