package main

	import (
		"fmt"
		"strconv"
		"strings"
	)

	func main() {
		fmt.Println(TalkingClock("00:00"))
		fmt.Println(TalkingClock("01:30"))
		fmt.Println(TalkingClock("12:05"))
		fmt.Println(TalkingClock("14:01"))
		fmt.Println(TalkingClock("20:29"))
		fmt.Println(TalkingClock("21:00"))
	}

	func TalkingClock(time string) string {
		hour, minute := UnpackPair(time, ":")

		period := "am"
		if i, _ := strconv.Atoi(hour); i >= 12 {
			hour = strconv.Itoa(i - 12)
			period = "pm"
		}

		if minute == "00" {
			return "It's " + HourToWords(hour) + " " + period
		}

		return "It's " + HourToWords(hour) + " " + MinuteToWords(minute) + " " + period
	}

	func oneToTen(n string) string {
		i, _ := strconv.Atoi(n)
		switch i {
		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"
		default:
			return "ten"
		}
	}

	func HourToWords(hour string) string {
		i, _ := strconv.Atoi(hour)
		switch i {
		case 0:
			return "twelve"
		case 11:
			return "eleven"
		default:
			return oneToTen(hour)
		}
	}

	func MinuteToWords(minute string) string {
		if minute == "00" {
			return ""
		}

		if minute == "10" {
			return "ten"
		}

		imin, _ := strconv.Atoi(minute)

		if imin < 10 {
			return "oh " + oneToTen(minute)
		}

		if imin > 10 && imin < 16 {
			switch imin {
			case 11:
				return "eleven"
			case 12:
				return "twelve"
			case 13:
				return "thirteen"
			case 14:
				return "fourteen"
			default:
				return "fifteen"
			}
		}

		tens, ones := UnpackPair(minute, "")

		if imin < 20 {
			return oneToTen(ones) + "teen"
		}

		itens, _ := strconv.Atoi(tens)
		switch itens {
		case 2:
			tens = "twenty"
		case 3:
			tens = "thirty"
		case 4:
			tens = "fourty"
		default:
			tens = "fifty"
		}

		if i, _ := strconv.Atoi(ones); i == 0 {
			return tens
		}

		return tens + " " + oneToTen(ones)
	}

	func UnpackPair(str string, sep string) (string, string) {
		split := strings.SplitN(str, sep, 2)
		if len(split) == 1 {
			return split[0], ""
		}
		return split[0], split[1]
	}