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

Add boolean chain approach for leap #178

Merged
merged 1 commit into from
Jan 16, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions exercises/practice/leap/.approaches/boolean-chain/content.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Boolean chaining

```pyret
fun leap(year):
fun year-is-divisible-by(divisor):
num-equal(num-modulo(year, divisor), 0)
end

year-is-divisible-by(4) and (not(year-is-divisible-by(100)) or year-is-divisible-by(400))
end
```

This approach uses the Boolean operators `and` and `or` to chain together values from two Boolean expressions, creating a Boolean value.
The `and` operator returns `true` when both sides are true but `false` otherwise.
The `or` operator returns `false` when both sides are false but `true` otherwise.

| n1 | n2 | n1 OR n2 | n1 AND n2 |
| ----- | ----- | ------- | --------- |
| false | false | false | false |
| false | true | true | false |
| true | false | true | false |
| true | true | true | true |

Both operators can short-circuit which means in some scenarios, the operators don't evaluate the expression to the right.
For `and`, if the left side produces `false`, that value is returned immediately.
For `or`, if the left side produces `true`, that value is returned immediately.

We can now test if a year is evenly divisible by 4, 100, and 400.
All leap years are divisible by 4 but not by 100 unless they're also divisible by 100.

| year | year % 4 == 0 | year % 100 != 0 | year % 400 == 0 | is leap year |
| ---- | ------------- | --------------- | --------------- | ------------ |
| 2020 | true | true | (not evaluated) | true |
| 2019 | false | (not evaluated) | (not evaluated) | false |
| 2000 | true | false | true | true |
| 1900 | true | false | false | false |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PLACEHOLDER
18 changes: 18 additions & 0 deletions exercises/practice/leap/.approaches/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"introduction": {
"authors": [
"BNAndras"
]
},
"approaches": [
{
"uuid": "2f53896f-b3e7-4c7d-be3a-a3342087826e",
"slug": "boolean-chain",
"title": "Boolean Chaining",
"blurb": "Use operators to check boolean values in a chain",
"authors": [
"BNAndras"
]
}
]
}
25 changes: 25 additions & 0 deletions exercises/practice/leap/.approaches/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Introduction

There are two approaches highlighted here for his exercise.
Both involve checking if a year is evenly divisible by 4, 100, and 400 using [num-modulo][num-modulo].

## General guidance

Regardless of the approach chosen, this exercise requires students to use Boolean logic to decide if a given year is a leap year.

## Approach: Boolean chaining

```pyret
fun leap(year):
fun year-is-divisible-by(divisor):
num-equal(num-modulo(year, divisor), 0)
end

year-is-divisible-by(4) and (not(year-is-divisible-by(100)) or year-is-divisible-by(400))
end
```

For more information, check the [Boolean chain approach][approach-boolean-chain].

[num-modulo]: https://pyret.org/docs/latest/numbers.html#%28part._numbers_num-modulo%29
[approach-boolean-chain]: https://exercism.org/tracks/pyret/exercises/leap/approaches/boolean-chain