Skip to content

Commit 379f058

Browse files
authored
Add gigasecond, with lua-tz (#130)
* Add gigasecond It relies on the [lua-tz](https://luarocks.org/modules/anaef/lua-tz) rock. * bump the difficulty
1 parent 82556e4 commit 379f058

13 files changed

Lines changed: 200 additions & 0 deletions

File tree

.github/workflows/pr.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ jobs:
2020
run: |
2121
luarocks install busted
2222
luarocks install moonscript
23+
luarocks install lua-tz
2324
2425
- name: Run tests for changed/added exercises
2526
env:

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ jobs:
2222
run: |
2323
luarocks install busted
2424
luarocks install moonscript
25+
luarocks install lua-tz
2526
2627
- name: test
2728
run: |

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": "gigasecond",
663+
"name": "Gigasecond",
664+
"uuid": "f870722b-6bfc-4516-92ba-9fb1c2866d34",
665+
"practices": [],
666+
"prerequisites": [],
667+
"difficulty": 5
668+
},
661669
{
662670
"slug": "matching-brackets",
663671
"name": "Matching Brackets",
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: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# dummy
2+
3+
## MoonScript-specific instructions
4+
5+
The input and expected datetime strings in the tests are expressed in the UTC timezone.
6+
This is done to remove the effects of daylight saving time in your local timezone.
7+
8+
The key challenge in this exercise is to parse the input timestamp _as if you are in the UTC timezone_.
9+
Lua's builtin `os.time` function simply can't do that.
10+
It can only return the **local** time.
11+
And it's not as simple as adjusting that local time with your timezone offset (in seconds) from UTC:
12+
you need to know the offset _at the moment you are parsing_, not the _current_ offset.
13+
14+
Datetime arithmetic is a **very** complicated topic, and you don't want to have to re-invent that wheel: you want to be able to rely on a well-tested library to get the details right.
15+
16+
The `lua-tz` module works well for this exercise.
17+
It provides `tz.time` and `tz.date` functions that are drop-in replacements for the builtin `os.time` and `os.date` functions, but allow you to provide a timezone name as an extra parameter.
18+
19+
We have provided some additional datetime modules to the MoonScript test runner, if you want to experiment with them.
20+
21+
* `lua-tz`: [luarocks info page][lua-tz-rock], [website][lua-tz-home], [documentation][lua-tz-doc]
22+
* `date`: [luarocks info page][date-rock], [website][date-home], [documentation][date-doc]
23+
* `luatz`: [luarocks info page][luatz-rock], [website][luatz-home], [documentation][luatz-doc]
24+
25+
[lua-tz-rock]: https://luarocks.org/modules/anaef/lua-tz
26+
[lua-tz-home]: https://github.com/anaef/lua-tz#readme
27+
[lua-tz-doc]: https://github.com/anaef/lua-tz/tree/master/doc#readme
28+
[date-rock]: https://luarocks.org/modules/tieske/date
29+
[date-home]: https://github.com/Tieske/date#readme
30+
[date-doc]: https://tieske.github.io/date/
31+
[luatz-rock]: https://luarocks.org/modules/daurnimator/luatz
32+
[luatz-home]: https://github.com/daurnimator/luatz#readme
33+
[luatz-doc]: https://daurnimator.github.io/luatz/
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Instructions
2+
3+
Your task is to determine the date and time one gigasecond after a certain date.
4+
5+
A gigasecond is one thousand million seconds.
6+
That is a one with nine zeros after it.
7+
8+
If you were born on _January 24th, 2015 at 22:00 (10:00:00pm)_, then you would be a gigasecond old on _October 2nd, 2046 at 23:46:40 (11:46:40pm)_.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Introduction
2+
3+
The way we measure time is kind of messy.
4+
We have 60 seconds in a minute, and 60 minutes in an hour.
5+
This comes from ancient Babylon, where they used 60 as the basis for their number system.
6+
We have 24 hours in a day, 7 days in a week, and how many days in a month?
7+
Well, for days in a month it depends not only on which month it is, but also on what type of calendar is used in the country you live in.
8+
9+
What if, instead, we only use seconds to express time intervals?
10+
Then we can use metric system prefixes for writing large numbers of seconds in more easily comprehensible quantities.
11+
12+
- A food recipe might explain that you need to let the brownies cook in the oven for two kiloseconds (that's two thousand seconds).
13+
- Perhaps you and your family would travel to somewhere exotic for two megaseconds (that's two million seconds).
14+
- And if you and your spouse were married for _a thousand million_ seconds, you would celebrate your one gigasecond anniversary.
15+
16+
~~~~exercism/note
17+
If we ever colonize Mars or some other planet, measuring time is going to get even messier.
18+
If someone says "year" do they mean a year on Earth or a year on Mars?
19+
20+
The idea for this exercise came from the science fiction novel ["A Deepness in the Sky"][vinge-novel] by author Vernor Vinge.
21+
In it the author uses the metric system as the basis for time measurements.
22+
23+
[vinge-novel]: https://www.tor.com/2017/08/03/science-fiction-with-something-for-everyone-a-deepness-in-the-sky-by-vernor-vinge/
24+
~~~~
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"authors": [
3+
"glennj",
4+
"BNAndras"
5+
],
6+
"files": {
7+
"solution": [
8+
"gigasecond.moon"
9+
],
10+
"test": [
11+
"gigasecond_spec.moon"
12+
],
13+
"example": [
14+
".meta/example.moon"
15+
]
16+
},
17+
"blurb": "Given a moment, determine the moment that would be after a gigasecond has passed.",
18+
"source": "Chapter 9 in Chris Pine's online Learn to Program tutorial.",
19+
"source_url": "https://pine.fm/LearnToProgram/chap_09.html"
20+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
tz = require 'tz' -- https://luarocks.org/modules/anaef/lua-tz
2+
3+
GIGASECOND = 1e9
4+
DATE_FORMAT = '%Y-%m-%dT%H:%M:%S'
5+
DATE_PATTERN = '^(%d%d%d%d)-(%d%d)-(%d%d)T(%d%d):(%d%d):(%d%d)$'
6+
7+
parse = (timestamp) ->
8+
local m
9+
spec = -> {year: m[1], month: m[2], day: m[3], hour: m[4], min: m[5], sec: m[6]}
10+
11+
m = table.pack timestamp\match DATE_PATTERN
12+
return spec! if m.n > 1
13+
14+
m = table.pack (timestamp .. 'T00:00:00')\match DATE_PATTERN
15+
return spec! if m.n > 1
16+
17+
error "can't parse \"#{timestamp}\""
18+
19+
20+
{
21+
add: (timestamp) ->
22+
time = tz.time parse(timestamp), 'UTC'
23+
tz.date DATE_FORMAT, time + GIGASECOND, 'UTC'
24+
-- os.date works here too: os.date '!...', time + GIGASECOND
25+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
module_name: 'Gigasecond',
3+
4+
generate_test: (case, level) ->
5+
lines = {
6+
"result = Gigasecond.#{case.property} #{quote case.input.moment}",
7+
"expected = #{quote case.expected}",
8+
"assert.are.equal expected, result"
9+
}
10+
table.concat [indent line, level for line in *lines], '\n'
11+
12+
exclusions: {
13+
{key: 'scenarios', op: 'contains', value: 'immutable'}
14+
}
15+
}

0 commit comments

Comments
 (0)