-
-
Notifications
You must be signed in to change notification settings - Fork 107
Implement new Concept Exercise: tuples #1009
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
Changes from all commits
7d947f3
8f66fcf
e74d509
49282cd
9e07ed0
3fb4075
4e54dc4
4969e89
5cad567
5b9b6ec
24f89f4
99a8774
e07de40
dba112e
69ea0c3
78daf9c
2e3525a
b8ec116
792022e
94135e2
8cb0763
d5a0332
0509d1a
35f0994
d4a93b3
aa334d3
2f7e5b5
a3f5008
268988a
7e84349
3001dcc
9938230
745d2ff
b621a3e
819adca
40dbdf5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"blurb": "A tuple is a grouping of unnamed but ordered values, possibly of different types.", | ||
"authors": ["Grenkin1988"], | ||
"contributors": [] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# About | ||
|
||
A [tuple][tuple] is a _immutable_ grouping of unnamed but ordered values, possibly of different types. Tuples can either be reference types or structs. | ||
|
||
`tuples` can hold any (or multiple) data type(s) -- including other `tuples`. | ||
|
||
## Tuple Construction | ||
|
||
Tuples can be created using `(<element_1>, <element_2>)` declaration. | ||
Tuples can be pairs, triples, and so on, of the same or different types. Some examples are illustrated in the following code: | ||
|
||
```fsharp | ||
(1, 2) | ||
// Triple of strings. | ||
("one", "two", "three") | ||
// Tuple of generic types. | ||
(a, b) | ||
// Tuple that has mixed types. | ||
("one", 1, 2.0) | ||
// Tuple of integer expressions. | ||
(a + 1, b + 1) | ||
``` | ||
|
||
## Obtaining Individual Values | ||
|
||
Pattern matching | ||
|
||
```fsharp | ||
match tuple with | ||
| (x,y) -> printfn "Pair %A %A" x y | ||
``` | ||
Tuple deconstruction | ||
|
||
```fsharp | ||
let (a,b) = (12, "twelve") | ||
// a = 12, b = "twelve" | ||
``` | ||
Using helper functions | ||
|
||
```fsharp | ||
let tuple = (1, 2) | ||
let c = fst tuple | ||
let d = snd tuple | ||
// c = 1, d = 2 | ||
``` | ||
|
||
## Key points about tuples | ||
Some key things to know about tuples are: | ||
|
||
* A particular instance of a tuple type is a single object, similar to a two-element array in C#, say. When using them with functions they count as a single parameter. | ||
* Tuple types cannot be given explicit names. The “name” of the tuple type is determined by the combination of types that are multiplied together. | ||
* The order of the multiplication is important. So `int*string` is not the same tuple type as `string*int`. | ||
* The comma is the critical symbol that defines tuples, not the parentheses. You can define tuples without the parentheses, although it can sometimes be confusing. In F#, if you see a comma, it is probably part of a tuple. | ||
* Tuples have structural equality. `(1, 4, 6) = (1, 4, 6) -> true` | ||
* Tuples can be used as arguments of function and return value of function |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# Introduction | ||
|
||
A tuple is an _immutable_ grouping of unnamed but ordered values. | ||
Tuples can hold any (or multiple) data type(s) -- including other tuples. | ||
|
||
Tuples support can be used when pattern matching. They can be deconstructed and constructed. | ||
|
||
Tuples have structural equality. Tuples must be of the same length and same type in order to be equal. All value of tuple compared. | ||
For example: | ||
|
||
```fsharp | ||
(1, 2) = (1, 2) | ||
// true | ||
(1, 2) = (2, 1) | ||
// false | ||
(1, 2) = (1, 2, 3) | ||
// compiler error | ||
(1, 2) = (1, "2") | ||
// compiler error | ||
``` | ||
|
||
## Tuple Construction | ||
|
||
Tuples can be created using `(<element_1>, <element_2>)` declaration. | ||
Tuples ca be pairs, triples, and so on, of the same or different types. Some examples are illustrated in the following code.: | ||
|
||
```fsharp | ||
("one", 2) // Tuple pair | ||
("one", 2, true) // Tuple triplet | ||
``` | ||
|
||
## Obtaining Individual Values | ||
|
||
Pattern matching | ||
|
||
```fsharp | ||
match tuple with | ||
| (x,y) -> printfn "Pair %A %A" x y | ||
``` | ||
Tuple deconstruction | ||
|
||
```fsharp | ||
let (a,b) = (12, "twelve") | ||
// a = 12, b = "twelve" | ||
``` | ||
Using helper functions | ||
|
||
```fsharp | ||
let tuple = (1, 2) | ||
let c = fst tuple | ||
let d = snd tuple | ||
// c = 1, d = 2 | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[ | ||
{ | ||
"url": "https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/tuples", | ||
"description": "Tuples" | ||
}, | ||
{ | ||
"url": "https://fsharpforfunandprofit.com/posts/tuples/", | ||
"description": "Understanding tuples" | ||
} | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Hints | ||
|
||
## General | ||
|
||
- [Tuples](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/tuples) are immutable grouping of unnamed but ordered values, possibly of different types. | ||
- Elements within tuples can be [obtained](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/tuples#obtaining-individual-values) via pattern matching, tuple deconstruction or using helper functions. | ||
|
||
## 1. Extract coordinates | ||
|
||
- Remember: tuples allow access using helper functions or deconstruction. | ||
- Check [parsing](https://docs.microsoft.com/en-us/dotnet/api/system.int32.parse?view=net-5.0) in order to get number from string. | ||
|
||
## 2. Format coordinates | ||
|
||
- Check [examples](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/tuples#examples) for more details on tuples creation. | ||
- Check [string slicing](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/strings#string-indexing-and-slicing) for more details on strings. | ||
|
||
## 3. Match coordinates | ||
|
||
- What operators could be used here for for [testing membership](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/strings#string-indexing-and-slicing)? | ||
- Could you re-use your `convertCoordinate()` function? | ||
|
||
## 4. Combine matched records | ||
|
||
- Remember that tuples support [pattern matching](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/tuples#obtaining-individual-values). | ||
- Could you re-use your `compareRecords()` function here? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
# Instructions | ||
|
||
Aazra and Rui are teammates competing in a pirate-themed treasure hunt. | ||
One has a list of treasures with map coordinates, the other a list of location names with map coordinates. | ||
They've also been given blank maps with a starting place marked YOU ARE HERE. | ||
|
||
<table> | ||
<tr><th>Azara's List</th><th></th><th>Rui's List</th></tr> | ||
<tr><td> | ||
|
||
| Treasure | Coordinates | | ||
| --------------------------- | ----------- | | ||
| Amethyst Octopus | 1F | | ||
| Angry Monkey Figurine | 5B | | ||
| Antique Glass Fishnet Float | 3D | | ||
| Brass Spyglass | 4B | | ||
| Carved Wooden Elephant | 8C | | ||
| Crystal Crab | 6A | | ||
| Glass Starfish | 6D | | ||
| Model Ship in Large Bottle | 8A | | ||
| Pirate Flag | 7F | | ||
| Robot Parrot | 1C | | ||
| Scrimshaw Whale's Tooth | 2A | | ||
| Silver Seahorse | 4E | | ||
| Vintage Pirate Hat | 7E | | ||
|
||
</td><td></td><td> | ||
|
||
| Location Name | Coordinates | Quandrant | | ||
| ------------------------------------- | ----------- | --------- | | ||
| Seaside Cottages | ("1", "C") | Blue | | ||
| Aqua Lagoon (Island of Mystery) | ("1", "F") | Yellow | | ||
| Deserted Docks | ("2", "A") | Blue | | ||
| Spiky Rocks | ("3", "D") | Yellow | | ||
| Abandoned Lighthouse | ("4", "B") | Blue | | ||
| Hidden Spring (Island of Mystery) | ("4", "E") | Yellow | | ||
| Stormy Breakwater | ("5", "B") | Purple | | ||
| Old Schooner | ("6", "A") | Purple | | ||
| Tangled Seaweed Patch | ("6", "D") | Orange | | ||
| Quiet Inlet (Island of Mystery) | ("7", "E") | Orange | | ||
| Windswept Hilltop (Island of Mystery) | ("7", "F") | Orange | | ||
| Harbor Managers Office | ("8", "A") | Purple | | ||
| Foggy Seacave | ("8", "C") | Purple | | ||
|
||
</td></tr> | ||
</table> | ||
|
||
But things are a bit disorganized: Azara's coordinates appear to be formatted and sorted differently from Rui's, and they have to keep looking from one list to the other to figure out which treasures go with which locations. | ||
Being budding fsharpies, they have come to you for help in writing a small program (a set of functions, really) to better organize their hunt information. | ||
|
||
## 1. Extract coordinates | ||
|
||
Implement the `getCooordinate()` function that takes a `(treasure, coordinate)` pair from Azaras list and returns only the extracted map coordinate. | ||
|
||
Grenkin1988 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
```fsharp | ||
Grenkin1988 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
getCoordinate ("Scrimshaw Whale's Tooth", "2A") | ||
// "2A" | ||
``` | ||
|
||
## 2. Format coordinates | ||
|
||
Implement the `convertCoordinate()` function that takes a coordinate in the format "2A" and returns a tuple in the format `("2", "A")`. | ||
|
||
Grenkin1988 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
```fsharp | ||
Grenkin1988 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
convertCoordinate "2A" | ||
// ("2", "A") | ||
``` | ||
|
||
## 3. Match coordinates | ||
|
||
Implement the `compareRecords()` function that takes a `(treasure, coordinate)` pair and a `(location, coordinate, quadrant)` record and compares coordinates from each. | ||
Return **`true`** if the coordinates "match", and return **`false`** if they do not. | ||
Re-format coordinates as needed for accurate comparison. | ||
|
||
Grenkin1988 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
```fsharp | ||
Grenkin1988 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
compareRecords ("Brass Spyglass", "4B") ("Seaside Cottages", ("1", "C"), "blue") | ||
// false | ||
|
||
compareRecords ("Model Ship in Large Bottle", "8A") ("Harbor Managers Office", ("8", "A"), "purple") | ||
// true | ||
``` | ||
|
||
## 4. Combine matched records | ||
|
||
Implement the `createrecord()` function that takes a `(treasure, coordinate)` pair from Azara's list and a `(location, coordinate, quadrant)` record from Rui's list and returns `(treasure, coordinate, location, coordinate, quadrant)` **if the coordinates match**. | ||
If the coordinates _do not_ match, return the tuple of same shape but filled with `""` | ||
Re-format the coordinate as needed for accurate comparison. | ||
|
||
Grenkin1988 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
```fsharp | ||
Grenkin1988 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
createRecord ("Brass Spyglass", "4B") ("Abandoned Lighthouse", ("4", "B"), "Blue") | ||
("Brass Spyglass", "4B", "Abandoned Lighthouse", ("4", "B"), "Blue") | ||
|
||
createRecord ("Brass Spyglass", "4B") ("Seaside Cottages", ("1", "C"), "Blue") | ||
("", "", "", ("", ""), "") | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# Introduction | ||
|
||
A tuple is an _immutable_ grouping of unnamed but ordered values. | ||
Tuples can hold any (or multiple) data type(s) -- including other tuples. | ||
|
||
Tuples support can be used when pattern matching. They can be deconstructed and constructed. | ||
|
||
Tuples have structural equality. Tuples must be of the same length and same type in order to be equal. All value of tuple compared. | ||
For example: | ||
|
||
```fsharp | ||
(1, 2) = (1, 2) | ||
// true | ||
(1, 2) = (2, 1) | ||
// false | ||
(1, 2) = (1, 2, 3) | ||
// compiler error | ||
(1, 2) = (1, "2") | ||
// compiler error | ||
``` | ||
|
||
## Tuple Construction | ||
|
||
Tuples can be created using `(<element_1>, <element_2>)` declaration. | ||
Tuples ca be pairs, triples, and so on, of the same or different types. Some examples are illustrated in the following code.: | ||
|
||
```fsharp | ||
("one", 2) // Tuple pair | ||
("one", 2, true) // Tuple triplet | ||
``` | ||
|
||
## Obtaining Individual Values | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be nice to move the examples next to the text where the concept is explained. For example, the example of matching a tuple can be moved to the pattern matching example, possibly including the deconstruction code too. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, not sure I understand what is required There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No problem. I can do a follow-up PR later. |
||
|
||
Pattern matching | ||
|
||
```fsharp | ||
match tuple with | ||
| (x,y) -> printfn "Pair %A %A" x y | ||
``` | ||
Tuple deconstruction | ||
|
||
```fsharp | ||
let (a,b) = (12, "twelve") | ||
// a = 12, b = "twelve" | ||
``` | ||
Using helper functions | ||
|
||
```fsharp | ||
let tuple = (1, 2) | ||
let c = fst tuple | ||
let d = snd tuple | ||
// c = 1, d = 2 | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
module TisburyTreasureHunt | ||
Grenkin1988 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
open System | ||
|
||
let getCoordinate (line: string * string): string = snd line | ||
|
||
let convertCoordinate (coordinate: string): int * char = | ||
Int32.Parse(string coordinate.[0]), coordinate.[1] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I hadn't considered the fact that we need students to convert a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also might be worse adding parsing to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure, I'll think on it. |
||
|
||
let compareRecords (azarasData: string * string) (ruisData: string * (int * char) * string) : bool = | ||
let azarasCoordinate = getCoordinate azarasData | ||
let (_, ruisCoordinate, _) = ruisData | ||
convertCoordinate azarasCoordinate = ruisCoordinate | ||
|
||
let createRecord (azarasData: string * string) (ruisData: string * (int * char) * string) : (string * string * string * string) = | ||
if compareRecords azarasData ruisData then | ||
match azarasData, ruisData with | ||
| (treasure, coordinate), (location, _, quadrant) -> | ||
(coordinate, location, quadrant, treasure) | ||
else | ||
("", "", "", "") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"blurb": "Learn about tuples by helping out competitors in the Tisbury Treasure Hunt.", | ||
"icon": "proverb", | ||
"authors": [ | ||
"Grenkin1988" | ||
], | ||
"files": { | ||
"solution": [ | ||
"TisburyTreasureHunt.fs" | ||
], | ||
"test": [ | ||
"TisburyTreasureHuntTests.fs" | ||
], | ||
"exemplar": [ | ||
".meta/Exemplar.fs" | ||
] | ||
}, | ||
"forked_from": ["python/tisbury-treasure-hunt"] | ||
} |
Uh oh!
There was an error while loading. Please reload this page.