在Edx上有个网课叫How to code: Complex Data,在做最后一个课设的时侯。
想了很久都没有想通为什么我的代码没有运行出来正确的结果,而且因为这个
编程软件Dr.Racket自带的Debugger不好用,所以需要大佬帮忙debug一下,代码如下:
; PROBLEM 2:
;
; In UBC's version of How to Code, there are often more than 800 students taking
; the course in any given semester, meaning there are often over 40 Teaching Assistants.
;
; Designing a schedule for them by hand is hard work - luckily we've learned enough now to write
; a program to do it for us!
;
; Below are some data definitions for a simplified version of a TA schedule. There are some
; number of slots that must be filled, each represented by a natural number. Each TA is
; available for some of these slots, and has a maximum number of shifts they can work.
;
; Design a search program that consumes a list of TAs and a list of Slots, and produces one
; valid schedule where each Slot is assigned to a TA, and no TA is working more than their
; maximum shifts. If no such schedules exist, produce false.
;
; You should supplement the given check-expects and remember to follow the recipe!
;; Slot is Natural
;; interp. each TA slot has a number, is the same length, and none overlap
(define-struct ta (name max avail))
;; TA is (make-ta String Natural (listof Slot))
;; interp. the TA's name, number of slots they can work, and slots they're available for
(define SOBA (make-ta "Soba" 2 (list 1 3)))
(define UDON (make-ta "Udon" 1 (list 3 4)))
(define RAMEN (make-ta "Ramen" 1 (list 2)))
(define NOODLE-TAs (list SOBA UDON RAMEN))
(define-struct assignment (ta slot))
;; Assignment is (make-assignment TA Slot)
;; interp. the TA is assigned to work the slot
;; Schedule is (listof Assignment)
;; ============================= FUNCTIONS
;; (listof TA) (listof Slot) -> Schedule or false
;; produce valid schedule given TAs and Slots; false if impossible
(check-expect (schedule-tas empty empty) empty)
(check-expect (schedule-tas empty (list 1 2)) false)
(check-expect (schedule-tas (list SOBA) empty) empty)
(check-expect (schedule-tas (list SOBA) (list 1)) (list (make-assignment SOBA 1)))
(check-expect (schedule-tas (list SOBA) (list 2)) false)
(check-expect (schedule-tas (list SOBA) (list 1 3)) (list (make-assignment SOBA 3)
(make-assignment SOBA 1)))
(check-expect (schedule-tas NOODLE-TAs (list 1 2 3 4))
(list
(make-assignment UDON 4)
(make-assignment SOBA 3)
(make-assignment RAMEN 2)
(make-assignment SOBA 1)))
(check-expect (schedule-tas NOODLE-TAs (list 1 2 3 4 5)) false)
;(define (schedule-tas tas slots) empty) ;stub
(define (schedule-tas tas slots)
(local [(define-struct slot (loc status))
;; slot is (make-slot number false|ta)
;; number is the slot location in list of slot
;; if the status is ta, means the slot is taken care of by that ta
;; if the status is false, means the slot don't have ta
(define-struct shifts (t n))
;; shifts is the ta's current shifts
;; t is ta, n is the current shifts occupied
(define (initialize-slots slots)
(cond [(empty? slots) empty]
[else (cons (make-slot (first slots) false) (initialize-slots (rest slots)))]))
(define (initialize-sh tas)
(cond [(empty? tas) empty]
[else (cons (make-shifts (first tas) 0) (initialize-sh (rest tas)))]))
(define los (initialize-slots slots))
;; los is listof slot
(define losh (initialize-sh tas))
;; losh is listof shifts
;; rsf is lisfof slot; result so far
(define (fn-for-los los losh rsf)
(cond [(empty? los) rsf]
[(shift-avail? (filter-out losh (slot-loc (first los)) empty))
(if (check-status? (first los))
(fn-for-los (rest los) losh (cons (first los) rsf))
(fn-for-los (rest los) (update-shift losh (slot-loc (first los)) empty) (cons (fill-in (first los) losh) rsf)))]
[else
(fn-for-los (rest los) losh (cons (first los) rsf))]))
(define (check-status? s)
(if (false? (slot-status s))
false
true))
(define (filter-out losh loc rsf)
(cond [(empty? losh) rsf]
[else
(if (member loc (ta-avail (shifts-t (first losh))))
(filter-out (rest losh) loc (cons (first losh) rsf))
(filter-out (rest losh) loc rsf))]))
(define (shift-avail? losh)
(cond [(empty? losh) false]
[else
(if (< (shifts-n (first losh)) (ta-max (shifts-t (first losh))))
true
(shift-avail? (rest losh)))]))
(define (update-shift losh loc rsf)
(cond [(empty? losh) rsf]
[else
(if (available? (first losh) loc)
(append (cons (make-shifts (shifts-t (first losh)) (add1 (shifts-n (first losh)))) rsf) (rest losh))
(update-shift (rest losh) loc rsf))]))
(define (available? sh loc)
(if (member loc (ta-avail (shifts-t sh)))
(< (shifts-n sh) (ta-max (shifts-t sh)))
false))
(define (fill-in s losh)
(cond [(empty? losh) (error "something went wrong")]
[else
(if (available? (first losh) (slot-loc s))
(make-slot (slot-loc s) (shifts-t (first losh)))
(fill-in s (rest losh)))]))
(define (full? loas)
(cond [(empty? loas) true]
[else
(if (false? (slot-status (first loas)))
false
(full? (rest loas)))]))
(define (make los)
(cond [(empty? los) empty]
[else
(cons (make-assignment (slot-status (first los)) (slot-loc (first los))) (make (rest los)))]))]
(if (full? (fn-for-los los losh empty))
(make (fn-for-los los losh empty))
false)))