On May 30, 2011, at 9:11 PM, Richard Cleis wrote:
> An HtDP solution would more likely describe the data first (days are less
> than 366, equal to 366, or greater than 366). One cond would handle all
> three, two would terminate, and the the last would continue the accumulation.
I had actually written the program in HtDP style, and yes, the accumulator made
it clear that the if was wrong:
;; N -> [List N N N]
(define (my-date days)
;; N N -> N
;; accu: y is the number of complete years between days and d, plus 1980
;; gen. recursion (subtract number of days until the number is w/i a year)
(define (year d y)
(cond
[(<= d 365) (values y d)]
[else (if (leap-year? y)
(cond
[(> d 366) (year (- d 366) (+ y 1))]
[(= d 366) (values y d)])
(year (- d 365) (+ y 1)))]))
(define-values (the-year remaining-days-in-year) (year days 1980))
;; N N -> N
;; accu: m is the months between remaining-days-in-year and d, starting in Jan
;; gen. recursion (subtract number of days until w/i a month)
(define (month d m)
(cond
[(<= d (month->days m the-year)) (values m d)]
[else (month (- d (month->days m the-year)) (+ m 1))]))
(define-values (the-month remaining-days-in-month) (month
remaining-days-in-year 1))
;; -- IN --
(list the-year the-month remaining-days-in-month))
;; N -> Boolean
;; simplistic definition
(define (leap-year? y)
(= (remainder y 4) 0))
;; N N -> N
;; the number of days in month m for year y
(define (month->days m y)
(case m
[(1 3 5 7 8 10 12) 31]
[( 4 6 9 11) 30]
[else (if (leap-year? y) 29 28)]))
;; -- testing ---
(check-equal? (my-date 364) '(1980 12 29))
(check-equal? (my-date 366) '(1980 12 31))
(check-equal? (my-date (+ 365 366)) '(1981 12 31))
(check-equal? (my-date (+ 365 365 365 366)) '(1983 12 31))
(define long
(let ([years# (- 2009 1980)])
(apply + (build-list years# (lambda (i) (define y (+ i 1980)) (if
(leap-year? y) `366 365))))))
(check-equal? (my-date long) '(2008 12 31))
> In other words, the possibility of that hard-to-read bug doesn't exist.
There are bugs in FP programs for sure, but the [while-]loop exit bugs
disappear.
_________________________________________________
For list-related administrative tasks:
http://lists.racket-lang.org/listinfo/users