#+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]] 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 { ':' ' '? ? } token hour { \d ** 1..2 } token minute { \d ** 1..2 } token meridiem { ['am'|'pm'] } } #+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 { ... } } 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 == 12 ?? "00" !! $m, $m; } #+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 < 12 ?? $m + 12 !! $m, $m; } #+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 == 0 ?? "12" !! $m > 12 ?? $m - 12 !! $m, $m, $m < 12 ?? "am" !! "pm"; } #+end_src