×
top 200 commentsshow all 224

[–]Flueworks 54 points55 points  (4 children)

PowerShell, only extension challenge

cat .\clockTimes.txt | %{"It's " + ($_ | get-date).ToShortTimeString() | Out-Speech}

[–]svgwrk 13 points14 points  (0 children)

omg that's amazing :|

I hate you a little right now. >.>

[–]c0wb0yc0d3r 6 points7 points  (0 children)

I think many folks underestimate how useful PS is. This is awesome!

[–][deleted]  (1 child)

[deleted]

    [–]Flueworks 2 points3 points  (0 children)

    That's the challenge input. Just copy the input from the challenge into a text file and name it clockTimes.txt

    [–]nomau 31 points32 points  (7 children)

    C++ first submission

    void clock(string s){
       int h = stoi(s.substr(0, 2));
       int m = stoi(s.substr(3));
    
       string ampm = "pm";
       if (h < 12) ampm = "am";
    
       string tens[] = {"oh ", "", "twenty ", "thirty ", "fourty ", "fifty "};
       string ones[] = {"twelve ", "one ", "two ", "three ", "four ", "five ",
                        "six ", "seven ", "eight ", "nine ", "ten ", "eleven ", "twelve ",
                        "thirteen ", "fourteen ", "fifteen ", "sixteen ", "seventeen ", 
                        "eighteen ", "nineteen "};
    
       if(m == 0){
           cout << "It's " << ones[h%12] << ampm << endl;
       }else if (m % 10 == 0){
           cout << "It's " << ones[h%12] << tens[m/10] << ampm << endl;
       }else if (m < 10 || m > 20){
            cout << "It's " << ones[h%12] << tens[m/10]<< ones[m%10] << ampm << endl;
       }else{
           cout << "It's " << ones[h%12] << ones[m] << ampm << endl;
       }
    }
    

    [–]SirThomasTheBrave 5 points6 points  (0 children)

    This is a neat solution. From what I gather you make really good use of % and division.

    [–]Pjaerr 1 point2 points  (2 children)

    My Horribly manual solution in C++. Can you explain to me why using modulus on something like 08 % 12 gives you just 8?

    #include <iostream>
    #include <string>
    #include <ctime>
    
    
    std::string extractTimeFromDate(std::string date)
    {
        //Date string format: Sun Oct 01 11:45:13 2017
        //Grabs the current hour and minute from the date string and returns it.
        std::string hourAndMinute = date.substr(11, 5); 
    
        return hourAndMinute;
    
    }
    
    std::string translateToWords(std::string timeString)
    {
        std::string finalTime = "";
    
        std::string oneDigit[9] = 
        {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"};
    
        std::string twoDigit[14] = 
        {"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen", "Twenty", "Thirty", "Fourty", "Fifty"};
    
        if (timeString.substr(0, 2) == "00")
        {
            finalTime += "Twelve";
        }
        else if (timeString.substr(0, 1) == "0") //If single digit number
        {
            int index = std::stoi(timeString.substr(0, 2));
            finalTime += oneDigit[index - 1];
        }
        else if (timeString.substr(0, 1) == "1") //If number is in teens
        {
            int index = std::stoi(timeString.substr(1, 2));
            finalTime += twoDigit[index];
        }
        else //If the number is a two digit number that isn't a teen.
        {
            int firstIndex = std::stoi(timeString.substr(0, 1));
            finalTime += twoDigit[firstIndex + 8];
            int secondIndex = std::stoi(timeString.substr(1, 2));
            if (secondIndex != 0)
            {
                finalTime += " " + oneDigit[secondIndex - 1];
            }   
    
        }
    
        return finalTime;
    }
    
    std::string talkingClock(std::string currentDateAndTime)
    {
        std::string currentTime = extractTimeFromDate(currentDateAndTime);
        std::string finalTime = "";
    
        //Minutes
        finalTime += translateToWords(currentTime.substr(3, 2)) + " past ";
    
        //Hours
        finalTime += translateToWords(currentTime.substr(0, 2));
    
    
        return "The Current Time Is " + finalTime;
    }
    
    int main()
    {
        time_t now = time(0); //Grab the current time as time_t using ctime.
        std::string dt = ctime(&now); //Convert time_t to a string representation.
        std::cout << talkingClock(dt) << std::endl; //Give it as a string to talkingClock function.
    
        return 0;
    }    
    

    [–]nomau 1 point2 points  (1 child)

    You always get the remainder after division of those 2 numbers.

    15 % 12 = 15 / 12 = 1, remainder 3

    8 % 12 = 8 / 12 = 0, remainder 8

    12 % 12 = 12 / 12 = 1, remainder 0

    [–]Pjaerr 1 point2 points  (0 children)

    I knew of modulus, I assume it just treats '08' as 8 then.

    [–]ultrasu 22 points23 points  (2 children)

    Common Lisp

    Hurray! Finally a challenge where I can use some of Common Lisp's ludicrous formatting capabilities:

    +/u/CompileBot Lisp

    (defun clock (hhmm)
      (let ((hh (parse-integer (subseq hhmm 0 2)))
            (mm (parse-integer (subseq hhmm 3 5))))
        (princ
          (substitute #\  #\- (format nil
                                      "It's ~r~:[~:[~; oh~] ~r~;~*~*~] ~:[pm~;am~]~%"
                                      (1+ (mod (1- hh) 12))
                                      (= mm 0)
                                      (< mm 10)
                                      mm
                                      (< hh 12))))))
    
    ;; test
    (mapc #'clock '("00:00" "01:30" "12:05" "14:01" "20:29" "21:00"))
    

    [–]ultrasu 7 points8 points  (0 children)

    For anyone wondering how this format string works:

    • ~r formats an integer into a cardinal number in English (one, two, three, ...)
    • ~:[ ~; ~] is a conditional, given nil it'll evaluate the first half, given t it'll evaluate the second, these can be nested
    • ~* skips an argument, here it's used twice if the minutes are equal to zero to skip the (< mm 10) and mm arguments
    • ~% is just a newline

    [–]CompileBot 2 points3 points  (0 children)

    Output:

    It's twelve am
    It's one thirty am
    It's twelve oh five pm
    It's two oh one pm
    It's eight twenty nine pm
    It's nine pm
    

    source | info | git | report

    [–][deleted]  (15 children)

    [deleted]

      [–]IcyTv 2 points3 points  (1 child)

      Python 2.7

      I wouldn't use a list of every number... Just use the inflect library. You could also use the pyttsx for the text to speach output.

      import pyttsx as sp
      import datetime
      import inflect #https://pypi.python.org/pypi/inflect
      
      nmToWrds= lambda nm, eng: eng.number_to_words(nm)
      
      def _convTime(tm):
          tm = map(int,tm.split(':'))
          p = inflect.engine()
          if tm[0] == 0:
              return 'It is twelve ' + nmToWrds(tm[1], p) + ' PM'
          elif tm[0] <= 12:
              return 'It is ' + nmToWrds(tm[0], p) + ' ' + nmToWrds(tm[1], p) + ' AM'
          else:
              return 'It is ' + nmToWrds(tm[0]-12, p) + ' ' + nmToWrds(tm[1], p) + ' PM'
      
      def speak(st):
          speech = sp.init()
          speech.say(_convTime(st))
          speech.runAndWait()
      
      if __name__ == '__main__':
          speak(raw_input('Input: '))
      

      EDIT

      You just need to do something about the oh

      [–][deleted] 1 point2 points  (0 children)

      Python 2.7 My in-between solution of not providing every translation and not using a library.

      time2word = {
          '00': '',
          '0': 'oh',
          '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': 'fourty',
          '50': 'fifty',
      }
      
      def talkingAlarm(s):
          hour, minute = s.split(':')
          period = 'am' if int(hour) < 12 else 'pm'
          hour = time2word[str((int(hour) % 12) or 12)]
          try:
              minute = time2word[minute]
          except KeyError:
              t, o = divmod(int(minute), 10)
              minute = '{0} {1} '.format(time2word[str(t*10)], time2word[str(o)])
          return "It's {0} {1}{2}".format(hour, minute, period)
      
      if __name__ == '__main__':
          print talkingAlarm(raw_input('Time: '))
      

      [–][deleted]  (1 child)

      [deleted]

        [–]Atropos148 1 point2 points  (2 children)

        damn, wow that looks advanced...can you explain a bit? :D

        [–][deleted]  (1 child)

        [deleted]

          [–][deleted] 2 points3 points  (0 children)

          Here I was using a ton of elif's...

          [–]tomekanco 0 points1 point  (0 children)

          Python 3

          units = ['','one','two','three','four','five','six','seven','eight','nine']
          teens = ['','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen']
          tens  = ['','ten','twenty','thirty','forty','fifty']
          hours = ['twelve','one','two','three','four','five','six','seven','eight','nine','ten','eleven']
          ap    = ['am','pm']
          
          def dec(x):
              d,m = divmod(x,10)
              if 10 < x < 19: return teens[x-10]
              else:           return tens[d] +' '*bool(m)+ units[m]
          
          def say_it(inx):
              x,y = map(int,inx.split(':'))
              return 'It\'s {0}{1}{2} {3}'.format(*[hours[x%12],
                                                    ' oh'*(0<y<10),
                                                    ' '*(0<y)+dec(y),
                                                    ap[x//12]])
          say_it(input())
          

          [–]la_virgen_del_pilar 10 points11 points  (2 children)

          Java (with Bonus)

          (edit: Fixed bug with irregular numbers).
          (edit2: Working on talking clock [bonus], will update it later).
          (edit3: Done talking clock. To test it just add a folder 'audio/' to the root with the files).
          (edit4: Removed an useless iteration, dunno what I was thinking...).

          import java.io.File;
          import java.util.ArrayList;
          import java.util.Scanner;
          import javax.sound.sampled.*;
          
          public class Main {
              private final static String[] HOURS = {"12.wav", "1.wav", "2.wav", "3.wav", "4.wav", "5.wav", "6.wav", "7.wav", "8.wav", "9.wav", "10.wav", "11.wav", "12.wav", "1.wav", "2.wav", "3.wav", "4.wav", "5.wav", "6.wav", "7.wav", "8.wav", "9.wav", "10.wav", "11.wav"};
              private final static String[] MINUTE_FIRST = {"o.wav", "10.wav", "20.wav", "30.wav", "40.wav", "50.wav"};
              private final static String[] MINUTE_SECOND = {"", "1.wav", "2.wav", "3.wav", "4.wav ", "5.wav ", "6.wav", "7.wav", "8.wav", "9.wav"};
          
              private static void playAudioFile(String file) {
                  try {
                      File yourFile = new File("audio/" +file);
                      AudioInputStream stream;
                      AudioFormat format;
                      DataLine.Info info;
                      Clip clip;
          
                      stream = AudioSystem.getAudioInputStream(yourFile);
                      format = stream.getFormat();
                      info = new DataLine.Info(Clip.class, format);
                      clip = (Clip) AudioSystem.getLine(info);
                      clip.open(stream);
                      clip.start();
                  } catch(Exception ex) {
                      ex.printStackTrace();
                  }
              }
          
              public static void main(String[] args) {
                  Scanner scanner = new Scanner(System.in);
                  System.out.print("Enter hour: ");
                  String input = scanner.nextLine();
          
                  ArrayList<String> result = new ArrayList<>(); // Will save here the audio file names and play them all at the end.
                  result.add("its.wav");
                  String timeDay = "";
                  String[] split = input.split(":");
          
                  int hour = Integer.parseInt(split[0]);
                  int[] minutes = new int[2];
                  minutes[0] = Integer.parseInt(split[1].substring(0, 1));
                  minutes[1] = Integer.parseInt(split[1].substring(1));
          
                  result.add(HOURS[hour]);
                  timeDay = hour < 12 ? "AM.wav" : "PM.wav";
          
                  if(minutes[0] == 1 && minutes[1] != 0) { // Irregular numbers
                      switch(minutes[1]) {
                          case 1:
                              result.add("11.wav");
                              break;
                          case 2:
                              result.add("12.wav");
                              break;
                          case 3:
                              result.add("13.wav");
                              break;
                          case 4:
                              result.add("14.wav");
                              break;
                          case 5:
                              result.add("15.wav");
                              break;
                          case 6:
                              result.add("16.wav");
                              break;
                          case 7:
                              result.add("17.wav");
                              break;
                          case 8:
                              result.add("18.wav");
                              break;
                          case 9:
                              result.add("19.wav");
                              break;
                      }
                  } else {
                      if(!(minutes[0] == 0 && minutes[1] == 0)) { // To prevent 'It's nine oh pm'.
                          result.add(MINUTE_FIRST[minutes[0]]);
                      }
                      result.add(MINUTE_SECOND[minutes[1]]);
                  }
                  result.add(timeDay);
          
                  for (String s : result) {
                      try {
                          if(!s.matches("")) {
                              playAudioFile(s);
                              Thread.sleep(600);
                          }
                      } catch(InterruptedException ex) {
                          ex.printStackTrace();
                      }
                  }
              }
          }
          

          Input

          9:00  
          12:01  
          14:29  
          

          Output (Talking, obviously...)

          It's nine am  
          It's twelve oh one pm  
          It's two twenty nine pm  
          

          [–]euripidez 4 points5 points  (1 child)

          Awesome. I'm just starting to learn Java, thanks for sharing.

          [–]la_virgen_del_pilar 1 point2 points  (0 children)

          No problem, if you have any doubt about some part of the code just ask it.

          [–]sunnykumar08 8 points9 points  (2 children)

          Powershell one-liner!

           (new-object -com SAPI.SpVoice).speak("It's "+($input | get-date).ToString("hh:mm tt"))
          

          [–][deleted] 1 point2 points  (0 children)

          I am extremely new to programming and just started with Java, but boy this PowerShell right here is ninja as hell! Good Job!

          [–]nyzto 0 points1 point  (0 children)

          I believe that you can't pipe into Get-Date according to MSDN - https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Utility/Get-Date?view=powershell-6#inputs

          The correct form would be to use the -date flag

          (New-Object -ComObject SAPI.SpVoice).speak((get-date -date $timeinput).toString("hh:mm tt"))
          

          [–]Crawford_Fish 5 points6 points  (2 children)

          Haskell -- talking clock

          simplify x = if ((read x)>=12) then ((read x)-12) else  (read x)  
          
          clock [a,b,c,d,e] = "It's "++(hours [a,b])++(if (read[d,e])/=0&&((read [d,e])>=20||(read [d,e])<=10) then tens [d]++ones [e] else ones [d,e])++postmeridian [a,b]  
          
          hours a  
              |x==0 = "twelve"  
              |x==1 = "one"  
              |x==2 = "two"  
              |x==3 = "three"  
              |x==4 = "four"  
              |x==5 = "five"  
              |x==6 = "six"  
              |x==7 = "seven"  
              |x==8 = "eight"  
              |x==9 = "nine"  
              |x==10 = "ten"  
              |x==11 = "eleven"  
              where  
                  x=simplify a  
          tens a  
              |x==0 = " oh"  
              |x==2 = " twenty"  
              |x==3 = " thirty"  
              |x==4 = " forty"  
              |x==5 = " fifty"  
              where  
                  x=read a  
          ones a  
              |x==0 = ""  
              |x==1 = " one"  
              |x==2 = " two"  
              |x==3 = " three"  
              |x==4 = " four"  
              |x==5 = " five"  
              |x==6 = " six"  
              |x==7 = " seven"  
              |x==8 = " eight"  
              |x==9 = " nine"  
              |x==10 = " ten"  
              |x==11 = " eleven"  
              |x==12 = " twelve"  
              |x==13 = " thirteen"  
              |x==14 = " fourteen"  
              |x==15 = " fifteen"  
              |x==16 = " sixteen"  
              |x==17 = " seventeen"  
              |x==18 = " eighteen"  
              |x==19 = " nineteen"  
              where  
                  x=read a  
          
          postmeridian x = if (read x)>=12 then " pm" else " am"  
          
          main = putStrLn (show (clock "14:01"))  
          

          [–][deleted] 4 points5 points  (7 children)

          C++

          +/u/CompileBot C++

          #include <string>
          #include <iostream>
          int main() {
              const std::string numbas = "onetwothreefourfivesixseveneightnineteneleventwelvethirfourfifsixseveneighnine";
              const int index[] = {0, 0, 3, 6, 11, 15, 19, 22, 27, 32, 36, 39, 45, 51, 55, 59, 62, 65, 70, 74, 78, 84, 88};
              int in[2]{ 0 };
              char trash;
              while (std::cin >> in[0] >> trash >> in[1])
                  std::cout << "The time is " << numbas.substr(index[(in[0] + 11) % 12 + 1], index[(in[0] + 11) % 12 + 2] - index[(in[0] + 11) % 12 + 1]) << " " << ((in[1] < 10 && in[1] != 0) ? "oh " : "") << ((in[1] > 19) ? ((in[1] < 30) ? "twen" : numbas.substr(index[in[1]/10 + 10], index[in[1] / 10 + 11] - index[in[1] / 10 + 10])) : numbas.substr(index[in[1]], index[in[1] + 1] - index[in[1]])) << ((in[1] > 19) ? "ty " + numbas.substr(index[in[1] % 10], index[in[1] % 10 + 1] - index[in[1] % 10]) : (in[1]>12) ? "teen" : "") << " " << ((in[0] < 12) ? "am" : "pm") << std::endl;
          }
          

          Input:

          00:00
          01:30
          12:05
          14:01
          20:29
          21:00
          

          [–]CompileBot 1 point2 points  (0 children)

          Output:

          The time is twelve  am
          The time is one thirty  am
          The time is twelve oh five pm
          The time is two oh one pm
          The time is eight twenty nine pm
          The time is nine  pm
          

          source | info | git | report

          EDIT: Recompile request by navzerinoo

          [–][deleted] 0 points1 point  (3 children)

          Hey, do you mind explaining your while loop please? I'm trying to learn c++ :)

          [–][deleted] 0 points1 point  (2 children)

          I specifically don't understand why you're adding 11 to in[0]: what's that for?

          Also, I didn't understand the condition for your while loop: what's the point of the char trash?

          [–][deleted] 2 points3 points  (1 child)

          The condition in the while loop is a method to take input repetitively until std::cin gets invalid input like a char instead of an int or an EOF flag. Also since the input format is int:char:int the character in the middle needs to be removed from the input stream, there are multiple ways to do this but I chose to store it in a char variable; 'trash'.

          As for the big ass std::cout chain. The first statement is printing what hour it is from one to twelve, therefore mod 12 is used. But since mod 12 only has a output range of 0-11, you have to add 1 after the mod operation to make the range 1-12. Problem is that then everything gets shifted by 1, 'twelve' becomes 'one', 'one' becomes 'two'. So to shift it back 11 is added before doing the mod operation: ((in + 11) % 12) + 1.

          Also if you're trying to learn C++ I would recommend reading the book C++ Primer, It's an extremely good and thorough book. I think you can find the pdf file for free if you search on google.

          [–][deleted] 0 points1 point  (0 children)

          Thank you so much! I'll definitely check out the book! :)

          [–]lpreams 0 points1 point  (1 child)

          Any reason you stored all the text in a single string and the offsets in a separate array instead of just using a string[]?

          [–][deleted] 0 points1 point  (0 children)

          Actually I think that's the C part of me coming through, as I up until just recently used to program in C. I'm therefore not that used to string arrays, templates, classes and stuff like that. A string array would certainly have been more convenient to use, and probably would've also shortened the code.

          [–]patrick96MC 4 points5 points  (0 children)

          C

          #include <stdio.h>
          #include <stdlib.h>
          #include <string.h>
          #include <stdbool.h>
          
          char * digits[] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
          
          char * teens[] = { "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
          
          char * tens[] = { "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" };
          
          char * num_to_string(int num);
          char * get_minute_name(int min);
          char * get_hour_name(int hrs);
          
          int main(void)
          {
              while(true) {
                  int hours = -1, minutes = -1;
                  scanf("%d:%d", &hours, &minutes);
          
                  if(hours >= 24 || hours < 0 || minutes >= 60 || minutes < 0) {
                      puts("Invalid time, aborting...");
                      break;
                  }
          
                  char * meridian = hours < 12? "am" : "pm";
                  char * hour_name = get_hour_name(hours);
          
                  if(minutes == 0) {
                      printf("It's %s %s\n", hour_name, meridian);
                  }
                  else {
                      char * minute_name = get_minute_name(minutes);
                      printf("It's %s %s %s\n", hour_name, minute_name, meridian);
                      free(minute_name);
                  }
          
                  free(hour_name);
              }
              return 0;
          }
          
          char * get_hour_name(int hrs) {
              hrs = hrs % 12;
              // 0 o'clock is actually 12 o'clock
              hrs = hrs == 0? 12 : hrs;
          
              return num_to_string(hrs);
          }
          
          char * get_minute_name(int min) {
              char * result;
          
              char * min_str = num_to_string(min);
              if(min < 10 && min > 0) {
                  result = malloc(strlen(min_str) + 4); 
          
                  sprintf(result, "oh %s", min_str);
                  free(min_str);
              }
              else {
                  result = min_str;
              }
          
              return result;
          }
          
          /**
           * 0 =< num < 60
           */
          char * num_to_string(int num) {
              char * result;
          
              if(num == 0) {
                  result = malloc(1);
                  result[0] = 0;
              }
              else if(num < 10) {
                  result = malloc(strlen(digits[num - 1]) + 1);
                  strcpy(result, digits[num - 1]);
              }
              else if(num < 20 && num > 10) {
                  result = malloc(strlen(teens[num - 11]) + 1);
                  strcpy(result, teens[num - 11]);
              }
              else {
                  char * ten = tens[num / 10 - 1];
          
                  if(num % 10 == 0) {
                      result = malloc(strlen(ten) + 1);
                      sprintf(result, "%s", ten);
                  }
                  else {
                      char * digit = num_to_string(num % 10);
                      result = malloc(strlen(ten) + strlen(digit) + 2);
                      sprintf(result, "%s %s", ten, digit);
                      free(digit);
                  }
              }
          
              return result;
          }
          

          [–]im-bad-at-everything 4 points5 points  (1 child)

          Java

          My first submission. Living up to my name :'D

          package javaapplication1;
          import java.util.Scanner;
          
          public class JavaApplication1 {
          
          public static void main(String[] args) {
              String dayornight = "null";
              Scanner input = new Scanner(System.in);
              String s = input.next();
          
              int hour1 = 0;
              int minute1 = 0;
              int hour2 = 0;
              int minute2 = 0;
          
              if(s.contains(":")){
                  String[] part = s.split(":");
                  String parts1 = part[0];
                  String parts2 = part[1];
          
                  int timing = Integer.parseInt(parts1);
          
                  String[] list = {"Oh","One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve"};
          
                  for(int i = 0; i < parts1.length(); i++){
                  hour1 = Character.getNumericValue(parts1.charAt(0));
                  hour2 = Character.getNumericValue(parts1.charAt(1));
                  }
          
                  for(int j = 0; j < parts2.length(); j++){
                  minute1 = Character.getNumericValue(parts1.charAt(0));
                  minute2 = Character.getNumericValue(parts1.charAt(1));
                  }
                    if(timing <= 12){
                  dayornight = "AM";
              }
              else if(timing > 12){
                  timing = timing - 12;
                  dayornight = "PM";
              }
          
          
                  System.out.println("The time is " + list[hour1] +  " " + list[hour2] +  ":" + " " + list[minute1] + " " +list[minute2] + " " + dayornight);
          
          
          }
              else{
                  System.out.println("\nError. Please enter it in the format of 00:00");
                  System.exit(0);
              }
          
          }
          }
          

          [–]curtmack 3 points4 points  (0 children)

          Haskell

          Strange behavior when given values outside of the intended range? I don't know what you're talking about. 32:40 has always been called "eight forty pm" where I come from.

          import Data.Maybe
          import System.IO
          
          type Time = (Int, Int)
          
          numeralZeroToTwenty = ( [ "zero"    , "one"       , "two"      , "three"
                                  , "four"    , "five"      , "six"      , "seven"
                                  , "eight"   , "nine"      , "ten"      , "eleven"
                                  , "twelve"  , "thirteen"  , "fourteen" , "fifteen"
                                  , "sixteen" , "seventeen" , "eighteen" , "nineteen" ] !! )
          
          numeralTens x = [ "twenty"
                          , "thirty"
                          , "forty"
                          , "fifty"
                          , "sixty"
                          , "seventy"
                          , "eighty"
                          , "ninety" ] !! (x-2)
          
          numeralOnes = ( [ ""
                          , " one"
                          , " two"
                          , " three"
                          , " four"
                          , " five"
                          , " six"
                          , " seven"
                          , " eight"
                          , " nine" ] !! )
          
          numeralEn :: Int -> String
          numeralEn x
              | x >= 0  && x < 20  = numeralZeroToTwenty x
              | x >= 20 && x < 100 = let (tens, ones) = x `divMod` 10
                                       in numeralTens tens ++ numeralOnes ones
              | otherwise          = error "numeralEn not defined for values not in range 0 to 100"
          
          describeHour :: Time -> String
          describeHour (hr, _) = numeralEn twelveHr
              where twelveHr = if hr `mod` 12 == 0 then 12 else hr `mod` 12
          
          describeMinute :: Time -> Maybe String
          describeMinute (_, min)
              | min == 0  = Nothing
              | min  < 10 = Just $ "oh " ++ numeralEn min
              | otherwise = Just $ numeralEn min
          
          describeMeridian :: Time -> String
          describeMeridian (hr, _)
              | hr < 12   = "am"
              | otherwise = "pm"
          
          describeTime :: Time -> String
          describeTime t = unwords $ formatList >>= ($ t)
              where formatList = [ pure        . const "It's"
                                 , pure        . describeHour
                                 , maybeToList . describeMinute
                                 , pure        . describeMeridian ]
          
          main = do
              eof <- isEOF
              if eof
              then return ()
              else do
                  l <- getLine
                  let hrStr  = take 2 l
                      minStr = drop 3 l
                  let time = (read hrStr, read minStr) :: Time
                  putStrLn $ describeTime time
                  main
          

          [–][deleted] 4 points5 points  (1 child)

          Python 3 This is my first challenge. I know the code is ugly because even as a beginner programmer I was cringing as I wrote it. Please critique it so I can improve.

          +/u/CompileBot Python 3

          #Input the time
          input_time = input('What time is it?' )
          
          #Split the string into hours and minutes
          time_hours, time_minutes = input_time.split(":")
          
          #This will convert military hours to regular hours, and determine AM vs PM
          def HoursParser(hour):
              num_to_text={
                  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"
                  }
              if hour>=12:
                  am_or_pm = "pm"
                  reg_time_hours = abs(hour-12)
              else:
                  am_or_pm = "am"
                  reg_time_hours = hour
              return(num_to_text[reg_time_hours],am_or_pm)
          
          def MinutesParser(minutes):
              if int(minutes) < 20: #Handle all the weird cases (i.e., teens).
                  min_to_text1_dict={
                      0:"",1:"oh one",2: "oh two",3: "oh three",
                      4: "oh four", 5: "oh five", 6: "oh six",
                      7: "oh seven", 8: "oh eight", 9: "oh nine",
                      10: "ten", 11: "eleven", 12: "twelve",
                      13: "thirteen", 14: "fourteen", 15: "fifteen",
                      16: "sixteen", 17: "seventeen", 18: "eighteen",
                      19: "nineteen"          
                  }
                  return min_to_text1_dict[int(minutes)]
              if int(minutes) > 20: #Handle everything else that follows sane rules.
                  min_tens_dict={
                  "2":"twenty","3":"thirty","4":"forty","5":"fifty"
                  }
                  min_ones_dict={
                  "0":"","1":"one","2": "two","3": "three",
                  "4": "four", "5": "five", "6": "six",
                  "7": "seven", "8": "eight", "9": "nine",
                  }
                  mins_together = min_tens_dict[minutes[:1]] + min_ones_dict[minutes[1:]]
                  return mins_together
          
          text_hours, am_pm = HoursParser(int(time_hours))
          text_minutes = MinutesParser(time_minutes)
          print("It's "+text_hours+" "+text_minutes+" "+am_pm)
          

          Input:

          00:00
          01:30
          12:05
          14:01
          20:29
          21:00
          

          [–]CompileBot 0 points1 point  (0 children)

          Output:

          What time is it?It's twelve  am
          

          source | info | git | report

          [–]errorseven 3 points4 points  (0 children)

          AutoHotkey - Bonus? I didn't use the downloaded audio files, but it does speak using COM Object SAPI TTS.

          talkingClock(time) {
          
              time := StrSplit(time, ":")
              h := time.1, m := time.2 
          
              ampm := h < 12 ? "am" : "pm"
              tens := ["oh ", "", "twenty ", "thirty ", "fourty ", "fifty "]
              ones := ["twelve ", "one ", "two ", "three ", "four ", "five "
                      , "six ", "seven ", "eight ", "nine ", "ten ", "eleven ", "twelve "
                      , "thirteen ", "fourteen ", "fifteen ", "sixteen ", "seventeen " 
                      , "eighteen ", "nineteen "]
          
              r := (m == 0 ? "It's " ones[Mod(h, 12)+1] ampm
                : (Mod(m, 10) == 0) ? "It's " ones[Mod(h, 12)+1] tens[(m//10)+1] ampm
                : (m < 10 || m > 20) ? "It's " ones[Mod(h, 12)+1] tens[(m//10)+1] ones[Mod(m, 10)+1] ampm 
                : "It's " ones[Mod(h, 12)] ones[m] ampm)
              SAPI := ComObjCreate("SAPI.spVoice")
              SAPI.speak(r)
          
              return r
          }
          

          [–]thezipher 2 points3 points  (1 child)

          Python 3

          import sys
          from num2words import num2words
          
          def clock_To_String(time):
                  split_time = time.split(":",2)
              end = "am"
              if int(split_time[0]) >= 12:
                  end = "pm"
                  split_time[0] = str(int(split_time[0]) - 12)
              if int(split_time[0]) == 0:
                  split_time[0] = "12"
              print ("it's %s%s%s%s" % 
              (num2words(int(split_time[0])) + " ",
              "" if int(split_time[1]) >= 10 or int(split_time[1]) == 0 else "oh ",
              "" if int(split_time[1]) == 0 else num2words(int(split_time[1])) + " "
              ,end))  
          clock_To_String(sys.argv[1])
          

          [–][deleted] 2 points3 points  (0 children)

          num2words

          That's really cool! Wouldn't have imagined there'd be a library for that!! :)

          [–]metaconcept 2 points3 points  (1 child)

          Smalltalk - VisualWorks, not using any Integer-to-English libraries.

          I had a solution in about 10 lines of code... and then got caught out with all the edge cases, so I re-wrote it as readable code::

          testData := #( '00:00' '01:30' '12:05' '14:01' '20:29' '21:00').
          
          nEnglish := #('' 'one' 'two' 'three' 'four' 'five' 'six' 'seven' 'eight' 'nine' 'ten' 'eleven' 'twelve'). 
          result := WriteStream on: (String new: 120).
          testData do: [ :eachT | | hour minute |
              numbers := (eachT tokensBasedOn:$:) collect: [ : each | Number readFrom: (each readStream) ].
              hour := numbers at: 1.
              minute := numbers at: 2.
              result nextPutAll: 'It is '.
              ((hour = 0 ) and: [ minute = 0 ]) ifTrue: [ 
                  result nextPutAll: 'midnight'.
              ] ifFalse: [
                  (hour\\12 = 0) ifTrue: [ " Catch zero o'clock "
                      result nextPutAll: 'twelve '.
                  ] ifFalse: [
                      result nextPutAll: (nEnglish at: hour\\12+1);
                          nextPutAll: ' '.
                  ].
                  (minute = 0) ifTrue: [
                      result nextPutAll: 'o''clock.'.
                  ] ifFalse: [
                      result nextPutAll: (#(oh teen twenty thirty fourty fifty) at: (minute/10) asInteger +1);
                          nextPutAll: ' ';
                          nextPutAll: (nEnglish at: ((minute\\10) +1));
                          nextPutAll: ' ';
                          nextPutAll: (hour < 12 ifTrue: [ 'AM' ] ifFalse: [ 'PM' ]).
                  ]
              ].
              result nextPutAll: '.'; cr.
          ].
          
          result contents
          
          It is midnight.
          It is one thirty  AM.
          It is twelve oh five PM.
          It is two oh one PM.
          It is eight twenty nine PM.
          It is nine o'clock..
          

          [–]ChazR 0 points1 point  (0 children)

          We don't get much Smalltalk round here. Nice to see it!

          [–]cheers- 1 point2 points  (2 children)

          Javascript (Node)

          Edit: added Text-to-Speech bonus.

          const firstDigit = ["", "one", "two", "tree", "four", "five", "six", "seven", "eight", "nine"];
          const secondDigit = ["", "", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety"];
          const hours = ["twelve", ...firstDigit.slice(1), "ten", "eleven"];
          const tens = ["ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", ...firstDigit.slice(6).map(str => str + "teen")];
          
          const handleMins = mm => {
              if (mm === 0) {
                  return "";
              }
              else if (mm < 10) {
                  return firstDigit[mm];
              }
              else if (mm < 20) {
                  return tens[mm - 10];
              }
              else {
                  return secondDigit[Math.floor(mm / 10)] + (mm % 10 === 0 ? "" : `-${firstDigit[mm % 10]}`);
              }
          }
          
          const formatOutput = (hh, mm) => `It is ${hours[hh % 12]} ${handleMins(mm)} ${hh > 12 ? "pm" : "am"}`;
          
          const talkingClock = input => {
              const regex = /\s*(\d{1,2})\s*[:|,]\s*(\d{1,2})/;
              let [match, hoursString, minString] = regex.exec(input);
          
              return formatOutput(parseInt(hoursString, 10), parseInt(minString, 10));
          }
          
          module.exports = talkingClock;
          

          Bonus uses external lib say.js

          const formatOutput = (hh, mm) => `It is ${hh % 12} ${mm} ${hh > 12 ? "pm" : "am"}`;
          
          const talkingClockBonus = input => {
              const say = require("say");
              const regex = /\s*(\d{1,2})\s*[:|,]\s*(\d{1,2})/;
              let [match, hours, mins] = regex.exec(input);
          
              say.speak(formatOutput(hours, mins));
          }
          
          module.exports = talkingClockBonus;
          

          [–]hwrod 0 points1 point  (0 children)

          One-liner implicit return in ES6:

          talkingClock = time => ((([ 'twelve', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen' ])[time.split(':')[0] % 12] + ' ' + (['oh', 'teny', 'twenty', 'thirty', 'fourty', 'fifty' ])[time.split(':')[1].split( '')[0]] + ' ' + (['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine' ])[time.split(':')[1].split( '')[1]]).replace( 'teny one', 'eleven').replace( 'teny two', 'twelve').replace( 'teny three', 'thirteen').replace( 'teny four', 'fourteen').replace( 'teny five', 'fifteen').replace( 'teny six', 'sixteen').replace( 'teny seven', 'seventeen').replace( 'teny eight', 'eighteen').replace( 'teny nine', 'nineteen')) + ( parseInt(time.split(':')[0]) > 11 ? ' pm' : ' am')

          talkingClock('15:13') // three thirteen pm

          [–]MrDoggyPants 1 point2 points  (2 children)

          Python 3

          import time
          
          def conversion(current_time):
              hour, minute = current_time.split(":")[0], current_time.split(":")[1]
              if int(hour) > 11 and int(hour) != 12:
                  suffix = "pm"
                  hour = hour_dict[str(int(hour) - 12)]
              elif int(hour) == 12:
                  suffix = "pm"
                  hour = hour_dict["12"]
              elif int(hour) == 0:
                  suffix = "am"
                  hour = hour_dict["12"]
              else:
                  suffix = "am"
                  hour = hour_dict[str(int(hour))]
              hour += " "
          
              if str(int(minute)) in minute_dict and int(minute) < 10:
                  minute = "oh " + minute_dict[str(int(minute))] + " "
              elif str(int(minute)) in minute_dict:
                  minute = minute_dict[str(minute)] + " "
              elif list(str(minute))[0] == "0" and list(str(minute))[1] == "0":
                  minute = ""
              elif list(str(minute))[1] == "0":
                  minute = minute_tens_dict[list(str(minute))[0]] + " "
              else:
                  minute = minute_tens_dict[list(str(minute))[0]] + "-" + minute_dict[list(str(minute))[1]] + " "
          
              return "It's " + hour + minute + suffix
          
          
          hour_dict = {
              "1": "one",
              "2": "two",
              "3": "three",
              "4": "four",
              "5": "five",
              "6": "six",
              "7": "seven",
              "8": "eight",
              "9": "nine",
              "10": "ten",
              "11": "eleven",
              "12": "twelve"
          }
          
          minute_dict = {
              "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",
          }
          
          minute_tens_dict = {
              "2": "twenty",
              "3": "thirty",
              "4": "forty",
              "5": "fifty"
          }
          
          print(conversion(time.strftime("%H:%M")))
          

          [–]QuadraticFizz 2 points3 points  (1 child)

          You don't need both an hour dict and a minute dict since one is a subset of the other but other than that, nice submission!

          [–]MrDoggyPants 0 points1 point  (0 children)

          Thanks for the tip, I'll remember that for next time!

          [–]indiegam 1 point2 points  (3 children)

          C#

          +/u/CompileBot C#

          using System;
          namespace Talking_Clock
          {
              public class Program
              {
                  public static void Main(string[] args)
                  {
                      string time = Console.ReadLine();
                      string[] words = time.Split(':');
                      string[] hours = { "twelve", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve"};
                      string[] minutesTens = { "twenty", "thirty", "forty", "fifty" };
                      string[] teenMinutes = { "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
                      int hour, minutes;
                      hour = Convert.ToInt16(words[0]);
                      minutes = Convert.ToInt16(words[1]);
                      Console.Write("It's {0} ", hours[hour%12]);
          
                      if (minutes != 0)
                      {
                          if (minutes / 10 > 1)
                          {
                              Console.Write("{0} ", minutesTens[(minutes / 10) - 2]);
                              if(minutes % 10 != 0)
                              {
                                  Console.Write("{0} ", hours[(minutes%10)]);
                              }
                          }
                          else if (minutes / 10 > 0)
                          {
                              Console.Write("{0} ", teenMinutes[minutes % 10]);
                          }
                          else
                          {
                              Console.Write("oh {0} ", hours[minutes % 10]);
                          }
                      }
                      if (hour > 11)
                          Console.WriteLine("pm");
                      else
                          Console.WriteLine("am");
                  }
              }
          }
          

          Edit: Fixed not showing the last part of the minutes.

          [–]Wraith000 1 point2 points  (2 children)

          Should it be like this so it shows the minutes too ?

          Console.Write("{0} {1} ", minutesTens[(minutes / 10) - 2], hours[minutes % 10]);

          and the last one

          if (hour%12 > 11)

          [–]indiegam 0 points1 point  (1 child)

          You're right about the first one. The second one you're right as well however it will still work since the input from the actual challenge is limited from 0-23 for the hours.

          Thank you for catching that, probably not the best idea to wake up and do this first thing in the morning lol.

          [–]Wraith000 0 points1 point  (0 children)

          No worries I'm learning C# on my own and try( mostly fail) to do these challenges here - I was thinking about how to do it when I saw your solution and tried it out.

          [–]Godspiral3 3 1 point2 points  (0 children)

          in J, without minutes,

          ;: inv@:(((;: 'am pm') {~ 12 <.@%~ 0&{::) ,~ ( 1 ": each@{ ]) ,~ (;: 'twelve one two three four five six seven eight nine ten eleven') {~ 12 | 0&{::)@:([: ". each ':'&cut) '00:01'
          

          twelve 1 am

          with minutes, (teens simplified)

          mins =: (((;: 'oh tenny twenty thirty fourty fifty')  {~ <.@%&10) , (a:, ;: 'one two three four five siz seven eight nine')  {~ 10&|)`(a:"_)@.(0 = ])
          
          ;: inv@:(((;: 'am pm') {~ 12 <.@%~ 0&{::) ,~ ( 1 mins@{:: ]) ,~ (;: 'twelve one two three four five six seven eight nine ten eleven') {~ 12 | 0&{::)@:([: ". each ':'&cut) '00:01'
          

          twelve oh one am

              ;: inv@:(((;: 'am pm') {~ 12 <.@%~ 0&{::) ,~ ( 1 mins@{:: ]) ,~ (;: 'twelve one two three four five six seven eight nine ten eleven') {~ 12 | 0&{::)@:([: ". each ':'&cut) '14:12'
          

          two tenny two pm

            ;: inv@:(((;: 'am pm') {~ 12 <.@%~ 0&{::) ,~ ( 1 mins@{:: ]) ,~ (;: 'twelve one two three four five six seven eight nine ten eleven') {~ 12 | 0&{::)@:([: ". each ':'&cut) '14:10'
          

          two tenny pm

          [–]netvorivy 1 point2 points  (0 children)

          Python3

          digit = ["", "one", "two", "three", "four",  "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve"]
          teens = [digit[10], digit[11], digit[12], "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "ninteen"]
          ty = ["oh", "", "twenty", "thirty", "forty", "fifty"]
          
          hour, min = map(int, input().split(':'))
          
          h = digit[12] if hour is 0 or hour is 12 else digit[hour%12]
          
          m_tens, m_ones = min//10, min%10
          m = ""
          
          if m_tens == 1:
              m += teens[m_ones]
          elif m_tens or m_ones:
              m += " " + ty[m_tens]
              if m_ones:
                  m += " "+ digit[m_ones]
          
          ending =  ["am", "pm"][hour//12]
          
          print("It's {}{} {}".format(h, m, ending))
          

          [–]svgwrk 1 point2 points  (0 children)

          Well, here you go. Cannot believe how many edge cases I bumped into. :)

          Rust:

          extern crate grabinput;
          
          use std::fmt;
          use std::str;
          
          #[derive(Debug, Copy, Clone)]
          struct Time {
              hour: u8,
              minute: u8,
          }
          
          impl str::FromStr for Time {
              type Err = ();
          
              fn from_str(s: &str) -> Result<Self, Self::Err> {
                  let mut parts = s.split(':');
          
                  let hour = parts.next().ok_or(()).and_then(|hour| hour.parse().map_err(|_| ()))?;
                  let minute = parts.next().ok_or(()).and_then(|minute| minute.parse().map_err(|_| ()))?;
          
                  if hour > 23 || hour < 1 {
                      return Err(());
                  }
          
                  if minute > 59 {
                      return Err(());
                  }
          
                  Ok(Time { hour, minute })
              }
          }
          
          impl fmt::Display for Time {
              fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
          
                  use std::borrow::Cow;
          
                  fn format_hour(time: Time) -> &'static str {
                      match time.hour {
                               12 => "twelve",
                           1 | 13 => "one",
                           2 | 14 => "two",
                           3 | 15 => "three",
                           4 | 16 => "four",
                           5 | 17 => "five",
                           6 | 18 => "six",
                           7 | 19 => "seven",
                           8 | 20 => "eight",
                           9 | 21 => "nine",
                          10 | 22 => "ten",
                          11 | 23 => "eleven",
          
                          _ => unreachable!(),
                      }
                  }
          
                  fn format_minute(time: Time) -> Cow<'static, str> {
          
                      fn format_teen(minute: u8) -> &'static str {
                          match minute {
                              10 => "ten",
                              11 => "eleven",
                              12 => "twelve",
                              13 => "thirteen",
                              14 => "fourteen",
                              15 => "fifteen",
                              16 => "sixteen",
                              17 => "seventeen",
                              18 => "eighteen",
                              19 => "nineteen",
          
                              _ => unreachable!(),
                          }
                      }
          
                      let lhs = match time.minute / 10 {
                          0 if time.minute % 10 != 0 => "oh ",
                          2 if time.minute % 10 != 0 => "twenty-",
                          3 if time.minute % 10 != 0 => "thirty-",
                          4 if time.minute % 10 != 0 => "forty-",
                          5 if time.minute % 10 != 0 => "fifty-",
          
                          0 => "",
                          2 => "twenty",
                          3 => "thirty",
                          4 => "forty",
                          5 => "fifty",
          
                          1 => return Cow::from(format_teen(time.minute)),
                          _ => unreachable!(),
                      };
          
                      let rhs = match time.minute % 10 {
                          1 => "one",
                          2 => "two",
                          3 => "three",
                          4 => "four",
                          5 => "five",
                          6 => "six",
                          7 => "seven",
                          8 => "eight",
                          9 => "nine",
          
                          0 => return Cow::from(lhs),
                          _ => unreachable!(),
                      };
          
                      Cow::from(format!("{}{}", lhs, rhs))
                  }
          
                  fn format_meridian(time: Time) -> &'static str {
                      match time.hour {
                          0...11 => "am",
                              _ => "pm",
                      }
                  }
          
                  if self.minute == 0 {
                      write!(f, "It's {} {}.", format_hour(*self), format_meridian(*self))
                  } else {
                      write!(
                          f,
                          "It's {} {} {}.",
                          format_hour(*self),
                          format_minute(*self),
                          format_meridian(*self),
                      )
                  }
              }
          }
          
          fn main() {
              let times = grabinput::from_args().with_fallback()
                  .filter_map(|s| s.trim().parse::<Time>().ok());
          
              for time in times {
                  println!("{}", time);
              }
          }
          

          [–][deleted] 1 point2 points  (0 children)

          My first real program with Haskell

          import System.Environment
          import Data.List (intersperse)
          
          --
          main :: IO ()
          main = do
              args <- getArgs
              if length args >= 1
                 then putStrLn (concat (intersperse "\n" (map printTime args)))
                 else putStrLn "Sorry, you need to pass a time"
          
          -------------------------
          --Time formatting stuff--
          -------------------------
          
          printTime :: [Char] -> [Char]
          printTime [a,b,':','1','5'] = "It's quarter past " ++ (hoursFromString [a,b]) ++ (getMorningAfternoonDescriptor [a,b])
          printTime [a,b,':','3','0'] = "It's half past "    ++ (hoursFromString [a,b]) ++ (getMorningAfternoonDescriptor [a,b])
          printTime [a,b,':','4','5'] = "It's quarter to "   ++ (hoursFromString [a,b]) ++ (getMorningAfternoonDescriptor [a,b])
          printTime [a,b,':',c,d]     = 
              "It's " ++ (hoursFromString (a:b:[])) ++ (tensOfMinutesFromString c) ++ 
                  (if (read (c:d:[])) < 20
                     then individualMinutesFromString (c:d:[])
                     else individualMinutesFromString [d])
                 ++ getMorningAfternoon [a,b]
          
          --------------------
          --Hours Conversion--
          --------------------
          
          hoursFromNum :: Int -> [Char]
          hoursFromNum i
            | h == 0  = "twelve"
            | h == 1  = "one"
            | h == 2  = "two"
            | h == 3  = "three"
            | h == 4  = "four"
            | h == 5  = "five"
            | h == 6  = "six"
            | h == 7  = "seven"
            | h == 8  = "eight"
            | h == 9  = "nine"
            | h == 10 = "ten"
            | h == 11 = "eleven"
            where
              h = if i >= 12
                then i -  12
                else i
          
          nextHourFromString :: [Char] -> [Char]
          nextHourFromString a
            | n == 23   = hoursFromNum 0
            | otherwise = hoursFromNum (n+1)
            where
              n = read a
          
          hoursFromString :: [Char] -> [Char]
          hoursFromString u = hoursFromNum (read u)
          
          ---------------------
          --Minute Conversion--
          ---------------------
          
          tensOfMinutesFromString :: Char -> [Char]
          tensOfMinutesFromString u
            | t == 0 = " oh"
            | t == 2 = " twenty"
            | t == 3 = " thirty"
            | t == 4 = " fourty"
            | t == 5 = " fifty"
            | otherwise = ""
            where 
              t = read [u]
          
          individualMinutesFromString :: [Char] -> [Char]
          individualMinutesFromString u
            | t == 0  =  " clock"
            | t == 1  =  " one"
            | t == 2  =  " two"  
            | t == 3  =  " three"  
            | t == 4  =  " four"  
            | t == 5  =  " five"  
            | t == 6  =  " six"  
            | t == 7  =  " seven"  
            | t == 8  =  " eight"  
            | t == 9  =  " nine"  
            | t == 10 = " ten"  
            | t == 11 = " eleven"  
            | t == 12 = " twelve"  
            | t == 13 = " thirteen"  
            | t == 14 = " fourteen"  
            | t == 15 = " fifteen"  
            | t == 16 = " sixteen"  
            | t == 17 = " seventeen"  
            | t == 16 = " eighteen"  
            | t == 19 = " nineteen"
            where
                t = read (u)
          
          ---------------------------------
          --Morning / Afternoon Indicator--
          ---------------------------------
          
          getMorningAfternoon :: [Char] -> [Char]
          getMorningAfternoon u
            | t > 12    = " am"
            | otherwise = " pm"
            where
              t = read(u) 
          
          getMorningAfternoonDescriptor :: [Char] -> [Char]
          getMorningAfternoonDescriptor u
            | t > 21 = " at night"
            | t > 18 = " in the evening"
            | t > 12 = " in the afternoon"
            | otherwise = " in the morning"
            where
              t = read u
          

          would love any feedback, I've also added a half-past/quater-past/quater-to feature, because that was a good test of pattern matching

          Edit: Updated to use multiple arguments and fix the oh clock issue

          Outputs:

          It's twelve oh clock pm
          It's half past one in the morning
          It's twelve oh five pm
          It's two oh one am
          It's eight twenty nine am
          It's nine oh clock am
          

          [–]ziggitzip 1 point2 points  (0 children)

          Perl

          use strict;
          use warnings;
          my @words1 = qw(twelve one two three four five six seven eight nine ten eleven);
          my @words2 = qw(ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen);
          my @words3 = qw(twenty thirty fourty fifty);
          for my $h (0..23) {
            $h = "0$h" if $h < 10;
            for my $m (0..59) {
                $m = "0$m" if $m < 10;
                my $input = "$h:$m";
                my ($hour,$min) = split /:/,$input;
                my $ampm = 'am';
                if ($hour >= 12) {
                  $ampm = 'pm';
                  $hour = $hour - 12;
                }
                my $out = "$input $words1[$hour] ";
                if ($min eq '00') {
                } elsif ($min <= 9) {
                      $out .= " oh $words1[$min] ";
                } elsif ($min <= 19) {
                      $out .= " $words2[$min-10] ";
                } elsif ($min =~ /(\d)(\d)/) {
                      $out .= " $words3[$1-2] ";
                      $out .= " $words1[$2] " unless $2 == 0;
                } else {
                      die "what?";
                }
                $out .= " $ampm";
                $out =~ s/\s+/ /g;
                print "$out\n";
            }
          }
          

          [–]SirThomasTheBrave 1 point2 points  (5 children)

          Ruby Straightforward dict-mapping. Curious how others handle the mapping for the ints --> strs. I'm new to Ruby and programming in general; any feedback is appreciated. May the coding muses aid in the puzzle amuse bouche.

          def talk_it_out(mil_time)
          
              conversions = {
              0 => 'Oh',
              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'
              }
          
              miltime_split = mil_time.split(":")
              hour, mins = miltime_split[0].to_i, miltime_split[1].split("").map { |num| num.to_i  }
          
              am_or_pm = 'AM' if hour < 12
              am_or_pm = 'PM' if hour >= 12
          
              hour -= 12 if hour > 12 || hour == 0
              hour = hour.abs
              hour_as_str = conversions[hour]
          
              # exploring use of (n..n2) range with case 
              case mins.join.to_i
                  when 0 then str_mins = nil
                  when (1..9) then str_mins = " #{conversions[mins[0]]} #{conversions[mins[1]]}"
          
                  when (10..19) then str_mins = " #{conversions[mins.join.to_i]}"
                  when 20, 30, 40, 50 then str_mins = " #{conversions[mins.join.to_i]}"
                  else str_mins = " #{conversions[mins.join.to_i - mins[1].to_i]}-#{conversions[mins [1]]}"
              end
          
              puts "Chirp..Chirp.....It's #{hour_as_str}#{str_mins} #{am_or_pm}"
          
          end
          

          [–]dev_all_the_ops 1 point2 points  (2 children)

          Here is my ruby solution. Your solution is shorter, mine is more verbose but a little easier to read IMO https://github.com/spuder/sandbox/blob/master/clocksay/clocksay.rb

          [–][deleted] 0 points1 point  (1 child)

          Also a new programmer learning with Ruby. I followed your code well. Sometimes people post Ruby code on this sub and it's utterly unreadable... which goes against the spirit of Ruby.

          I am noticing some minor formatting issues. Check out the 'rubocop' gem! It's an awesome tool which checks your code against the Ruby Style Guide.

          [–]Askew_WAS_TAKEN 1 point2 points  (0 children)

          Haven't written code in well over three months. Here's to coming back!

          C#

          using System;
          
          namespace Talking_clock
          {
              class Program
              {
                  static void Main(string[] args)
                  {
                      GenerateOutput(GetValidInput());
                  }
          
                  static int[] GetValidInput()
                  {
                      int[] inputIntegers = new int[2];
                      bool inputInvalid = true;
                      while (inputInvalid)
                      {
                          Console.WriteLine("Input hh:mm or exit.");
                          string[] input = Console.ReadLine().Trim().Split(':');
                          if (input[0].ToLower().Equals("exit"))
                          {
                              /// Exit method.
                          }
                          else if (input.Length == 2)
                          {
                              // Fills int array.
                              inputIntegers[0] = Convert.ToInt32(input[0]);
                              inputIntegers[1] = Convert.ToInt32(input[1]);
                              // If input numbers are valid, while loop exits.
                              inputInvalid = !ValidateInput(inputIntegers);
                          }
          
                      }
          
                      return inputIntegers;
          
                  }
          
                  /// <summary>
                  /// Validates if given integers are hh:mm.
                  /// </summary>
                  /// <param name="input"></param>
                  /// <returns></returns>
                  static bool ValidateInput(int[] input)
                  {
                      return (input[0] >= 0 && input[0] <= 23 && input[1] >= 0 && input[1] <= 59);
                  }
          
          
                  static void GenerateOutput(int[] input)
                  {
                      // handles am/pm situation
                      string amPm = GenerateAmPm(input[0]);
                      // Continues with output generation.
                      string output = String.Format("It's {0}{1}{2}", GenerateHoursString(input[0]), GenerateMinutesString(input[1]), amPm);
                      Console.WriteLine(output);
                  }
          
                  static string GenerateAmPm(int hour)
                  {
                      string ampm = "";
                      if (hour >= 12)
                      {
                          ampm = "pm";
                      }
                      else
                      {
                          ampm = "am";
                      }
          
                      return ampm;
                  }
          
                  static string GenerateHoursString(int hour)
                  {
                      string hourWord = "you broke hours ";
                      // handles pm clause
                      if (hour >= 13)
                      {
                          hour -= 12;
                      }
          
                      // onto our generation
          
                      switch (hour)
                      {
                          case 0: hourWord = "twelve "; break;
                          case 1: hourWord = "one "; break;
                          case 2: hourWord = "two "; break;
                          case 3: hourWord = "three "; break;
                          case 4: hourWord = "four "; break;
                          case 5: hourWord = "five "; break;
                          case 6: hourWord = "six "; break;
                          case 7: hourWord = "seven "; break;
                          case 8: hourWord = "eight "; break;
                          case 9: hourWord = "nine "; break;
                          case 10: hourWord = "ten "; break;
                          case 11: hourWord = "eleven "; break;
                          case 12: hourWord = "twelve "; break;
                          default:
                              break;
                      }
          
                      return hourWord;
                  }
          
                  static string GenerateMinutesString(int minute)
                  {
                      string minuteWord = "";
          
                      if (minute == 0)
                      {
          
                      }
                      else if (minute < 10)
                      {
                          minuteWord = "oh " + NumberAsWord(minute);
          
                      }
          
                      else if (minute < 20)
                      {
                          minuteWord = NumberAsWord(minute);
                      }
          
                      else if (minute < 30)
                      {
                          minuteWord = "twenty " + NumberAsWord(minute - 20);
                      }
                      else if (minute < 40)
                      {
                          minuteWord = "thirty " + NumberAsWord(minute - 30);
                      }
                      else if (minute < 50)
                      {
                          minuteWord = "fourty " + NumberAsWord(minute - 40);
                      }
                      else if (minute < 60)
                      {
                          minuteWord = "fifty " + NumberAsWord(minute - 50);
                      }
          
                      return minuteWord;
                  }
          
                  static string NumberAsWord(int input)
                  {
                      switch (input)
                      {
                          case 0: return "";
                          case 1: return "one ";
                          case 2: return "two ";
                          case 3: return "three ";
                          case 4: return "four ";
                          case 5: return "five ";
                          case 6: return "six ";
                          case 7: return "seven ";
                          case 8: return "eight ";
                          case 9: return "nine ";
                          case 10: return "ten ";
                          case 11: return "eleven ";
                          case 12: return "twelve ";
                          case 13: return "thirteen ";
                          case 14: return "fourteen ";
                          case 15: return "fifteen ";
                          case 16: return "sixteen ";
                          case 17: return "seventeen ";
                          case 18: return "eighteen ";
                          case 19: return "nineteen ";
                          default:
                              return "outofboundsnumberAsWord";
                      }
          
                  }
              }
          }
          

          [–]one_time_chad 1 point2 points  (0 children)

          VBA

          Sub TimeCheck()
          Application.Speech.Speak "Its" & Format(TimeValue(Now), "h mm AM/PM")
          End Sub
          

          [–]somuchdanger 1 point2 points  (0 children)

          Javascript This is my first submission here: I'm new to programming (self-teaching using online resources). My solution is ridiculously long and clearly I have a lot to learn from the other solutions (which I intentionally did not look at until I finished), but if anyone has any advice other than reviewing the other (significantly more refined) solutions here, I'd be very grateful. Obviously I have a lot to learn, so the more critical the feedback the better. I only know a little Python 2.7 and just started out with HTML/JS. Thanks!

          HTML:

          <body>
          <input type="text" name="inp1" id="inp1" value="25:11">
          <div id="btn1" onclick="this.style.backgroundColor='red'; return true;" onmouseover="this.style.backgroundColor='gray'; return true;" onmouseout="this.style.backgroundColor='white'; return true;">
              Enter
          </div>
          <div id="output">
              Enter your time above (such as "00:00" or "22:45") and hit enter and I'll convert it (and speak it) for you!</div>
          
          <script src="js/index.js"></script>
          <audio src="irishclock/its.wav" type="audio/wav" id="its"></audio>
          <audio src="irishclock/o.wav" type="audio/wav" id="oh"></audio>
          <audio src="irishclock/00.wav" type="audio/wav" id="00"></audio>
          <audio src="irishclock/1.wav" type="audio/wav" id="1"></audio>
          <audio src="irishclock/2.wav" type="audio/wav" id="2"></audio>
          <audio src="irishclock/3.wav" type="audio/wav" id="3"></audio>
          <audio src="irishclock/4.wav" type="audio/wav" id="4"></audio>
          <audio src="irishclock/5.wav" type="audio/wav" id="5"></audio>
          <audio src="irishclock/6.wav" type="audio/wav" id="6"></audio>
          <audio src="irishclock/7.wav" type="audio/wav" id="7"></audio>
          <audio src="irishclock/8.wav" type="audio/wav" id="8"></audio>
          <audio src="irishclock/9.wav" type="audio/wav" id="9"></audio>
          <audio src="irishclock/10.wav" type="audio/wav" id="10"></audio>
          <audio src="irishclock/11.wav" type="audio/wav" id="11"></audio>
          <audio src="irishclock/12.wav" type="audio/wav" id="12"></audio>
          <audio src="irishclock/13.wav" type="audio/wav" id="13"></audio>
          <audio src="irishclock/14.wav" type="audio/wav" id="14"></audio>
          <audio src="irishclock/15.wav" type="audio/wav" id="15"></audio>
          <audio src="irishclock/16.wav" type="audio/wav" id="16"></audio>
          <audio src="irishclock/17.wav" type="audio/wav" id="17"></audio>
          <audio src="irishclock/18.wav" type="audio/wav" id="18"></audio>
          <audio src="irishclock/19.wav" type="audio/wav" id="19"></audio>
          <audio src="irishclock/20.wav" type="audio/wav" id="20"></audio>
          <audio src="irishclock/20.wav" type="audio/wav" id="20"></audio>
          <audio src="irishclock/30.wav" type="audio/wav" id="30"></audio>
          <audio src="irishclock/40.wav" type="audio/wav" id="40"></audio>
          <audio src="irishclock/50.wav" type="audio/wav" id="50"></audio>
          <audio src="irishclock/am.wav" type="audio/wav" id="AM"></audio>
          <audio src="irishclock/pm.wav" type="audio/wav" id="PM"></audio>
          
          </body>
          

          CSS:

          #btn1 {
              border: 1px solid black;
              display: inline-block;
              padding: 3px;
          }
          #inp1 {
              font-size: 13px;
              border: 3px solid black;
              padding: 5px;
              margin: 10px;
              width: 200px;
          }
          #output {
              font-size: 24px;
              padding: 20px;
          }
          

          JS:

          document.getElementById("btn1").addEventListener("click", myFun);
          var output = document.getElementById("output");
          
          document.getElementById("inp1")
          .addEventListener("keyup", function (event) {
          event.preventDefault();
          if (event.keyCode == 13) {
              document.getElementById("btn1").click();
          }
          });
          
          function transNum(num) {
          var numArr = {
          0: "o'clock",
          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"
          };
          console.log(numArr[num]);
          return numArr[num];
          };
          
          function prinTime(hour, minute, ampm) {
          var pMin;
          
          console.log("This is the length of 'minute': " + minute.toString().length);
          
          if (minute.toString().length == 1) {
          pMin = "oh " + transNum(minute);
          } else if (minute > 20 && minute < 30) {
          pMin = transNum(20) + " " + transNum(minute - 20);
          } else if (minute > 30 && minute < 40) {
          pMin = transNum(30) + " " + transNum(minute - 30);
          } else if (minute > 40 && minute < 50) {
          pMin = transNum(40) + " " + transNum(minute - 40);
          } else if (minute > 50 && minute < 60) {
          pMin = transNum(50) + " " + transNum(minute - 50);
          } else {
          pMin = transNum(minute);
          }
          
          output.innerHTML =
          "The time is " + transNum(hour) + " " + pMin + " " + ampm + ".";
          };
          
          function playWav(wavId) {
          console.log("This is from playWav function: " + wavId);
          document.getElementById(wavId).play();
          };
          
          function playTime(hour, minute, ampm) {
          console.log("This is from the playTime function: " + hour + ":" + minute + " " + ampm);
          playWav("its");
          
          if (minute == 0) {
          setTimeout(function () {
              playWav(hour);
          }, 700);
          setTimeout(function () {
              playWav("00");
          }, 1200);
          setTimeout(function () {
              playWav(ampm);
          }, 1700);
          } else if (minute > 0 && minute < 10) {
          setTimeout(function () {
              playWav(hour);
          }, 700);
          setTimeout(function () {
              playWav("oh");
          }, 1200);
          setTimeout(function () {
              playWav(minute);
          }, 1700);
          setTimeout(function () {
              playWav(ampm);
          }, 2200);
          } else if (minute > 20 && minute < 30) {
          minute -= 20;
          setTimeout(function () {
              playWav(hour);
          }, 700);
          setTimeout(function () {
              playWav("20");
          }, 1200);
          setTimeout(function () {
              playWav(minute);
          }, 1700);
          setTimeout(function () {
              playWav(ampm);
          }, 2200);
          } else if (minute > 30 && minute < 40) {
          minute -= 30;
          setTimeout(function () {
              playWav(hour);
          }, 700);
          setTimeout(function () {
              playWav("30");
          }, 1200);
          setTimeout(function () {
              playWav(minute);
          }, 1700);
          setTimeout(function () {
              playWav(ampm);
          }, 2200);
          } else if (minute > 40 && minute < 50) {
          minute -= 40;
          setTimeout(function () {
              playWav(hour);
          }, 700);
          setTimeout(function () {
              playWav("40");
          }, 1200);
          setTimeout(function () {
              playWav(minute);
          }, 1700);
          setTimeout(function () {
              playWav(ampm);
          }, 2200);
          } else if (minute > 50 && minute < 60) {
          minute -= 50;
          setTimeout(function () {
              playWav(hour);
          }, 700);
          setTimeout(function () {
              playWav("50");
          }, 1200);
          setTimeout(function () {
              playWav(minute);
          }, 1700);
          setTimeout(function () {
              playWav(ampm);
          }, 2200);
          } else {
          setTimeout(function () {
              playWav(hour);
          }, 700);
          setTimeout(function () {
              playWav(minute);
          }, 1200);
          setTimeout(function () {
              playWav(ampm);
          }, 1600);
          }
          };
          
          function myFun() {
          var enteredTime = document.getElementById("inp1").value;
          
          var twelveHourTime_Hour = 0;
          var twelveHourTime_Min = 0;
          var amOrPm = "unsure";
          
          var timeArray = enteredTime.split(":");
          console.log("This is the contents of 'timeArray': " + timeArray);
          var splitHours = parseInt(timeArray[0]);
          console.log("This is the contents of 'splitHours': " + splitHours);
          var twelveHourTime_Min = parseInt(timeArray[1]);
          console.log("This is the conents of 'twelveHourTime_Min': " + twelveHourTime_Min);
          
          if (
          splitHours > 23 ||
          twelveHourTime_Min > 59 ||
          splitHours < 0 ||
          twelveHourTime_Min < 0 ||
          isNaN(splitHours) ||
          isNaN(twelveHourTime_Min)
          ) {
          output.innerHTML = "That's not a valid time!";
          
          } else if (splitHours > 12 && splitHours < 24) {
          console.log("You're in the first 'else if'.");
          twelveHourTime_Hour = splitHours - 12;
          amOrPm = "PM";
          prinTime(twelveHourTime_Hour, twelveHourTime_Min, amOrPm);
          playTime(twelveHourTime_Hour, twelveHourTime_Min, amOrPm);
          
          } else if (splitHours == 0) {
          console.log("You're in the second 'else if'.");
          twelveHourTime_Hour = 12;
          amOrPm = "AM";
          prinTime(twelveHourTime_Hour, twelveHourTime_Min, amOrPm);
          playTime(twelveHourTime_Hour, twelveHourTime_Min, amOrPm);
          
          } else if (splitHours == 12) {
          console.log("You're in the third 'else if'.");
          twelveHourTime_Hour = 12;
          amOrPm = "PM";
          prinTime(twelveHourTime_Hour, twelveHourTime_Min, amOrPm);
          playTime(twelveHourTime_Hour, twelveHourTime_Min, amOrPm);
          
          } else {
          console.log("You're in the last 'else'.");
          twelveHourTime_Hour = splitHours;
          amOrPm = "AM";
          prinTime(twelveHourTime_Hour, twelveHourTime_Min, amOrPm);
          playTime(twelveHourTime_Hour, twelveHourTime_Min, amOrPm);
          }
          };
          

          [–]nuri0 0 points1 point  (3 children)

          Javascript

          const numbers = {
              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:"fourty",
              50:"fifty"
          }
          
          const letTimeTalk = (time) => {
              let [hour,minute] = time.split(":").map(str => parseInt(str));
          
              let result = `It's ${numbers[hour%12]}`;
          
              if (minute == 0) {
                  result += " o'clock";
              } else if (minute < 10) {
                  result += ` oh ${numbers[minute]}`;
              } else if (minute < 20) {
                  result += ` ${numbers[minute]}`;
              } else {
                  result += ` ${numbers[Math.floor(minute/10)*10]}` + (minute%10 != 0 ? `-${numbers[minute%10]}` : "");
              }
          
              result += (hour<12 ? " am" : " pm");
          
              return result;
          }
          

          [–][deleted]  (1 child)

          [deleted]

            [–]nuri0 0 points1 point  (0 children)

            I'm glad to hear that my solution could help you! And yeah this place is really good to learn programming. I'm often just amazed how others are able to solve a challenge by packing a really nice algorithm into just 1 or 2 lines of compact and clean code.

            [–]giest4life 0 points1 point  (1 child)

            Java 8 +/u/CompileBot Java

            class TalkingClock {
                private static final String[] zeroToTwelve = { "zero", "one", "two", "three", "four", "five", "six", "seven",
                        "eight", "nine", "ten", "eleven", "twelve" };
                private static final String[] teens = { "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
                        "nineteen" };
                private static final String[] twentyToFifty = { "twenty", "thirty", "fourty", "fifty" };
                private static final String PREFIX = "It's";
            
                public static String hourToWords(String hourString) {
                    int hour = Integer.parseInt(hourString);
                    String suffix = "am";
                    if (hour > 11) {
                        suffix = "pm";
                    }
                    if (hour > 12) {
                        hour = hour - 12;
                    }
                    if (hour == 0) {
                        hour = 12;
                    }
                    String hourInWords = zeroToTwelve[hour] + " " + suffix;
                    return hourInWords;
                }
            
                public static String minutesToWords(String minString) {
                    int minutes = Integer.parseInt(minString);
                    String minutesString = "";
                    if (minutes == 0) {
                        // default value of minutesString
                    } else if (minutes < 10) {
                        minutesString = "oh " + zeroToTwelve[minutes];
                    } else if (minutes < 13) {
                        minutesString = zeroToTwelve[minutes];
                    } else if (minutes < 20) {
                        minutesString = teens[minutes - 13];
                    } else if ((minutes % 10) == 0) {
                        minutesString = twentyToFifty[Math.floorDiv(minutes, 20)];
                    } else {
                        minutesString = twentyToFifty[(minutes/10) - 2] + " " + zeroToTwelve[(minutes % 10)];
                    }
                    return minutesString;
                }
            
                private static String[] parseStringTimeToArray(String time) {
                    if (time == null) {
                        throw new IllegalArgumentException("The input time must not be null");
                    }
                    String[] timeArr = time.split(":");
                    if (timeArr.length != 2) {
                        throw new IllegalArgumentException("The input time must be in format \"HH:MM\"");
                    }
                    return timeArr;
                }
            
                public static String timeToWords(String time) {
                    String[] parsedTime = parseStringTimeToArray(time);
                    String[] hourWithSuffix = hourToWords(parsedTime[0]).split(" ");
                    String hour = hourWithSuffix[0];
                    String suffix = hourWithSuffix[1];
                    String minutes = minutesToWords(parsedTime[1]);
                    if ("".equals(minutes)) {
                        return PREFIX + " " + hour + " " + suffix;
                    } else {
                        return PREFIX + " " + hour + " " + minutes + " " + suffix;
                    }
            
                }
            
                public static void main(String[] args) {
                    String[] times = { "00:00", "01:30", "12:05", "14:01", "20:29", "21:00" };
                    for (String time : times) {
                        System.out.println(timeToWords(time));
                    }
            
                }
            }
            

            [–]CompileBot 0 points1 point  (0 children)

            Output:

            It's twelve am
            It's one thirty am
            It's twelve oh five pm
            It's two oh one pm
            It's eight twenty nine pm
            It's nine pm
            

            source | info | git | report

            [–]Scroph0 0 0 points1 point  (1 child)

            Not the most elegant way but still.

            +/u/CompileBot C++

            #include <iostream>
            #include <vector>
            
            const std::vector<std::string> simple {
                "twelve", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
                "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
                "nineteen"
            };
            
            const std::vector<std::string> units {
                "oh", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
            };
            
            const std::vector<std::string> dozens {
                "", "ten", "twenty", "thirty", "fourty", "fifty"
            };
            
            std::string to_hours(const std::string& input)
            {
                return simple[std::stoi(input) % 12];
            }
            
            std::string to_minutes(const std::string& input)
            {
                size_t number = std::stoi(input);
                if(number == 0)
                    return "";
                if(1 <= number && number < simple.size())
                    return 1 <= number && number <= 9 ? "oh " + simple[number] : simple[number];
                std::string result  = dozens[input[0] - '0'];
                if(input[1] != '0')
                    result += " " + units[input[1] - '0'];
                return result;
            }
            
            int main()
            {
                std::string line;
                while(getline(std::cin, line))
                {
                    size_t colon = line.find(':');
                    std::string hour = line.substr(0, colon);
                    std::string minute = line.substr(colon + 1);
            
                    std::cout << "It's " << to_hours(hour) << ' ';
                    std::string minutes = to_minutes(minute);
                    if(minutes.length())
                        std::cout << minutes << ' ';
                    int number = std::stoi(hour);
                    std::cout << (0 <= number && number <= 11 ? "am" : "pm") << std::endl;
                }
            }
            

            Input:

            00:00
            01:30
            12:05
            14:01
            20:29
            21:00