我想写一个
的函数1-消耗自然数(间隔)
2-生成一个计划,该计划是白天结构的列表 如下所示。
规则是,对于生成的每个列表,计划从(早上6点)开始,按给定间隔增加,并继续添加该间隔,直到它结束于(下午6点 - 即第18小时)并且不进行超过那个标记。 使用以下数据定义:
(define-struct daytime (hours minutes))
;; A Daytime is a (make-daytime Nat Nat)
;; requires the number that represents hours to be 6<= hours <= 18
;; and requires the number that represents minutes to be < 60
我遇到的问题是如何创建具有白天结构的列表?我创建了一个列表,但它使用“list”而不是make-day。 该计划的一个例子应该是:
(schedule 90) gives
(list (make-daytime 6 0) (make-daytime 7 30) (make-daytime 9 0)
(make-daytime 10 30) (make-daytime 12 0) (make-daytime 13 30)
(make-daytime 15 0) (make-daytime 16 30) (make-daytime 18 0))
答案 0 :(得分:1)
你的意思是,定义一个能够返回该列表的函数吗?嗯,你想要的例子会给你n分钟的间隔。
有很多方法可以编写它,通常基于循环(递归或不循环)。如果要使用for循环,则需要一系列值来迭代。如果使用递归,则可以递增值,直到结束条件满足。您可以在for循环中增加一个值,但它使用变异,在函数式编程中被认为是一种不好的方法。让我告诉你两种方法的方法,并留下一些细节:)
此外,我将为循环运算符选择/ list,因为它可以很好地为我们返回一个列表。
for循环:正如我所说,我们需要迭代的值,所以我们可以使用序列函数来创建值。让我们使用(范围内)函数:
(sequence->list (in-range 0 (* 12 60) 90))
会给你分钟增量:
'(0 90 180 270 360 450 540 630)
完美,我们可以解决这个问题:
(define (schedule n)
(for/list ([val (sequence->list (in-range 0 (* 12 60) n))])
(let ([hour 0] ; <== calculate the hour part here
[minute 0]) ; <== and minute here
(make-daytime hour minute))))
现在,如果你想以递归的方式做同样的事情:
(define (schedule.v2 n)
(define (schedule-aux result current-min)
(cond
[(>= current-min 720) result]
[else
(let ([hour 0] ; <== calculate the hour from current-min
[minute 0] ; <== calculate the min from current-min
[next-min (+ current-min n)])
(schedule-aux
(cons (make-daytime hour minute)
result)
next-min))]))
(schedule-aux null 0))