diff options
| -rw-r--r-- | challenge-100/andinus/README | 114 | ||||
| -rw-r--r-- | challenge-100/andinus/README.org | 131 | ||||
| -rw-r--r-- | challenge-100/andinus/blog-1.txt | 1 | ||||
| -rw-r--r-- | challenge-100/andinus/raku/ch-1.raku | 41 |
4 files changed, 228 insertions, 59 deletions
diff --git a/challenge-100/andinus/README b/challenge-100/andinus/README index 98fe099f22..3113a6fd55 100644 --- a/challenge-100/andinus/README +++ b/challenge-100/andinus/README @@ -1,58 +1,122 @@ ━━━━━━━━━━━━━━━ - CHALLENGE 098 + CHALLENGE 100 Andinus ━━━━━━━━━━━━━━━ - 2021-02-02 + 2021-02-20 Table of Contents ───────────────── -1. Task 1 - Read N-characters -.. 1. Raku +Task 1 - Fun Time +.. Raku -1 Task 1 - Read N-characters -════════════════════════════ +Task 1 - Fun Time +═════════════════ - You are given file `$FILE'. + You are given a time (12 hour / 24 hour). - Create subroutine `readN($FILE, $number)' returns the first - n-characters and moves the pointer to the `(n+1)th' character. + Write a script to convert the given time from 12 hour format to 24 + hour format and vice versa. + Ideally we expect a one-liner. -1.1 Raku -──────── + +Raku +──── • Program: <file:raku/ch-1.raku> - `readN' is defined as such: + One should use `DateTime' module to solve this but that is not fun so + we solve it the wrong way! + + The program will accept any string as `$time'. We do the format check + later. + + ┌──── + │ #| convert 12-hour formatted time to 24-hour format and vice-versa + │ unit sub MAIN ( + │ Str $time, #= time (format: 05:15pm or "05:15 pm" or 17:00) + │ ); + └──── + + The grammar `Time' will parse `$time' to give us meaningful + information required to do the task. + + ⁃ `hour' & `minute' match any digit ranging from 00 to 99 + ⁃ `meridiem' matches either /am/ or /pm/ + + ⁃ Note: This grammar will consider "99:99" as a valid timestamp. + + ┌──── + │ grammar Time { + │ token TOP { <hour> ':' <minute> ' '? <meridiem>? } + │ token hour { \d ** 1..2 } + │ token minute { \d ** 1..2 } + │ token meridiem { ['am'|'pm'] } + │ } + └──── + + We parse `$time' with `Time' grammar. If `meridiem' is set then it + must be 12-hour format time, otherwise it'll be 24-hour format time. + + ┌──── + │ # Match for time format. + │ if Time.parse($time) -> $m { + │ given $m<meridiem> { + │ ... + │ } + │ } else { + │ note "Wrong format!"; + │ exit 1; + │ } + └──── + + For "am" we just check if the hour is 12, if so then we print it as + "00" otherwise just print the hour. + ┌──── - │ sub readN ( - │ IO $file, Int $chars --> Str - │ ) { - │ ... + │ when 'am' { + │ printf "%02d:%02d\n", + │ $m<hour> == 12 ?? "00" !! $m<hour>, + │ $m<minute>; │ } └──── - The pointer index is stored in a state array (`%pointers'). It's - stores the pointer separately for each file. It's initialized with 0. + If the hour is < 12 then we print `hour + 12' otherwise just print the + hour. + ┌──── - │ # %pointers stores the pointer index. - │ state Int %pointers; - │ %pointers{$file} = 0 without %pointers{$file}; + │ when 'pm' { + │ printf "%02d:%02d\n", + │ $m<hour> < 12 ?? $m<hour> + 12 !! $m<hour>, + │ $m<minute>; + │ } └──── - The pointer is updated & required string is returned. + If the hour is 0 then print 12 otherwise check if it's > 12, if so + then print `hour - 12' otherwise just print the hour. + + 23 -> 11 + greater than 12 + 00 -> 12 + equal to 0 + 12 -> 12 + neither equal to 0, nor greater than 12 + + If the hour is < 12 then print "am" otherwise print "pm". + ┌──── - │ with %pointers{$file} -> $idx { - │ %pointers{$file} += $chars; - │ return $file.slurp.substr($idx, $chars); + │ default { + │ printf "%02d:%02d%s\n", + │ $m<hour> == 0 ?? "12" !! $m<hour> > 12 ?? $m<hour> - 12 !! $m<hour>, + │ $m<minute>, $m<hour> < 12 ?? "am" !! "pm"; │ } └──── diff --git a/challenge-100/andinus/README.org b/challenge-100/andinus/README.org index 353698db4f..9fe366c58c 100644 --- a/challenge-100/andinus/README.org +++ b/challenge-100/andinus/README.org @@ -1,39 +1,102 @@ -#+SETUPFILE: ~/.emacs.d/org-templates/level-2.org -#+HTML_LINK_UP: ../index.html -#+OPTIONS: toc:2 -#+EXPORT_FILE_NAME: index -#+DATE: 2021-02-02 -#+TITLE: Challenge 098 - -* Task 1 - Read N-characters -You are given file =$FILE=. - -Create subroutine =readN($FILE, $number)= returns the first n-characters -and moves the pointer to the =(n+1)th= character. +#+title: Challenge 100 +#+date: 2021-02-20 +#+options: toc:2 +#+html_link_up: ../index.html +#+export_file_name: index +#+setupfile: ~/.emacs.d/org-templates/level-2.org + +* Task 1 - Fun Time + +You are given a time (12 hour / 24 hour). + +Write a script to convert the given time from 12 hour format to 24 hour +format and vice versa. + +Ideally we expect a one-liner. + ** Raku + - Program: [[file:raku/ch-1.raku]] -=readN= is defined as such: -#+BEGIN_SRC raku -sub readN ( - IO $file, Int $chars --> Str -) { - ... +One should use ~DateTime~ module to solve this but that is not fun so we +solve it the wrong way! + +The program will accept any string as ~$time~. We do the format check later. + +#+begin_src raku +#| convert 12-hour formatted time to 24-hour format and vice-versa +unit sub MAIN ( + Str $time, #= time (format: 05:15pm or "05:15 pm" or 17:00) +); +#+end_src + +The grammar ~Time~ will parse ~$time~ to give us meaningful information +required to do the task. + ++ ~hour~ & ~minute~ match any digit ranging from 00 to 99 ++ ~meridiem~ matches either /am/ or /pm/ + ++ *Note*: This grammar will consider "99:99" as a valid timestamp. + +#+begin_src raku +grammar Time { + token TOP { <hour> ':' <minute> ' '? <meridiem>? } + token hour { \d ** 1..2 } + token minute { \d ** 1..2 } + token meridiem { ['am'|'pm'] } } -#+END_SRC - -The pointer index is stored in a state array (=%pointers=). It's stores -the pointer separately for each file. It's initialized with 0. -#+BEGIN_SRC raku -# %pointers stores the pointer index. -state Int %pointers; -%pointers{$file} = 0 without %pointers{$file}; -#+END_SRC - -The pointer is updated & required string is returned. -#+BEGIN_SRC raku -with %pointers{$file} -> $idx { - %pointers{$file} += $chars; - return $file.slurp.substr($idx, $chars); +#+end_src + +We parse ~$time~ with ~Time~ grammar. If ~meridiem~ is set then it must be +12-hour format time, otherwise it'll be 24-hour format time. + +#+begin_src raku +# Match for time format. +if Time.parse($time) -> $m { + given $m<meridiem> { + ... + } +} else { + note "Wrong format!"; + exit 1; +} +#+end_src + +For "am" we just check if the hour is 12, if so then we print it as "00" +otherwise just print the hour. + +#+begin_src raku +when 'am' { + printf "%02d:%02d\n", + $m<hour> == 12 ?? "00" !! $m<hour>, + $m<minute>; +} +#+end_src + +If the hour is < 12 then we print =hour + 12= otherwise just print the +hour. + +#+begin_src raku +when 'pm' { + printf "%02d:%02d\n", + $m<hour> < 12 ?? $m<hour> + 12 !! $m<hour>, + $m<minute>; +} +#+end_src + +If the hour is 0 then print 12 otherwise check if it's > 12, if so then +print =hour - 12= otherwise just print the hour. + ++ 23 -> 11 :: greater than 12 ++ 00 -> 12 :: equal to 0 ++ 12 -> 12 :: neither equal to 0, nor greater than 12 + +If the hour is < 12 then print "am" otherwise print "pm". + +#+begin_src raku +default { + printf "%02d:%02d%s\n", + $m<hour> == 0 ?? "12" !! $m<hour> > 12 ?? $m<hour> - 12 !! $m<hour>, + $m<minute>, $m<hour> < 12 ?? "am" !! "pm"; } -#+END_SRC +#+end_src diff --git a/challenge-100/andinus/blog-1.txt b/challenge-100/andinus/blog-1.txt new file mode 100644 index 0000000000..a08e7e7986 --- /dev/null +++ b/challenge-100/andinus/blog-1.txt @@ -0,0 +1 @@ +https://andinus.tilde.institute/pwc/challenge-100/ diff --git a/challenge-100/andinus/raku/ch-1.raku b/challenge-100/andinus/raku/ch-1.raku new file mode 100644 index 0000000000..1a2a3f99c6 --- /dev/null +++ b/challenge-100/andinus/raku/ch-1.raku @@ -0,0 +1,41 @@ +#!/usr/bin/env raku + +use v6.d; + +#| convert 12-hour format time to 24-hour format and vice-versa +unit sub MAIN ( + Str $time, #= time (format: 05:15pm or "05:15 pm" or 17:00) +); + +grammar Time { + token TOP { <hour> ':' <minute> ' '? <meridiem>? } + token hour { \d ** 1..2 } + token minute { \d ** 1..2 } + token meridiem { ['am'|'pm'] } +} + +# Match for time format. +if Time.parse($time) -> $m { + given $m<meridiem> { + when 'am' { + printf "%02d:%02d\n", + $m<hour> == 12 ?? "00" !! $m<hour>, + $m<minute>; + } + when 'pm' { + printf "%02d:%02d\n", + $m<hour> < 12 ?? $m<hour> + 12 !! $m<hour>, + $m<minute>; + } + # If neither 'am' nor 'pm' is set then $time must be in + # 24-hour format. + default { + printf "%02d:%02d%s\n", + $m<hour> == 0 ?? "12" !! $m<hour> > 12 ?? $m<hour> - 12 !! $m<hour>, + $m<minute>, $m<hour> < 12 ?? "am" !! "pm"; + } + } +} else { + note "Wrong format!"; + exit 1; +} |
