Skip to content

Commit

Permalink
Add new practice exercise meetup (#705)
Browse files Browse the repository at this point in the history
  • Loading branch information
jiegillet authored Jul 21, 2024
1 parent a2c69dc commit 05b25d3
Show file tree
Hide file tree
Showing 9 changed files with 1,199 additions and 0 deletions.
15 changes: 15 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -1295,6 +1295,21 @@
],
"difficulty": 4
},
{
"slug": "meetup",
"name": "Meetup",
"uuid": "3dc4b700-6ce6-4ae7-94e2-1b37290b8235",
"practices": [
"pattern-matching"
],
"prerequisites": [
"strings",
"booleans",
"comparison",
"pattern-matching"
],
"difficulty": 7
},
{
"slug": "spiral-matrix",
"name": "Spiral Matrix",
Expand Down
34 changes: 34 additions & 0 deletions exercises/practice/meetup/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Instructions

Your task is to find the exact date of a meetup, given a month, year, weekday and week.

There are five week values to consider: `first`, `second`, `third`, `fourth`, `last`, `teenth`.

For example, you might be asked to find the date for the meetup on the first Monday in January 2018 (January 1, 2018).

Similarly, you might be asked to find:

- the third Tuesday of August 2019 (August 20, 2019)
- the teenth Wednesday of May 2020 (May 13, 2020)
- the fourth Sunday of July 2021 (July 25, 2021)
- the last Thursday of November 2022 (November 24, 2022)
- the teenth Saturday of August 1953 (August 15, 1953)

## Teenth

The teenth week refers to the seven days in a month that end in '-teenth' (13th, 14th, 15th, 16th, 17th, 18th and 19th).

If asked to find the teenth Saturday of August, 1953, we check its calendar:

```plaintext
August 1953
Su Mo Tu We Th Fr Sa
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
```

From this we find that the teenth Saturday is August 15, 1953.
29 changes: 29 additions & 0 deletions exercises/practice/meetup/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Introduction

Every month, your partner meets up with their best friend.
Both of them have very busy schedules, making it challenging to find a suitable date!
Given your own busy schedule, your partner always double-checks potential meetup dates with you:

- "Can I meet up on the first Friday of next month?"
- "What about the third Wednesday?"
- "Maybe the last Sunday?"

In this month's call, your partner asked you this question:

- "I'd like to meet up on the teenth Thursday; is that okay?"

Confused, you ask what a "teenth" day is.
Your partner explains that a teenth day, a concept they made up, refers to the days in a month that end in '-teenth':

- 13th (thirteenth)
- 14th (fourteenth)
- 15th (fifteenth)
- 16th (sixteenth)
- 17th (seventeenth)
- 18th (eighteenth)
- 19th (nineteenth)

As there are also seven weekdays, it is guaranteed that each day of the week has _exactly one_ teenth day each month.

Now that you understand the concept of a teenth day, you check your calendar.
You don't have anything planned on the teenth Thursday, so you happily confirm the date with your partner.
18 changes: 18 additions & 0 deletions exercises/practice/meetup/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"authors": [
"jiegillet"
],
"files": {
"solution": [
"src/Meetup.elm"
],
"test": [
"tests/Tests.elm"
],
"example": [
".meta/src/Meetup.example.elm"
]
},
"blurb": "Calculate the date of meetups.",
"source": "Jeremy Hinegardner mentioned a Boulder meetup that happens on the Wednesteenth of every month"
}
253 changes: 253 additions & 0 deletions exercises/practice/meetup/.meta/src/Meetup.example.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
module Meetup exposing (Month(..), Week(..), Weekday(..), meetup)


type Month
= January
| February
| March
| April
| May
| June
| July
| August
| September
| October
| November
| December


type Weekday
= Monday
| Tuesday
| Wednesday
| Thursday
| Friday
| Saturday
| Sunday


type Week
= First
| Second
| Third
| Fourth
| Last
| Teenth


meetup : Int -> Month -> Week -> Weekday -> String
meetup year month week weekday =
let
firstOfMonth =
dateToWeekday year month 1

firstWeekdayOfMonth =
1 + modBy 7 (weekdayToInt weekday - firstOfMonth)

dayOfMonth =
case week of
First ->
firstWeekdayOfMonth

Second ->
7 + firstWeekdayOfMonth

Third ->
14 + firstWeekdayOfMonth

Fourth ->
21 + firstWeekdayOfMonth

Teenth ->
if firstWeekdayOfMonth >= 6 then
7 + firstWeekdayOfMonth

else
14 + firstWeekdayOfMonth

Last ->
if 28 + firstWeekdayOfMonth <= getDaysInMonth year month then
28 + firstWeekdayOfMonth

else
21 + firstWeekdayOfMonth
in
[ String.fromInt year
, printMonthNumber month
, dayOfMonth |> String.fromInt |> String.padLeft 2 '0'
]
|> String.join "-"


{-| Sakamoto's method
<https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week#Sakamoto's_methods>
Returns the weeday of a given date with 0 = Sunday, 1 = Monday...
valid for year > 1752 (in the U.K.)
-}
dateToWeekday : Int -> Month -> Int -> Int
dateToWeekday year month day =
let
y =
sakamotoYear year month
in
modBy 7 (y + y // 4 - y // 100 + y // 400 + sakamotoMagicValue month + day)


sakamotoYear : Int -> Month -> Int
sakamotoYear year month =
case month of
January ->
year - 1

February ->
year - 1

_ ->
year


sakamotoMagicValue : Month -> Int
sakamotoMagicValue month =
case month of
January ->
0

February ->
3

March ->
2

April ->
5

May ->
0

June ->
3

July ->
5

August ->
1

September ->
4

October ->
6

November ->
2

December ->
4


weekdayToInt : Weekday -> Int
weekdayToInt weekday =
case weekday of
Sunday ->
0

Monday ->
1

Tuesday ->
2

Wednesday ->
3

Thursday ->
4

Friday ->
5

Saturday ->
6


printMonthNumber : Month -> String
printMonthNumber month =
case month of
January ->
"01"

February ->
"02"

March ->
"03"

April ->
"04"

May ->
"05"

June ->
"06"

July ->
"07"

August ->
"08"

September ->
"09"

October ->
"10"

November ->
"11"

December ->
"12"


getDaysInMonth : Int -> Month -> Int
getDaysInMonth year month =
case month of
February ->
if isLeapYear year then
29

else
28

January ->
31

March ->
31

May ->
31

July ->
31

August ->
31

October ->
31

December ->
31

_ ->
30


isLeapYear : Int -> Bool
isLeapYear year =
modBy 400 year == 0 || (modBy 400 year /= 0 && modBy 4 year == 0)
Loading

0 comments on commit 05b25d3

Please sign in to comment.