That's a beautiful monstrosity, good job :D Did you run it through some kind of minifier? You're missing an extra ) in your first test case :) and you're printing an extra space in one thirty am.
That's a beautiful monstrosity, good job :D Did you run it through some kind of minifier?
You're missing an extra ) in your first test case :) and you're printing an extra space in one thirty am.
Implemented in GNU Awk. I hacked this together in a few minutes, it's not the best, but I believe it does the job. EDIT: I just noticed this program doesn't work with minutes 13-19. Oh well,...
Implemented in GNU Awk. I hacked this together in a few minutes, it's not the best, but I believe it does the job.
EDIT: I just noticed this program doesn't work with minutes 13-19. Oh well, better luck next time.
#!/run/current-system/sw/bin/awk -f# If on a non-NixOS system, replace with /usr/bin/awk -f# Write the times in a separate file on each line and then pass that# file to the program, something like this:# ./talking_clock.awk input.txtBEGIN{FS=":"nums[0]="twelve"nums[1]="one"nums[2]="two"nums[3]="three"nums[4]="four"nums[5]="five"nums[6]="six"nums[7]="seven"nums[8]="eight"nums[9]="nine"nums[10]="ten"nums[11]="eleven"nums[12]="twelve"other[2]="twenty"other[3]="thirty"other[4]="forty"other[5]="fifty"}{first_num=$1%12printf"It's"printf" %s",nums[first_num]if($2<10&&$2!=0){printf" oh %s",nums["0"+$2]}elseif($2!=0){printf" %s",other[int($2/10)]snd_digit=$2-int($2/10)*10if(snd_digit!=0){printf" %s",nums[snd_digit]}}if($1<12){printf" am\n"}else{printf" pm\n"}}
Rust (1.28, nightly): Takes input as the first argument to the program. use std::env; use std::process; fn num(n: i32) -> String { match n { 21..=29 => format!("{} {}", num(20), num(n - 20)),...
Rust (1.28, nightly): Takes input as the first argument to the program.
use std::env;
use std::process;
fn num(n: i32) -> String {
match n {
21..=29 => format!("{} {}", num(20), num(n - 20)),
31..=39 => format!("{} {}", num(30), num(n - 30)),
41..=49 => format!("{} {}", num(40), num(n - 40)),
51..=59 => format!("{} {}", num(50), num(n - 50)),
_ => match n {
1 => "one",
2 => "two",
3 => "three",
4 => "four",
5 => "five",
6 => "six",
7 => "seven",
8 => "eight",
9 => "nine",
10 => "ten",
11 => "eleven",
12 => "twelve",
13 => "thirteen",
14 => "fourteen",
15 => "fifteen",
16 => "sixteen",
17 => "seventeen",
18 => "eighteen",
19 => "nineteen",
20 => "twenty",
30 => "thirty",
40 => "forty",
50 => "fifty",
_ => unreachable!(),
}.to_string()
}
}
fn hour(h: i32) -> Option<(String, String)> {
let am = String::from("am");
let pm = String::from("pm");
match h {
0 => Some((num(12), am)),
1..=11 => Some((num(h) , am)),
12 => Some((num(12), pm)),
13..=23 => Some((num(h - 12) , pm)),
_ => None,
}
}
fn minute(m: i32) -> Option<String> {
match m {
0 => Some("".to_string()),
1..=9 => Some(format!("oh {}", num(m))),
10..=59 => Some(num(m)),
_ => None,
}
}
fn main() {
if let Some(input) = env::args().skip(1).next() {
let parts = input.split(":").collect::<Vec<&str>>();
if parts.len() == 2 {
let h = String::from(*parts.get(0).unwrap()).parse::<i32>();
let m = String::from(*parts.get(1).unwrap()).parse::<i32>();
if !(h.is_ok() && m.is_ok()) {
eprintln!("Could not parse input");
process::exit(1);
}
let hour = hour(h.unwrap());
let minute = minute(m.unwrap());
if !(hour.is_some() && minute.is_some()) {
eprintln!("Invalid input");
process::exit(1);
}
let hour = hour.unwrap();
let minute = minute.unwrap();
if minute.len() != 0 {
println!("It's {} {} {}",
hour.0,
minute,
hour.1);
}
else {
println!("It's {} {}",
hour.0,
hour.1);
}
}
else {
eprintln!("Could not parse input");
process::exit(1);
}
}
else {
eprintln!("No argument given");
process::exit(1);;
}
}
Some quick and dirty JS. It could be better, but it's 4am and I spent the daylight hours programming at work, so I'll worry about quality some other time :) function intToHumanReadable(value) {...
Some quick and dirty JS. It could be better, but it's 4am and I spent the daylight hours programming at work, so I'll worry about quality some other time :)
Python. Some might say it's over engineered, I like writing easy to read code. I'm glad I made a function for most of the steps. I'm a tad annoyed with minute_text() because of how it turns...
Python. Some might say it's over engineered, I like writing easy to read code. I'm glad I made a function for most of the steps. I'm a tad annoyed with minute_text() because of how it turns numbers above 20 into text. Any suggestions about the minute_text() function are very welcome as long as they are easy to read.
Also: Woho! Let the coding challenges begin!
Edit: I wish I had planned this program. Even though it's small it would have benefited from more though. Just shows that to make a program readable all the way through you need to plan.
numbers_in_text = {
0: "",
1: "one",
2: "two",
3: "three",
4: "four",
5: "five",
6: "six",
7: "seven",
8: "eight",
9: "nine",
10: "ten",
11: "eleven",
12: "twelve",
13: "thirteen",
14: "fourteen",
15: "fifteen",
16: "sixteen",
17: "seventeen",
18: "eightteen",
19: "nineteen",
20: "twenty",
30: "thirty",
40: "fourty",
50: "fifty"
}
def time_text(time):
"""Returns text representation of the time."""
hour, minute = hour_and_minute(time)
time_of_day = am_or_pm(hour)
hour = converted_hour_from_24_to_12(hour)
time_in_text = hour_in_text(hour)
if minute and minute not in [15,30, 45]:
time_in_text += " oh "
elif minute in [15,30, 45]:
time_in_text += " "
time_in_text += minute_text(minute)
time_in_text += " " + time_of_day
return time_in_text
def hour_text(hour):
"""Returns an hour as text."""
if hour == 0:
hour_in_text = "twelve"
else:
hour_in_text = numbers_in_text[hour]
return hour_in_text
def minute_text(minute):
"""Returns a minute as text."""
minute_in_text = ""
if 0 <= minute <= 19:
minute_in_text = numbers_in_text[minute]
else:
minute_string = str(minute)
ones, tens = minute_string[0], minute_string[1]
minute_in_text += numbers_in_text[tens]
minute_in_text += numbers_in_text[ones]
return minute_in_text
def hour_and_minute(time):
"""Returns which hours it is in $time."""
hour = time.split(":")[0]
minute = time.split(":")[1]
hour, minute = int(hour), int(minute)
return hour, minute
def am_or_pm(hour):
"""Returns if the hour is AM or PM."""
time_of_day = ""
if 0 <= hour <= 11:
time_of_day = "am"
elif 12 <= hour <= 23:
time_of_day = "pm"
return time_of_day
def converted_hour_from_24_to_12(hour):
converted_hour = hour % 12
return converted_hour
times = ["00:00", "13:45", "9:05"]
for time in times:
print(time_text(time))
I believe I saw a discussion yesterday about how important naming is in code. Assuming you don't have plans to revisit this project in two weeks, I admire your variable names. I'm guilty of using...
I believe I saw a discussion yesterday about how important naming is in code. Assuming you don't have plans to revisit this project in two weeks, I admire your variable names. I'm guilty of using one to two letter variable names for coding challenge type questions.
I see that you and other commenters hard-coded the teens, specifically 14-19. I wonder how you could translate 0-20 with the fewest duplicated string literals without becoming a mess of if-else/switch-cases and the cleanest way to substitute similar spoken languages (such as Spanish and Portuguese).
I meant exactly what you did. Python is full of crazy looking stuff that fits the bill "is the time/energy saved ... worth making this extra line?" Readable or not, there's always some kooky...
I meant exactly what you did. Python is full of crazy looking stuff that fits the bill "is the time/energy saved ... worth making this extra line?" Readable or not, there's always some kooky solution built in to this language.
I used python. It's probablsy not the best solution but i guess it works ¯\_(ツ)_/¯ hours = 0 minutes = 0 amOrPM = "am" oh = "" translation = ["", "One", "Two", "Three", "Four", "Five", "Six",...
I used python. It's probablsy not the best solution but i guess it works ¯\_(ツ)_/¯
My Haskell implementation. I'm sure there room for improvement, I don't have a ton of Haskell experience. getText :: Int -> [(Int, String)] -> String getText n translation = snd (head (filter...
My Haskell implementation. I'm sure there room for improvement, I don't have a ton of Haskell experience.
Perl 6 Tests #!/usr/bin/env perl6 use v6.c; use Local::Tildes::Challenge; use Test; is convert('00:00'), "It's twelve am"; is convert('01:30'), "It's one thirty am"; is convert('12:05'), "It's...
Perl 6
Tests
#!/usr/bin/env perl6
use v6.c;
use Local::Tildes::Challenge;
use Test;
is convert('00:00'), "It's twelve am";
is convert('01:30'), "It's one thirty am";
is convert('12:05'), "It's twelve oh five pm";
is convert('14:01'), "It's two oh one pm";
Source
#!/usr/bin/env perl6
use v6.c;
unit module Local::Tildes::Challenge;
my %translations =
0 => "oh",
10 => "ten",
11 => "eleven",
12 => "twelve",
15 => "fifteen",
20 => "twenty",
30 => "thirty",
40 => "fourty",
50 => "fifty",
;
for 1..9 {
%translations{$_} = $_.Str.uninames.head.split(' ').tail.lc
}
sub convert (
Str:D $time,
--> Str
) is export {
my ($hours, $minutes) = $time.split(':');
my $stringified = "{convert-hours($hours)} {convert-minutes($minutes)} {am-pm($hours)}".subst(/\s+/, ' ', :g);
"It's $stringified";
}
sub am-pm (
Str:D $hours,
--> Str
) {
$hours.Int < 12 ?? "am" !! "pm";
}
sub convert-hours (
Str:D $hours,
--> Str
) {
my $hours-int = $hours.Int % 12;
return %translations{12} if $hours-int == 0;
%translations{$hours-int};
}
sub convert-minutes (
Str:D $minutes,
--> Str
) {
my $spoken = '';
return '' if $minutes eq '00';
return %translations{$minutes} if (%translations ∋ $minutes.Str);
for $minutes.comb {
$spoken ~= %translations{$_} ~ ' ';
}
$spoken.trim;
}
Did it in C#. Mostly works, it has some issues with a few numbers (apparently 11-19 returns nothing and when testing I also saw 00:59 return nothing) that I should fix, but I'm already running...
Did it in C#. Mostly works, it has some issues with a few numbers (apparently 11-19 returns nothing and when testing I also saw 00:59 return nothing) that I should fix, but I'm already running late.
Did it in Kotlin, didn't feel like jumping out of the comfort zone today: data class Time(val hours: Int, val minutes: Int) { fun hoursIn12() = hours.rem(12) } fun Int.onesDigit() = this.rem(10)...
Did it in Kotlin, didn't feel like jumping out of the comfort zone today:
data class Time(val hours: Int, val minutes: Int) {
fun hoursIn12() = hours.rem(12)
}
fun Int.onesDigit() = this.rem(10)
val sampleInput = listOf(
"00:00",
"00:59",
"01:30",
"12:05",
"14:01",
"23:59"
)
fun main(args: Array<String>) {
sampleInput.map {
val time = Time(parseHours(it), parseMinutes(it))
val hourString = when(time.hours) {
0 -> translationMapTeens[12]
in 1..9 -> translationMapOnes[time.hours]
in 10..12 -> translationMapTeens[time.hours]
in 13..21 -> translationMapOnes[time.hoursIn12()]
in 22..24 -> translationMapTeens[time.hoursIn12()]
else -> ""
}
val minuteString = when(time.minutes) {
0 -> ""
in 1..9 -> "oh ${translationMapOnes[time.minutes]}"
in 10..19 -> translationMapTeens[time.minutes]
in 20..29 -> "${translationMapOther[20]} ${translationMapOnes[time.minutes.onesDigit()]}"
in 30..39 -> "${translationMapOther[30]} ${translationMapOnes[time.minutes.onesDigit()]}"
in 40..49 -> "${translationMapOther[40]} ${translationMapOnes[time.minutes.onesDigit()]}"
in 50..59 -> "${translationMapOther[50]} ${translationMapOnes[time.minutes.onesDigit()]}"
else -> "[tr]"
}
val amPm = if(isAm(time.hours)) AM else PM
"It's $hourString $minuteString $amPm"
}
.forEach{ println(it) }
}
fun parseHours(input: String): Int = input.subSequence(0, 2).toString().toInt()
fun parseMinutes(input: String): Int = input.subSequence(3, 5).toString().toInt()
fun isAm(hours: Int) = hours < 12
fun isOnes(minutes: Int) = minutes in 0..10
val translationMapOnes = mapOf<Int, String>(
0 to "",
1 to "one",
2 to "two",
3 to "three",
4 to "four",
5 to "five",
6 to "six",
7 to "seven",
8 to "eight",
9 to "nine"
)
val translationMapTeens = mapOf<Int, String>(
10 to "ten",
11 to "eleven",
12 to "twelve",
13 to "thirteen",
14 to "fourteen",
15 to "fifteen",
16 to "sixteen",
17 to "seventeen",
18 to "eighteen",
19 to "nineteen"
)
val translationMapOther = mapOf<Int, String>(
20 to "twenty",
30 to "thirty",
40 to "fourty",
50 to "fifty"
)
const val AM = "AM"
const val PM = "PM"
Here's my implementation in rust fn to_words (val: u32) -> String { let mut ans = String::new(); if val >= 50 { ans.push_str("fifty"); } else if val >= 40 { ans.push_str("forty"); } else if val >=...
Here's my implementation in rust
fn to_words (val: u32) -> String {
let mut ans = String::new();
if val >= 50 {
ans.push_str("fifty");
} else if val >= 40 {
ans.push_str("forty");
} else if val >= 30 {
ans.push_str("thirty");
} else if val >= 20 {
ans.push_str("twenty");
} else if val == 19 {
ans.push_str("nineteen");
} else if val == 18 {
ans.push_str("eighteen");
} else if val == 17 {
ans.push_str("seventeen");
} else if val == 16 {
ans.push_str("sixteen");
} else if val == 15 {
ans.push_str("fifteen");
} else if val == 14 {
ans.push_str("fourteen");
} else if val == 13 {
ans.push_str("thirteen");
} else if val == 12 {
ans.push_str("twelve");
} else if val == 11 {
ans.push_str("eleven");
} else if val == 10 {
ans.push_str("ten");
}
let val = {
if 10 <= val && val <= 19 {
0
} else {
val % 10
}
};
if !ans.is_empty() && val != 0 {
ans.push_str("-");
}
if val > 0 {
match val {
9 => ans.push_str("nine"),
8 => ans.push_str("eight"),
7 => ans.push_str("seven"),
6 => ans.push_str("six"),
5 => ans.push_str("five"),
4 => ans.push_str("four"),
3 => ans.push_str("three"),
2 => ans.push_str("two"),
1 => ans.push_str("one"),
_ => ans.push_str(""),
}
}
return ans;
}
fn main() {
let tests = [
"00:00",
"01:30",
"12:05",
"14:01"
];
for test in tests.iter() {
let hour = test[0..2].parse::<u32>().unwrap_or(0);
let minute = test[3..5].parse::<u32>().unwrap_or(0);
let hour_str = to_words( if hour % 12 != 0 {hour % 12} else {12} );
let minute_str = to_words(minute);
let period = if hour < 12 {"am"} else {"pm"};
println!("It's {} {} {} {}",
hour_str,
if !minute_str.is_empty() {"oh"} else {""},
minute_str,
period
);
}
}
Here's my (probably too verbose/abuse of STL) semi-noob version in C++: #include <iostream> #include <vector> #include <string> #include <map> #include <sstream> void get_the_time(std::vector<int>...
Here's my (probably too verbose/abuse of STL) semi-noob version in C++:
I like python
That's a beautiful monstrosity, good job :D Did you run it through some kind of minifier?
You're missing an extra
)
in your first test case :) and you're printing an extra space inone thirty am
.Ah, not sure how that
)
got lost, I've added it back.No tooling was used, just moving code around until it was one expression.
This makes me feel dirty.
Perfect.
MoonScript:
Implemented in GNU Awk. I hacked this together in a few minutes, it's not the best, but I believe it does the job.
EDIT: I just noticed this program doesn't work with minutes 13-19. Oh well, better luck next time.
Rust (1.28, nightly): Takes input as the first argument to the program.
Some quick and dirty JS. It could be better, but it's 4am and I spent the daylight hours programming at work, so I'll worry about quality some other time :)
Stuff that bothers me right off the bat:
No comments.
Logic is too tightly entangled.
Too many assumptions.
No error handling.
Naming could be better.
Some of this stuff could be separated out quite a bit better.
Python. Some might say it's over engineered, I like writing easy to read code. I'm glad I made a function for most of the steps. I'm a tad annoyed with
minute_text()
because of how it turns numbers above 20 into text. Any suggestions about theminute_text()
function are very welcome as long as they are easy to read.Also: Woho! Let the coding challenges begin!
Edit: I wish I had planned this program. Even though it's small it would have benefited from more though. Just shows that to make a program readable all the way through you need to plan.
I believe I saw a discussion yesterday about how important naming is in code. Assuming you don't have plans to revisit this project in two weeks, I admire your variable names. I'm guilty of using one to two letter variable names for coding challenge type questions.
I see that you and other commenters hard-coded the teens, specifically 14-19. I wonder how you could translate 0-20 with the fewest duplicated string literals without becoming a mess of if-else/switch-cases and the cleanest way to substitute similar spoken languages (such as Spanish and Portuguese).
you could
Is the time/energy saved from typing worth making this extra line? Is it neccessary writing fewer string literals? Does it improve the code?
What do you mean with the below?
Doesn't work for fifteen, unless people started calling it fiveteen when I wasn't looking.
Thanks.
I meant exactly what you did. Python is full of crazy looking stuff that fits the bill "is the time/energy saved ... worth making this extra line?" Readable or not, there's always some kooky solution built in to this language.
Wait. Why do you need numbers from 14-19? Am I missing something?
EDIT: nvm, I'm stupid. My solution doesn't even work with those numbers.
I used python. It's probablsy not the best solution but i guess it works ¯\_(ツ)_/¯
My Haskell implementation. I'm sure there room for improvement, I don't have a ton of Haskell experience.
You could replace a lot of parens with the $ operator.
Perl 6
Tests
Source
Did it in C#. Mostly works, it has some issues with a few numbers (apparently 11-19 returns nothing and when testing I also saw 00:59 return nothing) that I should fix, but I'm already running late.
Did it in Kotlin, didn't feel like jumping out of the comfort zone today:
can run it here
Here's my implementation in rust
Here's my (probably too verbose/abuse of STL) semi-noob version in C++: