Это лучший способ разработать эту функцию?
Меня зовут Майкл Бутрос, и я сейчас учусь в старшей школе. В следующем году я буду учиться в Университете Ватерлоо и в качестве учебного пособия по их курсам CS я выполнил и выполнил некоторые задания. Язык, который они используют, - это Схема, и я изучаю его по ходу дела. Я родом из PHP и Ruby, поэтому беспокоюсь, что некоторые из моих привычек, извлеченных из этих языков, неправильно применяются к тому, что я делаю со схемой. Вот вопрос из задания (доступно онлайн, кстати):
Напишите функцию с именем sub-time, которая использует начальное время строки, представляющее время, и натуральное число mins, которое представляет количество минут до. Функция создает строку, представляющую минуты за несколько минут до заданного времени начала.
Используемая строка будет отформатирована следующим образом: двухзначное число, затем "часы", затем двухзначное число, а затем "минуты". Время занято в 24-часовом формате. Если количество часов или минут меньше 10, то число будет содержать начальный 0. Полученная строка должна быть точно в следующем формате: число, затем "часы", затем число, а затем "минуты". ". Обратите внимание, что созданная строка не имеет начального 0 перед числами меньше 10. Возможно, что произведенное время может представлять время предыдущего дня.
Например,
• (суб-время "03 часа 15 минут" 0) производит
"3 часа 15 минут",
• (суб-время "13 часов 05 минут" 845) производит
"23 часа 0 минут" и
• (суб-время "13 часов 05 минут" 2881) произведено
"13 часов 4 минуты"Встроенные функции Scheme string->number и number->string могут быть полезны.
Очень важно, чтобы вы создали строку точно так, как описано, иначе автотесты не пройдут. В частности, все символы должны быть в нижнем регистре, и между всеми частями строки должны быть одинарные пробелы.
Не используйте выражения cond в вашем решении.
(Честно говоря, я даже не заметил последнюю строку до сих пор, и мое решение использует условные выражения. Есть ли способ избежать их?)
Вот мое решение:
;; Assignment 1 Question 4
(define (convert-to-string hours minutes)
(string-append (number->string hours) " hours " (number->string minutes) " minutes"))
(define (subtract_hours start_hours sub_hours minutes)
(let ((hours (- start_hours (modulo sub_hours 24))))
(if (< hours 0)
(convert-to-string (+ 24 hours) minutes)
(convert-to-string hours minutes))))
(define (subtract_minutes start_hours start_minutes sub_hours sub_minutes)
(let ((minutes (- start_minutes sub_minutes)))
(if (< minutes 0)
(subtract_hours start_hours (+ 1 sub_hours) (+ 60 minutes))
(subtract_hours start_hours sub_hours minutes))))
(define (sub-time start-time mins)
(let ((start_hours (string->number (substring start-time 0 2)))
(start_minutes (string->number (substring start-time 9 11)))
(sub_hours (quotient mins 60))
(sub_minutes (modulo mins 60)))
(subtract_minutes start_hours start_minutes sub_hours sub_minutes)))
Я невероятно новичок в Scheme, и хотя мое решение работает (из моего ограниченного тестирования), мне интересно, что скажут некоторые опытные ветераны. Спасибо за ваше время!
2 ответа
Да, вы можете написать этот код без каких-либо условий. Подумайте о преобразовании часов + минут в количество минут, затем вычитании и преобразовании результата обратно в часы + минуты.
Я попытался сделать ответ, используя идею минутного преобразования, и придумал что-то, что, кажется, работает. Похоже на дискуссию, разрешено ли нам использовать условные выражения или нет, поэтому я старался не использовать их.
К сожалению, я ничего не знаю о Scheme, но, надеюсь, этот код достаточно ванильный, чтобы вы могли его преобразовать.
int offset; //the mins we are going to subtract
int startTimeInMins = inputHours * 60;
startTimeInMins += inputMins;
int offsetDayRolled = offset mod 1440;
int newTime = startTimeInMins - offsetDayRolled;
newTime += 1440;
newTime = newTime mod 1440;
int newHours = newTime / 60;
int newMins = newTime mod 60;