27 votes

Programming Challenge: Translate 24-hour time into words

This is an adapted version of Talking Clock from /r/DailyProgrammer.

The point of this thread is to post your code for solving the task. Other will comment with feedback and new ideas. Post what language (and version, if relevant) your code is written in.

Task description

Your task is to translate a 24-hour formatted time to words.

Input description

An hour between 00 and 23 followed by a colon followed by a minute between 0 and 59.

Output description

The time expressed in words, in 12-hour format followed by "am" or "pm".

Sample input

00:00
01:30
12:05
14:01

Sample output

It's twelve am
It's one thirty am
It's twelve oh five pm
It's two oh one pm

24 comments

  1. [5]
    kgz
    (edited )
    Link
    I like python def whats_the_time(t): return ' '.join([(lambda __, _: [(n[__ % 12 if __ > 12 else 12 if __ == 0 else __], list(filter(lambda _: _ != '', [f(_) for f in [ lambda _: "o'clock" if _ ==...

    I like python

    def whats_the_time(t):
        return ' '.join([(lambda __, _:
            [(n[__ % 12 if __ > 12 else 12 if __ == 0 else __],
            list(filter(lambda _: _ != '', [f(_) for f in [
            lambda _: "o'clock" if _ == 0 else "", lambda _: f"oh {n[_]}" if _ < 10 else "",
            lambda _: n[_] if _ < 20 or _ % 10 else "",
            lambda _: f"{n[int(str(_).rjust(2, '0')[0])*10]} {n[int(str(_).rjust(2, '0')[1])]}",
            ]]))[0], 'am' if __ < 12 else 'pm') for n in [dict(list(zip(range(32), [
            "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
    	"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen",
            "seventeen", "eighteen", "nineteen"])) + list(zip(range(20, 64), [""]*64)) +
            list({20: "twenty", 30: "thirty", 40: "forty", 50: "fifty"
            }.items()))]])(*list(_)) for _ in [map(int, t.split(":"))]][0][0])
    
    print(whats_the_time("00:00"))
    print(whats_the_time("01:30"))
    print(whats_the_time("01:35"))
    print(whats_the_time("12:05"))
    print(whats_the_time("14:01"))
    print(whats_the_time("14:51"))
    
    7 votes
    1. [2]
      zowesiouff
      Link Parent
      That's a beautiful monstrosity, good job :D Did you run it through some kind of minifier? You're missing an extra ) in your first test case :) and you're printing an extra space in one thirty am.

      That's a beautiful monstrosity, good job :D Did you run it through some kind of minifier?

      You're missing an extra ) in your first test case :) and you're printing an extra space in one thirty am.

      2 votes
      1. kgz
        Link Parent
        Ah, not sure how that ) got lost, I've added it back. No tooling was used, just moving code around until it was one expression.

        Ah, not sure how that ) got lost, I've added it back.

        No tooling was used, just moving code around until it was one expression.

        1 vote
  2. chewbacca
    Link
    MoonScript: tests = { "00:00" "01:30" "12:05" "14:01" } translations = [1]: "one", [2]: "two", [3]: "three", [4]: "four" [5]: "five", [6]: "six", [7]: "seven", [8]: "eight", [9]: "nine" [10]:...

    MoonScript:

    tests = {
    	"00:00"
    	"01:30"
    	"12:05"
    	"14:01"
    }
    
    translations =
    	[1]: "one", [2]: "two", [3]: "three", [4]: "four"
    	[5]: "five", [6]: "six", [7]: "seven", [8]: "eight", [9]: "nine"
    	[10]: "ten", [11]: "eleven", [12]: "twelve", [13]: "thirteen", [14]: "fourteen"
    	[15]: "fifteen", [16]: "sixteen", [17]: "seventeen", [18]: "eighteen", [19]: "nineteen"
    	[20]: "twenty", [30]: "thirty", [40]: "forty", [50]: "fifty"
    
    translate = (t) ->
    	h = tonumber t\sub 1,2
    	m = tonumber t\sub 4,5
    
    	suffix = h < 12 and "am" or "pm"
    	h = if h == 0 then 12 else h
    	hFinal = translations[if h > 12 then h % 12 else h]
    
    	local mFinal
    	if m == 0
    		mFinal = "o'clock"
    	elseif m < 10
    		mFinal = "oh #{translations[m]}"
    	elseif m < 20 or m % 10 == 0
    		mFinal = translations[m]
    	else
    		mFirst = tonumber tostring(m)\sub 1,1
    		mLast = tonumber tostring(m)\sub 2,2
    		mFinal = translations[mFirst * 10] .. translations[mLast]
    
    	"It's #{hFinal} #{mFinal} #{suffix}"
    	
    print translate t for t in *tests
    
    4 votes
  3. planNine
    (edited )
    Link
    Implemented in GNU Awk. I hacked this together in a few minutes, it's not the best, but I believe it does the job. EDIT: I just noticed this program doesn't work with minutes 13-19. Oh well,...

    Implemented in GNU Awk. I hacked this together in a few minutes, it's not the best, but I believe it does the job.

    EDIT: I just noticed this program doesn't work with minutes 13-19. Oh well, better luck next time.

    #!/run/current-system/sw/bin/awk -f
    # If on a non-NixOS system, replace with /usr/bin/awk -f
    
    # Write the times in a separate file on each line and then pass that
    # file to the program, something like this:
    # ./talking_clock.awk input.txt
    
    BEGIN {
        FS = ":"
    
        nums[0] = "twelve"
        nums[1] = "one"
        nums[2] = "two"
        nums[3] = "three"
        nums[4] = "four"
        nums[5] = "five"
        nums[6] = "six"
        nums[7] = "seven"
        nums[8] = "eight"
        nums[9] = "nine"
        nums[10] = "ten"
        nums[11] = "eleven"
        nums[12] = "twelve"
    
        other[2] = "twenty"
        other[3] = "thirty"
        other[4] = "forty"
        other[5] = "fifty"
    }
    
    {
        first_num = $1 % 12
        printf "It's"
        printf " %s", nums[first_num]
    
        if ($2 < 10 && $2 != 0) {
            printf " oh %s", nums["0" + $2]
        } else if ($2 != 0) {
            printf " %s", other[int($2 / 10)]
            snd_digit = $2 - int($2 / 10) * 10
            if (snd_digit != 0) {
                printf " %s", nums[snd_digit]
            }
        }
    
        if ($1 < 12) { printf " am\n" }
        else         { printf " pm\n" }
    }
    
    3 votes
  4. jgb
    (edited )
    Link
    Rust (1.28, nightly): Takes input as the first argument to the program. use std::env; use std::process; fn num(n: i32) -> String { match n { 21..=29 => format!("{} {}", num(20), num(n - 20)),...

    Rust (1.28, nightly): Takes input as the first argument to the program.

    use std::env;
    use std::process;
    
    fn num(n: i32) -> String {
        match n {
            21..=29 => format!("{} {}", num(20), num(n - 20)),
            31..=39 => format!("{} {}", num(30), num(n - 30)),
            41..=49 => format!("{} {}", num(40), num(n - 40)),
            51..=59 => format!("{} {}", num(50), num(n - 50)),
            _ => match n {
                1  => "one",
                2  => "two",
                3  => "three",
                4  => "four",
                5  => "five",
                6  => "six",
                7  => "seven",
                8  => "eight",
                9  => "nine",
                10 => "ten",
                11 => "eleven",
                12 => "twelve",
                13 => "thirteen",
                14 => "fourteen",
                15 => "fifteen",
                16 => "sixteen",
                17 => "seventeen",
                18 => "eighteen",
                19 => "nineteen",
                20 => "twenty",
                30 => "thirty",
                40 => "forty",
                50 => "fifty",
                _  => unreachable!(),
            }.to_string()
        }
    }
    
    fn hour(h: i32) -> Option<(String, String)> {
        let am = String::from("am");
        let pm = String::from("pm");
        match h {
            0       => Some((num(12), am)),
            1..=11  => Some((num(h) , am)),
            12      => Some((num(12), pm)),
            13..=23 => Some((num(h - 12) , pm)),
            _       => None,
        }
    }
    
    fn minute(m: i32) -> Option<String> {
        match m {
            0       => Some("".to_string()),
            1..=9   => Some(format!("oh {}", num(m))),
            10..=59 => Some(num(m)),
            _       => None,
        }
    }
    
    fn main() {
        if let Some(input) = env::args().skip(1).next() {
            let parts = input.split(":").collect::<Vec<&str>>();
            if parts.len() == 2 {
                let h = String::from(*parts.get(0).unwrap()).parse::<i32>();
                let m = String::from(*parts.get(1).unwrap()).parse::<i32>();
    
                if !(h.is_ok() && m.is_ok()) {
                    eprintln!("Could not parse input");
                    process::exit(1);
                }
    
                let hour = hour(h.unwrap());
                let minute = minute(m.unwrap());
    
                if !(hour.is_some() && minute.is_some()) {
                    eprintln!("Invalid input");
                    process::exit(1);
                }
    
                let hour = hour.unwrap();
                let minute = minute.unwrap();
    
                if minute.len() != 0 {
                    println!("It's {} {} {}",
                                   hour.0,
                                   minute,
                                   hour.1);
                }
                else {
                    println!("It's {} {}",
                                   hour.0,
                                   hour.1);
                }
            }
            else {
                eprintln!("Could not parse input");
                process::exit(1);
            }
        }
        else {
            eprintln!("No argument given");
            process::exit(1);;
        }
    }
    
    3 votes
  5. Emerald_Knight
    (edited )
    Link
    Some quick and dirty JS. It could be better, but it's 4am and I spent the daylight hours programming at work, so I'll worry about quality some other time :) function intToHumanReadable(value) {...

    Some quick and dirty JS. It could be better, but it's 4am and I spent the daylight hours programming at work, so I'll worry about quality some other time :)

    function intToHumanReadable(value) {
        var ones = [
            '',
            'one',
            'two',
            'three',
            'four',
            'five',
            'six',
            'seven',
            'eight',
            'nine'
        ];
    
        var teens = [
            'ten',
            'eleven',
            'twelve',
            'thirteen',
            'fourteen',
            'fifteen',
            'sixteen',
            'seventeen',
            'eighteen',
            'nineteen',
        ];
    
        var twenty_and_above = [
            '',
            '',
            'twenty',
            'thirty',
            'fourty',
            'fifty'
        ];
    
        if(value < 10) return ones[value];
    
        if(value < 20) return teens[value - 10];
    
        var ones_digit = value % 10;
        var tens_digit = Math.floor(value / 10);
    
        var hyphen = value % 10 != 0 ? '-' : '';
    
        return twenty_and_above[tens_digit] + hyphen + ones[ones_digit];
    }
    
    function timeToHumanReadable(time) {
        var time_parts = time.split(':');
    
        var hour = parseInt(time_parts[0]);
        var hour_text = intToHumanReadable(hour % 12);
        hour_text = hour_text ? hour_text : 'twelve';
        
        var minute = parseInt(time_parts[1]);
        var minute_text = intToHumanReadable(minute);
        minute_text = (0 < minute && minute < 10 ? 'oh ' : '') + minute_text;
    
        var extra_space = (minute_text ? ' ' : '');
        var am_pm = hour < 12 ? 'am' : 'pm';
    
        return 'It\'s ' + hour_text + ' ' + minute_text + extra_space + am_pm;
    }
    

    Stuff that bothers me right off the bat:

    • No comments.

    • Logic is too tightly entangled.

    • Too many assumptions.

    • No error handling.

    • Naming could be better.

    • Some of this stuff could be separated out quite a bit better.

    2 votes
  6. [7]
    Social
    (edited )
    Link
    Python. Some might say it's over engineered, I like writing easy to read code. I'm glad I made a function for most of the steps. I'm a tad annoyed with minute_text() because of how it turns...

    Python. Some might say it's over engineered, I like writing easy to read code. I'm glad I made a function for most of the steps. I'm a tad annoyed with minute_text() because of how it turns numbers above 20 into text. Any suggestions about the minute_text() function are very welcome as long as they are easy to read.

    Also: Woho! Let the coding challenges begin!

    Edit: I wish I had planned this program. Even though it's small it would have benefited from more though. Just shows that to make a program readable all the way through you need to plan.

    numbers_in_text = {
        0: "",
        1: "one",
        2: "two",
        3: "three",
        4: "four",
        5: "five",
        6: "six",
        7: "seven",
        8: "eight",
        9: "nine",
    
        10: "ten",
        11: "eleven",
        12: "twelve",
        13: "thirteen",
        14: "fourteen",
        15: "fifteen",
        16: "sixteen",
        17: "seventeen",
        18: "eightteen",
        19: "nineteen",
    
        20: "twenty",
        30: "thirty",
        40: "fourty",
        50: "fifty"
    }
    
    def time_text(time):
        """Returns text representation of the time."""
    
        hour, minute = hour_and_minute(time)
        time_of_day = am_or_pm(hour)
        hour = converted_hour_from_24_to_12(hour)
    
        time_in_text = hour_in_text(hour)
        if minute and minute not in [15,30, 45]:
            time_in_text += " oh "
        elif minute in [15,30, 45]:
            time_in_text += " "
        time_in_text += minute_text(minute)
        time_in_text += " " + time_of_day
    
        return time_in_text
    
    
    def hour_text(hour):
        """Returns an hour as text."""
    
        if hour == 0:
            hour_in_text = "twelve"
        else:
            hour_in_text = numbers_in_text[hour]
    
        return hour_in_text
    
    
    def minute_text(minute):
        """Returns a minute as text."""
    
        minute_in_text = ""
        if 0 <= minute <= 19:
            minute_in_text = numbers_in_text[minute]
        else:
            minute_string = str(minute)
            ones, tens = minute_string[0], minute_string[1]
            minute_in_text += numbers_in_text[tens]
            minute_in_text += numbers_in_text[ones]
    
        return minute_in_text
    
    
    def hour_and_minute(time):
        """Returns which hours it is in $time."""
    
        hour = time.split(":")[0]
        minute = time.split(":")[1]
        hour, minute = int(hour), int(minute)
    
        return hour, minute
    
    
    def am_or_pm(hour):
        """Returns if the hour is AM or PM."""
    
        time_of_day = ""
        if 0 <= hour <= 11:
            time_of_day = "am"
        elif 12 <= hour <= 23:
            time_of_day = "pm"
    
        return time_of_day
    
    
    def converted_hour_from_24_to_12(hour):
        converted_hour = hour % 12
        return converted_hour
    
    times = ["00:00", "13:45", "9:05"]
    for time in times:
        print(time_text(time))
    
    2 votes
    1. [6]
      bel
      Link Parent
      I believe I saw a discussion yesterday about how important naming is in code. Assuming you don't have plans to revisit this project in two weeks, I admire your variable names. I'm guilty of using...

      I believe I saw a discussion yesterday about how important naming is in code. Assuming you don't have plans to revisit this project in two weeks, I admire your variable names. I'm guilty of using one to two letter variable names for coding challenge type questions.

      I see that you and other commenters hard-coded the teens, specifically 14-19. I wonder how you could translate 0-20 with the fewest duplicated string literals without becoming a mess of if-else/switch-cases and the cleanest way to substitute similar spoken languages (such as Spanish and Portuguese).

      2 votes
      1. [4]
        Social
        Link Parent
        you could numbers_in_text = { 0: "", 1: "one", 2: "two", 3: "three", 4: "four", 5: "five", 6: "six", 7: "seven", 8: "eight", 9: "nine", 10: "ten", 11: "eleven", 12: "twelve", 13: "thirteen" }...

        you could

        numbers_in_text = {
            0: "",
            1: "one",
            2: "two",
            3: "three",
            4: "four",
            5: "five",
            6: "six",
            7: "seven",
            8: "eight",
            9: "nine",
        
            10: "ten",
            11: "eleven",
            12: "twelve",
            13: "thirteen"
        }
        
        numbers_in_text.update({number + 10: numbers_in_text[number] + "teen" for number in range(4, 10)})
        

        Is the time/energy saved from typing worth making this extra line? Is it neccessary writing fewer string literals? Does it improve the code?

        What do you mean with the below?

        without becoming a mess of if-else/switch-cases

        2 votes
        1. [2]
          BBBence1111
          Link Parent
          Doesn't work for fifteen, unless people started calling it fiveteen when I wasn't looking.

          Doesn't work for fifteen, unless people started calling it fiveteen when I wasn't looking.

          3 votes
        2. bel
          Link Parent
          I meant exactly what you did. Python is full of crazy looking stuff that fits the bill "is the time/energy saved ... worth making this extra line?" Readable or not, there's always some kooky...

          I meant exactly what you did. Python is full of crazy looking stuff that fits the bill "is the time/energy saved ... worth making this extra line?" Readable or not, there's always some kooky solution built in to this language.

          2 votes
      2. planNine
        Link Parent
        Wait. Why do you need numbers from 14-19? Am I missing something? EDIT: nvm, I'm stupid. My solution doesn't even work with those numbers.

        Wait. Why do you need numbers from 14-19? Am I missing something?

        EDIT: nvm, I'm stupid. My solution doesn't even work with those numbers.

  7. iAmUserNumberOne
    Link
    I used python. It's probablsy not the best solution but i guess it works ¯\_(ツ)_/¯ hours = 0 minutes = 0 amOrPM = "am" oh = "" translation = ["", "One", "Two", "Three", "Four", "Five", "Six",...

    I used python. It's probablsy not the best solution but i guess it works ¯\_(ツ)_/¯

    hours = 0
    minutes = 0
    amOrPM = "am"
    oh = ""
    
    translation = ["", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve",
                     "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen", "Twenty", "Twenty-One",
                     "Twenty-Two", "Twenty-Three", "Twenty-Four", "Twenty-Five", "Twenty-Six", "Twenty-Seven", "Twenty-Eight", "Twenty-Nine",
                     "Thirty", "Thirty-One", "Thirty-Two","Thirty-Three", "Thirty-Four", "Thirty-Five", "Thirty-Six", "Thirty-Seven", "Thirty-Eight", "Thirty-Nine",
                     "Fourty", "Fourty-One", "Fourty-Two","Fourty-Three", "Fourty-Four", "Fourty-Five", "Fourty-Six", "Fourty-Seven", "Fourty-Eight", "Fourty-Nine",
                     "Fifty", "Fifty-One", "Fifty-Two","Fifty-Three", "Fifty-Four", "Fifty-Five", "Fifty-Six", "Fifty-Seven", "Fifty-Eight", "Fifty-Nine"]
    
    while(1):
        inClock = input("Enter a time: ")
        inputArr = inClock.split(":")
    
        hours = int(inputArr[0])
        minutes = int(inputArr[1])
        
        if hours > 12:
            hours -= 12
            AMorPM = " pm"
        elif hours == 0:
            hours = 12
            AMorPM = "am"
        else:
            AMorPM = " am"
    
        if minutes < 10 and minutes > 0:
            oh = " oh "
        else:
            oh = " "
        
        print("It's " + translation[hours] + oh + translation[minutes] + AMorPM + ".\n")
    
    2 votes
  8. [2]
    googs
    Link
    My Haskell implementation. I'm sure there room for improvement, I don't have a ton of Haskell experience. getText :: Int -> [(Int, String)] -> String getText n translation = snd (head (filter...

    My Haskell implementation. I'm sure there room for improvement, I don't have a ton of Haskell experience.

    getText :: Int -> [(Int, String)] -> String
    getText n translation = snd (head (filter ((==n).fst) translation))
    
    translateTime :: String -> String
    translateTime (a:b:':':c:d:xs)
        | intHour < 12 = "It's " ++ (if intHour == 0 then "twelve" else getText intHour translation) ++ minutes ++ "am"
        | intHour >= 12 = "It's " ++ (getText (intHour `mod` 12) translation) ++ minutes ++ "pm"
        where
            intHour = read ([a] ++ [b]) :: Int
            intMinutes = read ([c] ++ [d]) :: Int
            intMinutesTens = 10 * read [c] :: Int
            intMinutesOnes = read [d] :: Int
    
            translation = [(0, "twelve"),(1,"one"),(2,"two"),(3,"three"),(4,"four"),(5,"five"),(6,"six"),(7,"seven"),(8,"eight"),(9,"nine"),
                            (10,"ten"),(11,"eleven"),(12,"twelve"),(13,"thirteen"),(14,"fourteen"),(15,"fifteen"),(16,"sixteen"),
                            (17,"seventeen"),(18,"eighteen"),(19,"nineteen"),(20,"twenty"),(30,"thirty"),(40,"forty"),(50,"fifty")]
    
            minutes =   " " ++  (if intMinutes == 0 
                                then ""
                                else if intMinutes < 10
                                   then "oh " ++ getText intMinutesOnes translation ++ " "
                                    else if intMinutesTens < 20 || intMinutes `mod` 10 == 0
                                        then getText intMinutes translation ++ " "
                                        else getText intMinutesTens translation ++ getText intMinutesOnes translation ++ " "
                                )
                            
    main = do
        putStrLn (translateTime "00:00")
        putStrLn (translateTime "01:30")
        putStrLn (translateTime "12:05")
        putStrLn (translateTime "14:01")
    
    2 votes
    1. planNine
      Link Parent
      You could replace a lot of parens with the $ operator.

      You could replace a lot of parens with the $ operator.

      2 votes
  9. tyil
    Link
    Perl 6 Tests #!/usr/bin/env perl6 use v6.c; use Local::Tildes::Challenge; use Test; is convert('00:00'), "It's twelve am"; is convert('01:30'), "It's one thirty am"; is convert('12:05'), "It's...

    Perl 6

    Tests

    #!/usr/bin/env perl6
    
    use v6.c;
    
    use Local::Tildes::Challenge;
    use Test;
    
    is convert('00:00'), "It's twelve am";
    is convert('01:30'), "It's one thirty am";
    is convert('12:05'), "It's twelve oh five pm";
    is convert('14:01'), "It's two oh one pm";
    

    Source

    #!/usr/bin/env perl6
    
    use v6.c;
    
    unit module Local::Tildes::Challenge;
    
    my %translations =
    	 0 => "oh",
    	10 => "ten",
    	11 => "eleven",
    	12 => "twelve",
    	15 => "fifteen",
    	20 => "twenty",
    	30 => "thirty",
    	40 => "fourty",
    	50 => "fifty",
    ;
    
    for 1..9 {
    	%translations{$_} = $_.Str.uninames.head.split(' ').tail.lc
    }
    
    sub convert (
    	Str:D $time,
    	--> Str
    ) is export {
    	my ($hours, $minutes) = $time.split(':');
    	my $stringified = "{convert-hours($hours)} {convert-minutes($minutes)} {am-pm($hours)}".subst(/\s+/, ' ', :g);
    	"It's $stringified";
    }
    
    sub am-pm (
    	Str:D $hours,
    	--> Str
    ) {
    	$hours.Int < 12 ?? "am" !! "pm";
    }
    
    sub convert-hours (
    	Str:D $hours,
    	--> Str
    ) {
    	my $hours-int = $hours.Int % 12;
    
    	return %translations{12} if $hours-int == 0;
    	
    	%translations{$hours-int};
    }
    
    sub convert-minutes (
    	Str:D $minutes,
    	--> Str
    ) {
    	my $spoken = '';
    
    	return '' if $minutes eq '00';
    	return %translations{$minutes} if (%translations ∋ $minutes.Str);
    
    	for $minutes.comb {
    		$spoken ~= %translations{$_} ~ ' ';
    	}
    
    	$spoken.trim;
    }
    
    1 vote
  10. BBBence1111
    Link
    Did it in C#. Mostly works, it has some issues with a few numbers (apparently 11-19 returns nothing and when testing I also saw 00:59 return nothing) that I should fix, but I'm already running...

    Did it in C#. Mostly works, it has some issues with a few numbers (apparently 11-19 returns nothing and when testing I also saw 00:59 return nothing) that I should fix, but I'm already running late.

    static void Main(string[] args)
        {
            string[] hour = new string[] { "twelve", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven" };
            string[] tens = new string[] { "oh", "ten", "twenty", "thirty", "forty", "fifty" };
            string[] ones = new string[] { "\b", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
            string[] annoyance = new string[] { "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
            do
            {
                string[] time = Console.ReadLine().Split(':');
                string am = "am";
                int hours = int.Parse(time[0]);
                if (hours >= 12)
                {
                    am = "pm";
                    hours = hours - 12;
                }
    
                int minutes = int.Parse(time[1]);
                int mins;
                if (minutes > 10 && minutes < 20)
                {
                    minutes = minutes - 11;
                    Console.WriteLine("It's {0} {1} {2}", hour[hours], annoyance[minutes], am);
                }
                else
                {
                    mins = minutes / 10;
                    minutes = minutes % 10;
                    if (mins == 0 && minutes == 0)
                        Console.WriteLine("It's {0} {1}", hour[hours], am);
                    else
                        Console.WriteLine("It's {0} {1} {2} {3}", hour[hours], tens[mins], ones[minutes], am);
                }
    
                Console.ReadLine();
            } while (true);
    
    1 vote
  11. burntcookie90
    Link
    Did it in Kotlin, didn't feel like jumping out of the comfort zone today: data class Time(val hours: Int, val minutes: Int) { fun hoursIn12() = hours.rem(12) } fun Int.onesDigit() = this.rem(10)...

    Did it in Kotlin, didn't feel like jumping out of the comfort zone today:

    data class Time(val hours: Int, val minutes: Int) {
        fun hoursIn12() = hours.rem(12)   
    }
    
    fun Int.onesDigit() = this.rem(10)
    
    val sampleInput = listOf(
        "00:00",
        "00:59",
        "01:30",
        "12:05",
        "14:01",
        "23:59"
    )
    
    fun main(args: Array<String>) {
        sampleInput.map {
            val time = Time(parseHours(it), parseMinutes(it))
            
            val hourString = when(time.hours) {
                0 -> translationMapTeens[12]
                in 1..9 -> translationMapOnes[time.hours]
                in 10..12 -> translationMapTeens[time.hours]
                in 13..21 -> translationMapOnes[time.hoursIn12()]
                in 22..24 -> translationMapTeens[time.hoursIn12()]
                else -> ""
            }
            
            val minuteString = when(time.minutes) {
                0 -> ""
                in 1..9 -> "oh ${translationMapOnes[time.minutes]}"
                in 10..19 -> translationMapTeens[time.minutes]
                in 20..29 -> "${translationMapOther[20]} ${translationMapOnes[time.minutes.onesDigit()]}"
                in 30..39 -> "${translationMapOther[30]} ${translationMapOnes[time.minutes.onesDigit()]}"
                in 40..49 -> "${translationMapOther[40]} ${translationMapOnes[time.minutes.onesDigit()]}"
                in 50..59 -> "${translationMapOther[50]} ${translationMapOnes[time.minutes.onesDigit()]}"
                else -> "[tr]"
            }
            val amPm = if(isAm(time.hours)) AM else PM
            "It's $hourString $minuteString $amPm" 
        }
        .forEach{ println(it) }
    }
    
    fun parseHours(input: String): Int = input.subSequence(0, 2).toString().toInt()
    fun parseMinutes(input: String): Int = input.subSequence(3, 5).toString().toInt()
    fun isAm(hours: Int) = hours < 12
    fun isOnes(minutes: Int) = minutes in 0..10
    
    val translationMapOnes = mapOf<Int, String>(
        0 to "",
        1 to "one",
        2 to "two",
        3 to "three",
        4 to "four",
        5 to "five",
        6 to "six",
        7 to "seven",
        8 to "eight",
        9 to "nine"
    )
    val translationMapTeens = mapOf<Int, String>(
        10 to "ten",
        11 to "eleven",
        12 to "twelve",
        13 to "thirteen",
        14 to "fourteen",
        15 to "fifteen",
        16 to "sixteen",
        17 to "seventeen",
        18 to "eighteen",
        19 to "nineteen"
    )
    val translationMapOther = mapOf<Int, String>(
        20 to "twenty",
        30 to "thirty",
        40 to "fourty",
        50 to "fifty"
    )
    const val AM = "AM"
    const val PM = "PM"
    

    can run it here

    1 vote
  12. Kremor
    (edited )
    Link
    Here's my implementation in rust fn to_words (val: u32) -> String { let mut ans = String::new(); if val >= 50 { ans.push_str("fifty"); } else if val >= 40 { ans.push_str("forty"); } else if val >=...

    Here's my implementation in rust

    fn to_words (val: u32) -> String {
        let mut ans = String::new();
    
        if val >= 50 {
            ans.push_str("fifty");
        } else if val >= 40 {
            ans.push_str("forty");
        } else if val >= 30 {
            ans.push_str("thirty");
        } else if val >= 20 {
            ans.push_str("twenty");
        } else if val == 19 {
            ans.push_str("nineteen");
        } else if val == 18 {
            ans.push_str("eighteen");
        } else if val == 17 {
            ans.push_str("seventeen");
        } else if val == 16 {
            ans.push_str("sixteen");
        } else if val == 15 {
            ans.push_str("fifteen");
        } else if val == 14 {
            ans.push_str("fourteen");
        } else if val == 13 {
            ans.push_str("thirteen");
        } else if val == 12 {
            ans.push_str("twelve");
        } else if val == 11 {
            ans.push_str("eleven");
        } else if val == 10 {
            ans.push_str("ten");
        }
    
        let val = {
            if 10 <= val && val <= 19 {
                0
            } else {
                val % 10
            }
        };
    
        if !ans.is_empty() && val != 0 {
            ans.push_str("-");
        }
    
            if val > 0 {
                match val {
                    9 => ans.push_str("nine"),
                    8 => ans.push_str("eight"),
                    7 => ans.push_str("seven"),
                    6 => ans.push_str("six"),
                    5 => ans.push_str("five"),
                    4 => ans.push_str("four"),
                    3 => ans.push_str("three"),
                    2 => ans.push_str("two"),
                    1 => ans.push_str("one"),
                    _ => ans.push_str(""),
            }
        }
    
        return ans;
    }
    
    
    fn main() {
         let tests = [
            "00:00",
            "01:30",
            "12:05",
            "14:01"
        ];
    
        for test in tests.iter() {
            let hour = test[0..2].parse::<u32>().unwrap_or(0);
            let minute = test[3..5].parse::<u32>().unwrap_or(0);
        
            let hour_str = to_words( if hour % 12 != 0 {hour % 12} else {12} );
            let minute_str = to_words(minute);
            let period = if hour < 12 {"am"} else {"pm"};
    
            println!("It's {} {} {} {}",
                hour_str,
                if !minute_str.is_empty() {"oh"} else {""},
                minute_str,
                period
            );
        }
    }
    
    1 vote
  13. fishinginthecoy
    Link
    Here's my (probably too verbose/abuse of STL) semi-noob version in C++: #include <iostream> #include <vector> #include <string> #include <map> #include <sstream> void get_the_time(std::vector<int>...

    Here's my (probably too verbose/abuse of STL) semi-noob version in C++:

    #include <iostream>
    #include <vector>
    #include <string>
    #include <map>
    #include <sstream>
    
    void get_the_time(std::vector<int> times, std::map<int, std::string> time_to_word)
    {
      std::string output = "It's ";
      std::string time_modifier = "am";
      std::string oh = "";
    
      if(times.at(0) > 12 )
      {
        times.at(0) -= 12;
        time_modifier = "pm";
      }
      if(times.at(1) < 10)
      {
        oh = "oh ";
      }
    
      auto search_for_hour = time_to_word.find(times.at(0));
      if(search_for_hour != time_to_word.end())
      {
        output += search_for_hour->second;
      }
      else
      {
        std::cout << "Invalid hour provided" << std::endl;
      }
    
      output += oh;
    
      auto search_for_minute = time_to_word.find(times.at(1));
      if(search_for_minute != time_to_word.end())
      {
        output += search_for_minute->second;
      }
      else
      {
        std::cout << "Invalid minute provided" << std::endl;
      }
    
      output += time_modifier;
    
      std::cout << output << std::endl;
    }
    
    std::map<int, std::string> generate_time_word_map()
    {
      std::map<int, std::string> the_map;
      the_map.emplace(0, "twelve ");
      the_map.emplace(1, "one ");
      the_map.emplace(2, "two ");
      the_map.emplace(3, "three ");
      the_map.emplace(4, "four ");
      the_map.emplace(5, "five ");
      the_map.emplace(6, "six ");
      the_map.emplace(7, "seven ");
      the_map.emplace(8, "eight ");
      the_map.emplace(9, "nine ");
      the_map.emplace(10, "ten ");
      the_map.emplace(11, "eleven ");
      the_map.emplace(12, "twelve ");
      the_map.emplace(13, "thirteen ");
      the_map.emplace(14, "fourteen ");
      the_map.emplace(15, "fifteen ");
      the_map.emplace(16, "sixteen ");
      the_map.emplace(17, "seventeen ");
      the_map.emplace(18, "eighteen ");
      the_map.emplace(19, "nineteen ");
      the_map.emplace(20, "twenty ");
      the_map.emplace(30, "thirty ");
      the_map.emplace(40, "forty");
      the_map.emplace(50, "fifty");
      return the_map;
    }
    
    int main()
    {
      std::map<int, std::string> time_to_word = generate_time_word_map();
    
      std::vector<int> times;
      std::string input;
      std::cin >> input;
      std::istringstream ss(input);
      std::string token;
      while(std::getline(ss, token, ':'))
      {
        int temp;
        std::istringstream(token) >> temp;
        times.push_back(temp);
      }
    
      if(times.at(0) > 24)
      {
        std::cout << "invalid hour provided" << std::endl;
        exit(EXIT_FAILURE);
      }
      if(times.at(1) > 60)
      {
        std::cout << "invalid minute provided" << std::endl;
        exit(EXIT_FAILURE);
      }
    
      get_the_time(times, time_to_word);
    
      return 0;
    }
    
    1 vote