;; Predicates (define title (lambda (recipe) (car recipe))) (define ingredients (lambda (recipe) (car (cdr recipe)))) (define steps (lambda (recipe) (car (cdr (cdr recipe))))) (define ingredient-name (lambda (ingredient) (if (= (length ingredient) 2) (car (cdr ingredient)) (car (cddr ingredient))))) (define ingredient-amount (lambda (ingredient) (car ingredient))) (define ingredient-unit (lambda (ingredient) (if (= (length ingredient) 2) "" (car (cdr ingredient))))) ;; (define ingredient-ref (lambda (ingredients n) (if (= n 0) (car ingredients) (ingredient-ref (cdr ingredients) (- n 1))))) (define ingredient-by-name (lambda (ingredients search-name) (let ((ingredient (car ingredients))) (cond [(equal? (ingredient-name ingredient) search-name) ingredient] [(null? (cdr ingredients)) #f] [else (ingredient-by-name (cdr ingredients) search-name)])))) (define contains-ingredient? (lambda (recipe search-ingredient) (contains-ingredients? recipe (cons search-ingredient '())))) (define contains-ingredients? (lambda (recipe search-ingredients) (let ((ingredients (ingredients recipe))) (cond [(null? search-ingredients) #t] [(ingredient-by-name ingredients (car search-ingredients)) (contains-ingredients? recipe (cdr search-ingredients))] [else #f]) ))) (define recipes-by-ingredients (lambda (recipes search-ingredients) (filter (lambda (x) (contains-ingredients? x search-ingredients)) recipes))) (define recipe-by-name (lambda (recipes name) (if (null? recipes) #f (let ((recipe (car recipes))) (if (equal? (title recipe) name) recipe (recipe-by-name (cdr recipes) name))))))