Skip to main content
Code Review

Return to Answer

Commonmark migration
Source Link

##Updated Thoughts ##

Updated Thoughts

Final Solution

#Final Solution SinceSince a solution that reliably passes all test cases has yet to be put forth...

##Updated Thoughts ##

#Final Solution Since a solution that reliably passes all test cases has yet to be put forth...

Updated Thoughts

Final Solution

Since a solution that reliably passes all test cases has yet to be put forth...

Added a fully working solution
Source Link
Zack
  • 1.9k
  • 11
  • 13

#Final Solution Since a solution that reliably passes all test cases has yet to be put forth...

def flux_capacitor(time, mins)
 #check if time in valid format
 time_match = time.strip.match /^(12|11|10|0?\d):([012345]\d)\s+(AM|PM)/
 
 #throw error on invalid time
 raise(ArgumentError, "Invalid time: #{time.strip}") if not time_match
 
 #calculate new time
 strhours, strminutes, meridian = time_match.captures
 hours = (meridian == "AM" ? strhours.to_i : strhours.to_i + 12)
 total_minutes = hours * 60 + strminutes.to_i + mins
 total_minutes = total_minutes % (24*60) # we only want the minutes that fit within a day
 adjusted_hours, adjusted_minutes = total_minutes.divmod(60)
 if adjusted_hours > 12
 adjusted_hours -= 12
 meridian = "PM"
 else
 meridian = "AM"
 end
 
 "%d:%02d %s" % [adjusted_hours, adjusted_minutes, meridian]
end

Testing:

[ "11:13 PM", 
 "13:09 PM", #invalid!
 "1:59 AM", 
 "04:49 PM",
 "4:79 PM" #invalid!
].each do |time|
 begin
 puts flux_capacitor(time, 0)
 rescue 
 puts $!
 end
end
puts "----------"
puts "#{flux_capacitor("11:13 PM", 10)}, expected: 11:23 PM"
puts "#{flux_capacitor("11:13 PM", 12*60)}, expected 11:13 AM"
puts "#{flux_capacitor("11:13 PM", 24*60)}, expected 11:13 PM"
puts "#{flux_capacitor("11:13 PM", 24*60 + 1)}, expected 11:14 PM"
puts "#{flux_capacitor("11:59 AM", 62)}, expected 1:01 PM"
puts "#{flux_capacitor("11:59 PM", 62)}, expected 1:01 AM"

#Final Solution Since a solution that reliably passes all test cases has yet to be put forth...

def flux_capacitor(time, mins)
 #check if time in valid format
 time_match = time.strip.match /^(12|11|10|0?\d):([012345]\d)\s+(AM|PM)/
 
 #throw error on invalid time
 raise(ArgumentError, "Invalid time: #{time.strip}") if not time_match
 
 #calculate new time
 strhours, strminutes, meridian = time_match.captures
 hours = (meridian == "AM" ? strhours.to_i : strhours.to_i + 12)
 total_minutes = hours * 60 + strminutes.to_i + mins
 total_minutes = total_minutes % (24*60) # we only want the minutes that fit within a day
 adjusted_hours, adjusted_minutes = total_minutes.divmod(60)
 if adjusted_hours > 12
 adjusted_hours -= 12
 meridian = "PM"
 else
 meridian = "AM"
 end
 
 "%d:%02d %s" % [adjusted_hours, adjusted_minutes, meridian]
end

Testing:

[ "11:13 PM", 
 "13:09 PM", #invalid!
 "1:59 AM", 
 "04:49 PM",
 "4:79 PM" #invalid!
].each do |time|
 begin
 puts flux_capacitor(time, 0)
 rescue 
 puts $!
 end
end
puts "----------"
puts "#{flux_capacitor("11:13 PM", 10)}, expected: 11:23 PM"
puts "#{flux_capacitor("11:13 PM", 12*60)}, expected 11:13 AM"
puts "#{flux_capacitor("11:13 PM", 24*60)}, expected 11:13 PM"
puts "#{flux_capacitor("11:13 PM", 24*60 + 1)}, expected 11:14 PM"
puts "#{flux_capacitor("11:59 AM", 62)}, expected 1:01 PM"
puts "#{flux_capacitor("11:59 PM", 62)}, expected 1:01 AM"
added a more robust implementation
Source Link
Zack
  • 1.9k
  • 11
  • 13

More testing is required:

flux_capacitor("11:59 AM", 62)
 => "12:21 AM" 

Definitely test some corner cases.


##Updated Thoughts ##

I think you should completely rethink the way you are handling time. Use a regex to validate that time is a valid string, then simply use string.split to get each portion of the time: hours, minutes, and AM/PM.

Next you should convert those into a quantity of minutes:

hours += 12 if meridian == 'PM'
total_minutes = hours*60+minutes+mins

Next I would recalculate the time as a 24-hour time (which goes up to 23 hours, 59 minutes):

# this is integer math so the decimal portion will be discarded
# adjusted_minutes may be greater than 23, but adjusted_minutes should always be less than 60
adjusted_hours = (total_minutes / 60)
adjusted_minutes = total_minutes - (60*adjusted_hours)
# modulus 24 converts adjusted_hours into 24-hour time
adjusted_hours = adjusted_hours % 24

Now convert to 12 hour time if necessary and determine if this is AM or PM

# the added mins may have been several days worth, so adjusted_hours might be very large.
if adjusted_hours > 12
 meridian = "PM"
 adjusted_hours -= 12
else
 meridian = "AM"
end

Finally return a string of the new time:

# zero pad the minutes, as this is expected for a time
return "%d:%02d %s" % [adjusted_hours, adjusted_minutes, meridian]

More testing is required:

flux_capacitor("11:59 AM", 62)
 => "12:21 AM" 

Definitely test some corner cases.

More testing is required:

flux_capacitor("11:59 AM", 62)
 => "12:21 AM" 

Definitely test some corner cases.


##Updated Thoughts ##

I think you should completely rethink the way you are handling time. Use a regex to validate that time is a valid string, then simply use string.split to get each portion of the time: hours, minutes, and AM/PM.

Next you should convert those into a quantity of minutes:

hours += 12 if meridian == 'PM'
total_minutes = hours*60+minutes+mins

Next I would recalculate the time as a 24-hour time (which goes up to 23 hours, 59 minutes):

# this is integer math so the decimal portion will be discarded
# adjusted_minutes may be greater than 23, but adjusted_minutes should always be less than 60
adjusted_hours = (total_minutes / 60)
adjusted_minutes = total_minutes - (60*adjusted_hours)
# modulus 24 converts adjusted_hours into 24-hour time
adjusted_hours = adjusted_hours % 24

Now convert to 12 hour time if necessary and determine if this is AM or PM

# the added mins may have been several days worth, so adjusted_hours might be very large.
if adjusted_hours > 12
 meridian = "PM"
 adjusted_hours -= 12
else
 meridian = "AM"
end

Finally return a string of the new time:

# zero pad the minutes, as this is expected for a time
return "%d:%02d %s" % [adjusted_hours, adjusted_minutes, meridian]
Source Link
Zack
  • 1.9k
  • 11
  • 13
Loading
lang-rb

AltStyle によって変換されたページ (->オリジナル) /