Weekly Challenge 348
Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.
Task 1: String Alike
Tasks
You are given a string of even length.
Write a script to find if the given string split into two halves of equal lengths and they both have same number of vowels.
My solution
The main logic for this challenge is a function called count_vowels. The takes a string and returns the number of vowels. The Python code for this function is
def count_vowels(s: str) -> int:
vowels = 'aeiouAEIOU'
return sum(1 for char in s if char in vowels)
Not to be outdone, it's a single line in Perl.
sub count_vowels ($s) {
return $s =~ tr/aeiouAEIOU/aeiouAEIOU/;
}
With that out of the way, the main function
- Throws an error if there there there is not an even number of characters in the
input_string. - Return False if there is are no vowels in the
input_string. - Set the variables
first_halfandsecond_half. - Compare the number of vowels in each half.
- Return True if the two string have the same number of vowels, else False.
def string_alike(input_string: str) -> bool:
if len(input_string) % 2 == 1:
raise ValueError("Input string must have an even length.")
if count_vowels(input_string) == 0:
return False
first_half = input_string[:len(input_string)//2]
second_half = input_string[len(input_string)//2:]
return count_vowels(first_half) == count_vowels(second_half)
The Perl solution follows the same logic.
sub string_alike ($input_string) {
die "Input string must have an even length."
if length($input_string) % 2 == 1;
if ( count_vowels($input_string) == 0 ) {
say "False";
return;
}
my $mid = length($input_string) / 2;
my $first_half = substr( $input_string, 0, $mid );
my $second_half = substr( $input_string, $mid );
say count_vowels($first_half) == count_vowels($second_half)
? "True"
: "False";
}
Examples
$ ./ch-1.py textbook
False
$ ./ch-1.py book
True
$ ./ch-1.py AbCdEfGh
True
$ ./ch-1.py rhythmmyth
False
$ ./ch-1.py UmpireeAudio
False
Task 2: Covert Time
Task
You are given two strings, $source and $target, containing time in 24-hour time form.
Write a script to convert the source into target by performing one of the following operations:
- Add 1 minute
- Add 5 minutes
- Add 15 minutes
- Add 60 minutes
Find the total operations needed to get to the target.
My solution
For this task I have created a function called time_to_minutes that takes the time in HH:MM format, and returns the minutes since midnight. It also checks that the time is in a valid format, and the hours (0-23) and minutes (0-59) minutes are in range.
def time_to_minute(s: str) -> int:
if not re.match(r'^\d{1,2}:\d{2}$', s):
raise ValueError("Invalid time format, should be HH:MM")
hour, minute = map(int, s.split(':'))
if hour < 0 or hour > 23 or minute < 0 or minute > 59:
raise ValueError("Invalid time format")
return hour * 60 + minute
In the main function, I set a variable duration that is the minutes difference between the source and target. If this value is negative, the time crosses midnight, so I add 1440 (60 × 24) minutes to compute the correct duration.
def convert_time(source: str, target: str) -> int:
duration = time_to_minute(target) - time_to_minute(source)
if duration < 0:
duration += 24 * 60
I set the moves list (array in Perl) to the possible moves, with the largest first. For each move, I make as many moves as possible, adding the number of moves to the count variable, and reducing duration to what remains.
moves = [60, 15, 5, 1]
count = 0
for move in moves:
count += duration // move
duration %= move
return count
The Perl solution follows the same logic.
Examples
$ ./ch-2.py 02:30 02:45
1
$ ./ch-2.py 11:55 12:15
2
$ ./ch-2.py 09:00 13:00
4
$ ./ch-2.py 23:45 00:30
3
$ ./ch-2.py 14:20 15:25
2
Top comments (0)