Skip to content

Commit eb5b8eb

Browse files
authored
Add swift-scheduling (#121)
1 parent c16c3b1 commit eb5b8eb

10 files changed

Lines changed: 330 additions & 0 deletions

File tree

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,14 @@
658658
"prerequisites": [],
659659
"difficulty": 5
660660
},
661+
{
662+
"slug": "swift-scheduling",
663+
"name": "Swift Scheduling",
664+
"uuid": "c1d0b2a7-d27e-43c9-a82b-73ff892a9ff3",
665+
"practices": [],
666+
"prerequisites": [],
667+
"difficulty": 5
668+
},
661669
{
662670
"slug": "change",
663671
"name": "Change",
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
return {
2+
default = {
3+
ROOT = { '.' }
4+
}
5+
}
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: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"glennj"
4+
],
5+
"files": {
6+
"solution": [
7+
"swift_scheduling.moon"
8+
],
9+
"test": [
10+
"swift_scheduling_spec.moon"
11+
],
12+
"example": [
13+
".meta/example.moon"
14+
]
15+
},
16+
"blurb": "Convert delivery date descriptions to actual delivery dates.",
17+
"source": "Erik Schierboom",
18+
"source_url": "https://github.com/exercism/problem-specifications/pull/2536"
19+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
QUARTER_END = {
2+
{month: 3, day: 31}
3+
{month: 6, day: 30}
4+
{month: 9, day: 30}
5+
{month: 12, day: 31}
6+
}
7+
8+
now = (spec) ->
9+
with spec
10+
.hour += 2
11+
12+
asap = (spec) ->
13+
with spec
14+
.day += (.hour < 13 and 0 or 1)
15+
.hour = (.hour < 13 and 17 or 13)
16+
.min = 0
17+
18+
eow = (spec) ->
19+
dow = tonumber os.date '%w', os.time spec
20+
switch dow
21+
when 1, 2, 3
22+
-- want dow = 5, Friday
23+
spec.day += 5 - dow
24+
spec.hour = 17
25+
when 4, 5
26+
spec.day += 7 - dow
27+
spec.hour = 20
28+
with spec
29+
.min = 0
30+
31+
month = (spec, m) ->
32+
spec = {
33+
year: spec.year + (spec.month < m and 0 or 1)
34+
month: m
35+
day: 1
36+
hour: 8
37+
}
38+
switch os.date '%w', os.time spec
39+
when '0' then spec.day += 1
40+
when '6' then spec.day += 2
41+
-- os.time normalizes the table it's given.
42+
-- This can cause off-by-one DST errors unless we unset
43+
-- the isdst field.
44+
with spec
45+
.isdst = nil
46+
47+
quarter = (spec, q) ->
48+
current_quarter = 1 + spec.month // 3
49+
spec = {
50+
year: spec.year + (current_quarter > q and 1 or 0)
51+
month: QUARTER_END[q].month
52+
day: QUARTER_END[q].day
53+
hour: 8
54+
}
55+
switch os.date '%w', os.time spec
56+
when '0' then spec.day -= 2
57+
when '6' then spec.day -= 1
58+
with spec
59+
.isdst = nil
60+
61+
-- ------------------------------------------------------------
62+
delivery_date = (code, timestamp) ->
63+
dt = [tonumber n for n in timestamp\gmatch '%d+']
64+
assert #dt == 6, "can't parse timestamp '#{timestamp}'"
65+
timespec = {
66+
year: dt[1]
67+
month: dt[2]
68+
day: dt[3]
69+
hour: dt[4]
70+
min: dt[5]
71+
sec: dt[6]
72+
}
73+
74+
timespec = switch code
75+
when 'NOW' then now timespec
76+
when 'ASAP' then asap timespec
77+
when 'EOW' then eow timespec
78+
else
79+
m = code\match '(%d+)M'
80+
q = code\match 'Q([1234])'
81+
if m then month timespec, tonumber m
82+
elseif q then quarter timespec, tonumber q
83+
else error "unknown code #{code}"
84+
85+
os.date '%Y-%m-%dT%H:%M:%S', os.time timespec
86+
87+
{ :delivery_date }
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
module_imports: {'delivery_date'},
3+
4+
generate_test: (case, level) ->
5+
lines = {
6+
"result = delivery_date #{quote case.input.description}, #{quote case.input.meetingStart}"
7+
"expected = #{quote case.expected}"
8+
"assert.are.equal expected, result"
9+
}
10+
table.concat [indent line, level for line in *lines], '\n'
11+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
delivery_date: (code, timestamp) ->
3+
error 'Implement me'
4+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import delivery_date from require 'swift_scheduling'
2+
3+
describe 'swift-scheduling', ->
4+
it 'NOW translates to two hours later', ->
5+
result = delivery_date 'NOW', '2012-02-13T09:00:00'
6+
expected = '2012-02-13T11:00:00'
7+
assert.are.equal expected, result
8+
9+
pending 'ASAP before one in the afternoon translates to today at five in the afternoon', ->
10+
result = delivery_date 'ASAP', '1999-06-03T09:45:00'
11+
expected = '1999-06-03T17:00:00'
12+
assert.are.equal expected, result
13+
14+
pending 'ASAP at one in the afternoon translates to tomorrow at one in the afternoon', ->
15+
result = delivery_date 'ASAP', '2008-12-21T13:00:00'
16+
expected = '2008-12-22T13:00:00'
17+
assert.are.equal expected, result
18+
19+
pending 'ASAP after one in the afternoon translates to tomorrow at one in the afternoon', ->
20+
result = delivery_date 'ASAP', '2008-12-21T14:50:00'
21+
expected = '2008-12-22T13:00:00'
22+
assert.are.equal expected, result
23+
24+
pending 'EOW on Monday translates to Friday at five in the afternoon', ->
25+
result = delivery_date 'EOW', '2025-02-03T16:00:00'
26+
expected = '2025-02-07T17:00:00'
27+
assert.are.equal expected, result
28+
29+
pending 'EOW on Tuesday translates to Friday at five in the afternoon', ->
30+
result = delivery_date 'EOW', '1997-04-29T10:50:00'
31+
expected = '1997-05-02T17:00:00'
32+
assert.are.equal expected, result
33+
34+
pending 'EOW on Wednesday translates to Friday at five in the afternoon', ->
35+
result = delivery_date 'EOW', '2005-09-14T11:00:00'
36+
expected = '2005-09-16T17:00:00'
37+
assert.are.equal expected, result
38+
39+
pending 'EOW on Thursday translates to Sunday at eight in the evening', ->
40+
result = delivery_date 'EOW', '2011-05-19T08:30:00'
41+
expected = '2011-05-22T20:00:00'
42+
assert.are.equal expected, result
43+
44+
pending 'EOW on Friday translates to Sunday at eight in the evening', ->
45+
result = delivery_date 'EOW', '2022-08-05T14:00:00'
46+
expected = '2022-08-07T20:00:00'
47+
assert.are.equal expected, result
48+
49+
pending 'EOW translates to leap day', ->
50+
result = delivery_date 'EOW', '2008-02-25T10:30:00'
51+
expected = '2008-02-29T17:00:00'
52+
assert.are.equal expected, result
53+
54+
pending '2M before the second month of this year translates to the first workday of the second month of this year', ->
55+
result = delivery_date '2M', '2007-01-02T14:15:00'
56+
expected = '2007-02-01T08:00:00'
57+
assert.are.equal expected, result
58+
59+
pending '11M in the eleventh month translates to the first workday of the eleventh month of next year', ->
60+
result = delivery_date '11M', '2013-11-21T15:30:00'
61+
expected = '2014-11-03T08:00:00'
62+
assert.are.equal expected, result
63+
64+
pending '4M in the ninth month translates to the first workday of the fourth month of next year', ->
65+
result = delivery_date '4M', '2019-11-18T15:15:00'
66+
expected = '2020-04-01T08:00:00'
67+
assert.are.equal expected, result
68+
69+
pending 'Q1 in the first quarter translates to the last workday of the first quarter of this year', ->
70+
result = delivery_date 'Q1', '2003-01-01T10:45:00'
71+
expected = '2003-03-31T08:00:00'
72+
assert.are.equal expected, result
73+
74+
pending 'Q4 in the second quarter translates to the last workday of the fourth quarter of this year', ->
75+
result = delivery_date 'Q4', '2001-04-09T09:00:00'
76+
expected = '2001-12-31T08:00:00'
77+
assert.are.equal expected, result
78+
79+
pending 'Q3 in the fourth quarter translates to the last workday of the third quarter of next year', ->
80+
result = delivery_date 'Q3', '2022-10-06T11:00:00'
81+
expected = '2023-09-29T08:00:00'
82+
assert.are.equal expected, result

0 commit comments

Comments
 (0)