Это лучший способ разработать эту функцию? - PullRequest
4 голосов
/ 20 июня 2011

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

2 голосов
/ 20 июня 2011

Да, вы можете написать этот код без каких-либо условий.Подумайте о преобразовании часов + минут в количество минут, затем вычитании и преобразовании результата обратно в часы + минуты.

0 голосов
/ 21 июня 2011

Я попытался сделать ответ, используя идею минутного преобразования, и придумал что-то, что, кажется, работает. Похоже на дискуссию, разрешено ли нам использовать условные выражения или нет, поэтому я старался не использовать их.

К сожалению, я ничего не знаю о Схеме, но, надеюсь, этот код достаточно ванильный, чтобы вы могли конвертировать.

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;
...