-
-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
227 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Conditional Chaining | ||
|
||
The [`cond`] form chains a series of tests to select an expression and then evaluate it, returning the result. | ||
Each test is evaluated in order until a test produces a true value, at which point its associated body is evaluated. | ||
The value from the body is then returned, and no more tests get evaluated inside the cond form. | ||
|
||
If the `cond` form sounds like the [`if`] form, that's because at runtime, the `cond` operates much like a nested `if`. | ||
|
||
Compare | ||
|
||
```scheme | ||
(cond | ||
[(zero? (modulo year 400)) #t] | ||
[(positive? (modulo year 100)) #f] | ||
[(zero? (modulo year 4)) #t] | ||
[else #f])) | ||
``` | ||
|
||
to | ||
|
||
```scheme | ||
(if (zero? (modulo year 400)) | ||
#t | ||
(if (positive? (modulo year 100)) | ||
#f | ||
(if (zero? (modulo year 4)) | ||
#t | ||
#f))) | ||
``` | ||
|
||
[cond]: https://docs.racket-lang.org/guide/conditionals.html#%28part._cond%29 | ||
[if]: https://docs.racket-lang.org/reference/if.html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
(define (leap-year? year) | ||
(cond | ||
[(zero? (modulo year 400)) #t] | ||
[(positive? (modulo year 100)) #f] | ||
[(zero? (modulo year 4)) #t] | ||
[else #f])) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"introduction": { | ||
"authors": [ | ||
"BNAndras" | ||
] | ||
}, | ||
"approaches": [ | ||
{ | ||
"uuid": "be6d6c6e-8e19-4657-aad5-3382e7ec01db", | ||
"slug": "operators", | ||
"title": "Boolean Operators", | ||
"blurb": "Use boolean operators to combine the checks.", | ||
"authors": [ | ||
"BNAndras" | ||
] | ||
}, | ||
{ | ||
"uuid": "428e3cee-309a-4c45-a6d4-3bff4eb41daa", | ||
"slug": "cond", | ||
"title": "Cond", | ||
"blurb": "Use `cond` to control order of checks.", | ||
"authors": [ | ||
"BNAndras" | ||
] | ||
}, | ||
{ | ||
"uuid": "129e6863-275b-4fa3-abfe-4cb07c97acae", | ||
"slug": "match", | ||
"title": "Match", | ||
"blurb": "Use `match` and lists to decide if the year is a leap one.", | ||
"authors": [ | ||
"BNAndras" | ||
] | ||
} | ||
] | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# Pattern matching | ||
|
||
Racket supports pattern matching through the use of the [match form](match). | ||
The `match` form compares an expression sequentially to a series of clauses containing patterns. | ||
Each clause contains a pattern and a body, and the first clause whose pattern matches the expression has their body evaluated. | ||
|
||
Let's see how the `match form` works with a list of values. | ||
In the following example, `_` is a wildcard and can match any value. | ||
So in the first clause, the pattern is looking for a list of three elements and the last value must be a literal `#t`. | ||
|
||
```scheme | ||
(match `(1 #t #f) | ||
[(list #t _ _) "first"] | ||
[(list _ #f _) "second"] | ||
[(list _ _ #f) "third"]) | ||
; "third" | ||
``` | ||
|
||
The first clause isn't matched since the first element is 1, not `#t`. | ||
The second clause isn't matched since the second element is `#f`, not `#t`. | ||
The third clause is matched since the third element is `#f`. | ||
Therefore, we evaluate the body of the third clause and return the string `"third"`. | ||
|
||
If no clauses matched, an exception is raised so the `else` syntax can be used to provide a default expression if no other clauses match. | ||
In the following example, the third cause no longer matches our value so the else is evaluated. | ||
|
||
```scheme | ||
(match `(1 #t 1) | ||
[(list #t _ _) "first"] | ||
[(list _ #f _) "second"] | ||
[(list _ _ #f) "third"]) | ||
[else "whoops"] | ||
; "whoops" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
(define (leap-year? year) | ||
(define by4 (zero? (modulo year 4))) | ||
(define by100 (positive? (modulo year 100))) | ||
(define by400 (zero? (modulo year 400))) | ||
(match (list by4 by100 by400) | ||
[(list _ _ #t) #t] | ||
[(list _ #t _) #f] | ||
[(list #t _ _) #t])) |
105 changes: 105 additions & 0 deletions
105
exercises/practice/leap/.approaches/operators/content.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# Combining Tests | ||
|
||
In Racket, [the `and` and `or` forms](and-or) can combine two expressions to produce a new value. Both forms can "short-circuit" or skip evaluation of the second expression depending on the result of the first expression's evaluation. Remember any value besides `#f` (false) is equivalent to `#t` (true). | ||
|
||
## And | ||
|
||
The `and` form returns the evaluated value of the first expression if it's false. However, if the first expression is true, Racket only then evaluates the second expression and returns this second value. | ||
|
||
```scheme | ||
(and #f #t) ; #f | ||
(and #t #f) ; #f | ||
(and #t #t) ; #t | ||
(and 1 2) ; 2 | ||
``` | ||
|
||
## Or | ||
|
||
The `or` form returns the evaluated value of the first expression that is true. | ||
The second expression is only evaluated when the first expression is false. | ||
|
||
```scheme | ||
(or #f #t) ; #t | ||
(or #t #f) ; #t | ||
(or #t #t) ; #t | ||
(or 1 2) ; 1 | ||
``` | ||
|
||
## Leap Year | ||
|
||
To check if `year` is a leap year, we can combine these two forms. | ||
For example, we can start with our base case that a leap year is evenly divisible by 4 so `(zero? (modulo year 4))` produces `#t` when a year is evenly divisible by 4 (no remainder left). | ||
We can exclude years not evenly divisible by 400 with `(positive? (modulo year 100)` which returns #t when there's a positive remainder left after dividing year by 100. | ||
Using the `and` form, we can first check the base case and only evaluate the second check when we're dealing with a potential leap year. | ||
|
||
Let's pretend we're checking the year 1900. | ||
|
||
```scheme | ||
(and (zero? (modulo year 4)) | ||
(positive? (modulo year 100))) | ||
``` | ||
|
||
```scheme | ||
(and (zero? (modulo 1900 4)) | ||
(positive? (modulo year 100))) | ||
``` | ||
|
||
```scheme | ||
(and (zero? 0) | ||
(positive? (modulo year 100))) | ||
``` | ||
|
||
```scheme | ||
(and #t | ||
(positive? (modulo year 100))) | ||
``` | ||
|
||
... | ||
|
||
```scheme | ||
(and #t | ||
#f) | ||
``` | ||
|
||
```scheme | ||
#f | ||
``` | ||
|
||
However, if a year is divisible by 400, it's still a leap year. | ||
Let's choose 2000 this time around. | ||
Using the previous code, we'd also get `#f` so we need to combine our three checks. | ||
2000 is divisible by 4, 100, and 400. 1900 is divisible by 4, 100, but not 400. | ||
Therefore we can use the `or` form to return `#t` if a year is divisible by 100 and 400 and `#f` otherwise. | ||
|
||
```scheme | ||
(and (zero? (modulo 2000 4)) | ||
(or (positive? (modulo year 100)) | ||
(zero? (modulo year 400)))) | ||
``` | ||
|
||
```scheme | ||
(and #t | ||
(or (positive? (modulo 2000 100)) | ||
(zero? (modulo year 400)))) | ||
``` | ||
|
||
```scheme | ||
(and #t | ||
(or #f | ||
(zero? (modulo 2000 400)))) | ||
``` | ||
|
||
```scheme | ||
(and #t | ||
(or #f | ||
#t)) | ||
``` | ||
|
||
```scheme | ||
(and #t | ||
#t) | ||
``` | ||
|
||
```scheme | ||
#t | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
(define (leap-year? year) | ||
(and (zero? (modulo year 4)) | ||
(or (positive? (modulo year 100)) | ||
(zero? (modulo year 400))))) |