Это лучший способ разработать эту функцию?

Меня зовут Майкл Бутрос, и я сейчас учусь в старшей школе. В следующем году я буду учиться в Университете Ватерлоо и в качестве учебного пособия по их курсам 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;
Другие вопросы по тегам