;; The first three lines of this file were inserted by DrRacket. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname main) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f () #f))) ; foo: bar: (A → A) → (A → A) (define (foo bar) (local [(define (baz buzz) (bar (bar buzz)))] baz)) (check-expect ((foo add1) 1) 3) ; goodies: good?: (A → Boolean), l: [A] → [Index] ; Returns a list of indices considered "good." (define (goodies good? l) (local [; goodies/help: l: [A], i: Index, a: [Index] → [Index] (define (goodies/help l i a) (cond [(empty? l) (reverse a)] [(good? (first l)) (goodies/help (rest l) (add1 i) (cons i a))] [else (goodies/help (rest l) (add1 i) a)]))] (goodies/help l 0 '()))) (check-expect (goodies even? '(1 2 3 4 5)) '(1 3)) (check-expect (goodies even? '()) '()) ; groupby: key: (A → B), l: [A], same? (B, B → Boolean) → [[A]] ; This isn't tail-recursive, so it takes up more memory than strictly necessary, but it doesn't need to reverse the list so probably faster. (define (groupby key l same?) (if (empty? l) '() (local [(define key1same? (λ (x) (same? (key x) (key (first l)))))] (cons (filter key1same? l) (groupby key (filter (λ (x) (not (key1same? x))) l) same?))))) (check-expect (groupby even? '(1 2 3 4 5) equal?) '((1 3 5) (2 4))) (check-expect (groupby (lambda (x) (modulo x 3)) '(1 2 1 2 54 2 5 43 7 2 643 1 2 0) equal?) '((1 1 43 7 643 1) (2 2 2 5 2 2) (54 0))) ; cart: [[A]] → [[A]] ; Takes a list of n lists, and computes the n-ary cartesian product. (define (cart ll) (foldr (λ (l acc) (foldr append ; Concat all lists. '() (map (λ (x) (map (λ (m) (cons x m)) acc)) l))) ; Create list of lists for each x. '(()) ; Base case. ll)) (check-expect (cart '((1 2 3) (a b c))) '((1 a) (1 b) (1 c) (2 a) (2 b) (2 c) (3 a) (3 b) (3 c))) (check-expect (cart '((4 5 6) (d e f) (#t #f))) '((4 d #t) (4 d #f) (4 e #t) (4 e #f) (4 f #t) (4 f #f) (5 d #t) (5 d #f) (5 e #t) (5 e #f) (5 f #t) (5 f #f) (6 d #t) (6 d #f) (6 e #t) (6 e #f) (6 f #t) (6 f #f)))