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

Reply via email to