Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Approaches]: Leap #336

Merged
merged 6 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 22 additions & 0 deletions exercises/practice/leap/.approaches/boolean-chain/content.md
Original file line number Diff line number Diff line change
@@ -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)
3 changes: 3 additions & 0 deletions exercises/practice/leap/.approaches/boolean-chain/snippet.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function Test-Leap([int] $year) {
$year % 4 -eq 0 -and $year % 100 -ne 0 -or $year % 400 -eq 0
}
12 changes: 12 additions & 0 deletions exercises/practice/leap/.approaches/built-in-method/content.md
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function Test-Leap([int] $year) {
[DateTime]::IsLeapYear($year)
}
29 changes: 29 additions & 0 deletions exercises/practice/leap/.approaches/config.json
Original file line number Diff line number Diff line change
@@ -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"]
}
]
}
14 changes: 14 additions & 0 deletions exercises/practice/leap/.approaches/datetime-object/content.md
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function Test-Leap([int] $year) {
(Get-Time -Year $year -Month 2 -Day 29).Month -eq 2
}
59 changes: 59 additions & 0 deletions exercises/practice/leap/.approaches/introduction.md
Original file line number Diff line number Diff line change
@@ -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.