Skip to content

Commit 5fdb43b

Browse files
authored
[swift-scheduling] Add new practice exercise (#197)
1 parent efbf240 commit 5fdb43b

12 files changed

Lines changed: 803 additions & 0 deletions

File tree

‎config.json‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,14 @@
406406
"prerequisites": [],
407407
"difficulty": 5
408408
},
409+
{
410+
"slug": "swift-scheduling",
411+
"name": "Swift Scheduling",
412+
"uuid": "1708d1f2-f588-43f0-a247-8072efcff288",
413+
"practices": [],
414+
"prerequisites": [],
415+
"difficulty": 6
416+
},
409417
{
410418
"slug": "variable-length-quantity",
411419
"name": "Variable Length Quantity",
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Instructions
2+
3+
Your task is to convert delivery date descriptions to _actual_ delivery dates, based on when the meeting started.
4+
5+
There are two types of delivery date descriptions:
6+
7+
1. Fixed: a predefined set of words.
8+
2. Variable: words that have a variable component, but follow a predefined set of patterns.
9+
10+
## Fixed delivery date descriptions
11+
12+
There are three fixed delivery date descriptions:
13+
14+
- `"NOW"`
15+
- `"ASAP"` (As Soon As Possible)
16+
- `"EOW"` (End Of Week)
17+
18+
The following table shows how to translate them:
19+
20+
| Description | Meeting start | Delivery date |
21+
| ----------- | ----------------------------- | ----------------------------------- |
22+
| `"NOW"` | - | Two hours after the meeting started |
23+
| `"ASAP"` | Before 13:00 | Today at 17:00 |
24+
| `"ASAP"` | After or at 13:00 | Tomorrow at 13:00 |
25+
| `"EOW"` | Monday, Tuesday, or Wednesday | Friday at 17:00 |
26+
| `"EOW"` | Thursday or Friday | Sunday at 20:00 |
27+
28+
## Variable delivery date descriptions
29+
30+
There are two variable delivery date description patterns:
31+
32+
- `"<N>M"` (N-th month)
33+
- `"Q<N>"` (N-th quarter)
34+
35+
| Description | Meeting start | Delivery date |
36+
| ----------- | ------------------------- | --------------------------------------------------------- |
37+
| `"<N>M"` | Before N-th month | At 8:00 on the _first_ workday of this year's N-th month |
38+
| `"<N>M"` | After or in N-th month | At 8:00 on the _first_ workday of next year's N-th month |
39+
| `"Q<N>"` | Before or in N-th quarter | At 8:00 on the _last_ workday of this year's N-th quarter |
40+
| `"Q<N>"` | After N-th quarter | At 8:00 on the _last_ workday of next year's N-th quarter |
41+
42+
~~~~exercism/note
43+
A workday is a Monday, Tuesday, Wednesday, Thursday, or Friday.
44+
45+
A year has four quarters, each with three months:
46+
1. January/February/March
47+
2. April/May/June
48+
3. July/August/September
49+
4. October/November/December.
50+
~~~~
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Introduction
2+
3+
This week, it is your turn to take notes in the department's planning meeting.
4+
In this meeting, your boss will set delivery dates for all open work items.
5+
Annoyingly, instead of specifying the _actual_ delivery dates, your boss will only _describe them_ in an abbreviated format.
6+
As many of your colleagues won't be familiar with this corporate lingo, you'll need to convert these delivery date descriptions to actual delivery dates.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"authors": [
3+
"IsaacG"
4+
],
5+
"files": {
6+
"solution": [
7+
"swift_scheduling.gd"
8+
],
9+
"test": [
10+
"swift_scheduling_test.gd",
11+
"run_tests",
12+
"lib/test_runner.gd",
13+
"project.godot"
14+
],
15+
"example": [
16+
".meta/example.gd"
17+
]
18+
},
19+
"blurb": "Convert delivery date descriptions to actual delivery dates.",
20+
"source": "Erik Schierboom",
21+
"source_url": "https://github.com/exercism/problem-specifications/pull/2536"
22+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
const QUARTERS = [[0, 4], [0, 7], [0, 10], [1, 1]]
2+
3+
func delivery_date(start: String, description: String):
4+
var now_details = Time.get_datetime_dict_from_datetime_string(start, true)
5+
var now_ts = Time.get_unix_time_from_datetime_string(start)
6+
var delivery = null
7+
var offset = 0
8+
if description == "NOW":
9+
# NOW: Two hours after the meeting started
10+
offset = 2 * 60 * 60
11+
elif description == "ASAP":
12+
# ASAP Before 12:00 => Today at 17:00
13+
# ASAP After 12:00 => Tomorrow at 12:00
14+
if now_details["hour"] <= 12:
15+
now_details["hour"] = 17
16+
else:
17+
now_details["hour"] = 13
18+
offset = 24 * 60 * 60
19+
now_details["minute"] = 0
20+
now_details["second"] = 0
21+
elif description == "EOW":
22+
# EOW Monday, Tuesday, Wednesday => Friday at 17:00
23+
# EOW Thursday or Friday => Sunday at 20:00
24+
if now_details["weekday"] in [Time.WEEKDAY_MONDAY, Time.WEEKDAY_TUESDAY, Time.WEEKDAY_WEDNESDAY]:
25+
now_details["hour"] = 17
26+
offset = 24 * 60 * 60 * (Time.WEEKDAY_FRIDAY - now_details["weekday"])
27+
else:
28+
now_details["hour"] = 20
29+
offset = 24 * 60 * 60 * (Time.WEEKDAY_SATURDAY + 1 - now_details["weekday"])
30+
now_details["minute"] = 0
31+
now_details["second"] = 0
32+
elif description.ends_with("M"):
33+
# "<N>M" Before N-th month => At 8:00 on the first workday¹ of this year's N-th month
34+
# "<N>M" After or in N-th month => At 8:00 on the first workday¹ of next year's N-th month
35+
var target_month = int(description.rstrip("M"))
36+
if now_details["month"] >= target_month:
37+
now_details["year"] += 1
38+
now_details["month"] = target_month
39+
now_details["day"] = 1
40+
now_details["hour"] = 8
41+
now_details["minute"] = 0
42+
now_details["second"] = 0
43+
44+
# Ensure it is not a weekend -- compute day of week and roll forward to Monday.
45+
now_details = Time.get_datetime_dict_from_unix_time(Time.get_unix_time_from_datetime_dict(now_details))
46+
if now_details["weekday"] == Time.WEEKDAY_SATURDAY:
47+
offset += 24 * 60 * 60 * 2
48+
elif now_details["weekday"] == Time.WEEKDAY_SUNDAY:
49+
offset += 24 * 60 * 60 * 1
50+
elif description[0] == "Q":
51+
# "Q<N>" Before or in N-th quarter² => At 8:00 on the last workday¹ of this year's N-th quarter²
52+
# "Q<N>" After N-th quarter² => At 8:00 on the last workday¹ of next year's N-th quarter²
53+
var quarter = int(description.lstrip("Q"))
54+
var current = ((now_details["month"] - 1) / 3) + 1
55+
var year_offset = QUARTERS[quarter - 1][0]
56+
var month = QUARTERS[quarter - 1][1]
57+
if current > quarter:
58+
year_offset = 1
59+
now_details = {"year": now_details["year"] + year_offset, "month": month, "day": 1, "hour": 8, "minute": 0, "second": 0}
60+
now_details = Time.get_datetime_dict_from_unix_time(Time.get_unix_time_from_datetime_dict(now_details) - 24 * 60 * 60 * 1)
61+
62+
# Ensure it is not a weekend -- compute day of week and roll backward to Friday.
63+
if now_details["weekday"] == Time.WEEKDAY_SATURDAY:
64+
offset = 24 * 60 * 60 * -1
65+
elif now_details["weekday"] == Time.WEEKDAY_SUNDAY:
66+
offset = 24 * 60 * 60 * -2
67+
68+
return Time.get_datetime_string_from_unix_time(Time.get_unix_time_from_datetime_dict(now_details) + offset)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{% for case in cases %}
2+
func test_{{ case.func_name }}(solution_script):
3+
var got = solution_script.{{ case.property | camel_to_snake }}({{ case.input.meetingStart | togdscript }}, {{ case.input.description | togdscript }})
4+
var want = {{ case.expected | togdscript }}
5+
return [got, want]
6+
7+
{% endfor %}
8+
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[1d0e6e72-f370-408c-bc64-5dafa9c6da73]
13+
description = "NOW translates to two hours later"
14+
15+
[93325e7b-677d-4d96-b017-2582af879dc2]
16+
description = "ASAP before one in the afternoon translates to today at five in the afternoon"
17+
18+
[cb4252a3-c4c1-41f6-8b8c-e7269733cef8]
19+
description = "ASAP at one in the afternoon translates to tomorrow at one in the afternoon"
20+
21+
[6fddc1ea-2fe9-4c60-81f7-9220d2f45537]
22+
description = "ASAP after one in the afternoon translates to tomorrow at one in the afternoon"
23+
24+
[25f46bf9-6d2a-4e95-8edd-f62dd6bc8a6e]
25+
description = "EOW on Monday translates to Friday at five in the afternoon"
26+
27+
[0b375df5-d198-489e-acee-fd538a768616]
28+
description = "EOW on Tuesday translates to Friday at five in the afternoon"
29+
30+
[4afbb881-0b5c-46be-94e1-992cdc2a8ca4]
31+
description = "EOW on Wednesday translates to Friday at five in the afternoon"
32+
33+
[e1341c2b-5e1b-4702-a95c-a01e8e96e510]
34+
description = "EOW on Thursday translates to Sunday at eight in the evening"
35+
36+
[bbffccf7-97f7-4244-888d-bdd64348fa2e]
37+
description = "EOW on Friday translates to Sunday at eight in the evening"
38+
39+
[d651fcf4-290e-407c-8107-36b9076f39b2]
40+
description = "EOW translates to leap day"
41+
42+
[439bf09f-3a0e-44e7-bad5-b7b6d0c4505a]
43+
description = "2M before the second month of this year translates to the first workday of the second month of this year"
44+
45+
[86d82e83-c481-4fb4-9264-625de7521340]
46+
description = "11M in the eleventh month translates to the first workday of the eleventh month of next year"
47+
48+
[0d0b8f6a-1915-46f5-a630-1ff06af9da08]
49+
description = "4M in the ninth month translates to the first workday of the fourth month of next year"
50+
51+
[06d401e3-8461-438f-afae-8d26aa0289e0]
52+
description = "Q1 in the first quarter translates to the last workday of the first quarter of this year"
53+
54+
[eebd5f32-b16d-4ecd-91a0-584b0364b7ed]
55+
description = "Q4 in the second quarter translates to the last workday of the fourth quarter of this year"
56+
57+
[c920886c-44ad-4d34-a156-dc4176186581]
58+
description = "Q3 in the fourth quarter translates to the last workday of the third quarter of next year"
59+
60+
[7c8f1616-be62-417e-bbd5-a60fa743eccc]
61+
description = "Q2 starting in the last month of the second quarter translates to the last workday of the second quarter of this year"

0 commit comments

Comments
 (0)