;; 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-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) (recipes-by-ingredients-rec recipes search-ingredients '()))) (define recipes-by-ingredients-rec (lambda (recipes search-ingredients list) (if (null? recipes) list (let* ((recipe (car recipes)) (ingredients (ingredients recipe)) (contains? (contains-ingredients? recipe search-ingredients)) (new-list (if contains? (cons recipe list) list))) (recipes-by-ingredients-rec (cdr recipes) search-ingredients new-list)))))