From fe5c57ddd0c8017403369528a2f909e2f679d544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Tue, 16 Sep 2025 07:50:00 -0700 Subject: [PATCH] Add canonical tests to `list-ops` --- exercises/practice/list-ops/.meta/config.json | 1 + exercises/practice/list-ops/.meta/example.rkt | 14 +- exercises/practice/list-ops/list-ops-test.rkt | 148 ++++++++---------- exercises/practice/list-ops/list-ops.rkt | 40 ++--- 4 files changed, 98 insertions(+), 105 deletions(-) diff --git a/exercises/practice/list-ops/.meta/config.json b/exercises/practice/list-ops/.meta/config.json index 2de86d83..ef92143d 100644 --- a/exercises/practice/list-ops/.meta/config.json +++ b/exercises/practice/list-ops/.meta/config.json @@ -3,6 +3,7 @@ "arguello" ], "contributors": [ + "BNAndras", "mbertheau", "PurityControl", "robertpostill", diff --git a/exercises/practice/list-ops/.meta/example.rkt b/exercises/practice/list-ops/.meta/example.rkt index b390515d..6125e16f 100644 --- a/exercises/practice/list-ops/.meta/example.rkt +++ b/exercises/practice/list-ops/.meta/example.rkt @@ -4,7 +4,8 @@ my-reverse my-map my-filter - my-fold + my-foldl + my-foldr my-append my-concatenate) @@ -38,10 +39,15 @@ (go (rest l) acc)))) (go l '())) -(define (my-fold f acc l) +(define (my-foldl f acc l) (if (null? l) acc - (my-fold f (f (first l) acc) (rest l)))) + (my-foldl f (f (first l) acc) (rest l)))) + +(define (my-foldr f acc l) + (if (null? l) + acc + (f (first l) (my-foldr f acc (rest l))))) (define (my-append a b) (define (go l acc) @@ -51,4 +57,4 @@ (go (my-reverse a) b)) (define (my-concatenate ll) - (my-fold my-append '() (my-reverse ll))) + (my-foldl my-append '() (my-reverse ll))) diff --git a/exercises/practice/list-ops/list-ops-test.rkt b/exercises/practice/list-ops/list-ops-test.rkt index dc384077..dd7a8445 100644 --- a/exercises/practice/list-ops/list-ops-test.rkt +++ b/exercises/practice/list-ops/list-ops-test.rkt @@ -6,114 +6,96 @@ (require rackunit rackunit/text-ui)) (module+ test - (define (inc x) (+ 1 x)) - (define suite (test-suite - "list operations tests" - - (test-eqv? "length of empty list" - (my-length '()) - 0) - - (test-eqv? "length of normal list" - (my-length '(1 3 5 7)) - 4) - - (test-eqv? "length of huge list" - (my-length (build-list 1000000 values)) - 1000000) + "list ops tests" - (test-equal? "reverse of empty list" - (my-reverse '()) + (test-equal? "append empty lists" + (my-append '() '()) '()) + + (test-equal? "append list to empty list" + (my-append '() '(1 2 3 4)) + '(1 2 3 4)) + + (test-equal? "append empty list to list" + (my-append '(1 2 3 4) '()) + '(1 2 3 4)) - (test-equal? "reverse of normal list" - (my-reverse '(1 3 5 7)) - '(7 5 3 1)) - - (test-equal? "reverse of huge list" - (my-reverse (build-list 1000000 values)) - (build-list 1000000 (lambda (x) (- 999999 x)))) + (test-equal? "append non-empty lists" + (my-append '(1 2) '(2 3 4 5)) + '(1 2 2 3 4 5)) - (test-equal? "map of empty list" - (my-map inc '()) + (test-equal? "concatenate empty list" + (my-concatenate '()) '()) - (test-equal? "map of normal list" - (my-map inc '(1 2 3 4)) - '(2 3 4 5)) + (test-equal? "concatenate list of lists" + (my-concatenate '((1 2) (3) () (4 5 6))) + '(1 2 3 4 5 6)) - (test-equal? "map of huge list" - (my-map inc (build-list 1000000 values)) - (build-list 1000000 (lambda (x) (+ x 1)))) + (test-equal? "concatenate list of nested lists" + (my-concatenate '(((1) (2)) ((3)) (()) ((4 5 6)))) + '((1) (2) (3) () (4 5 6))) - (test-equal? "filter of empty list" + (test-equal? "filter empty list" (my-filter odd? '()) '()) - (test-equal? "filter of normal list" - (my-filter odd? '(1 2 3 4)) - '(1 3)) + (test-equal? "filter non-empty list" + (my-filter odd? '(1 2 3 5)) + '(1 3 5)) - (test-equal? "filter of huge list" - (my-filter odd? (build-list 1000000 values)) - (filter odd? (build-list 1000000 values))) + (test-equal? "length of empty list" + (my-length '()) + 0) - (test-eqv? "fold of empty list" - (my-fold + 0 '()) - 0) + (test-equal? "length of non-empty list" + (my-length '(1 2 3 4)) + 4) - (test-eqv? "fold of normal list" - (my-fold + -3 '(1 2 3 4)) - 7) + (test-equal? "map empty list" + (my-map add1 '()) + '()) - (test-eqv? "fold of huge list" - (my-fold + 0 (build-list 1000000 values)) - (foldl + 0 (build-list 1000000 values))) + (test-equal? "map non-empty list" + (my-map add1 '(1 3 5 7)) + '(2 4 6 8)))) - (test-eqv? "fold with non-commutative function" - (my-fold (lambda (x acc) (- acc x)) 10 '(1 2 3 4)) - 0) + (test-equal? "foldl empty list" + (my-foldl * 2 '()) + 2) - (test-equal? "append of empty lists" - (my-append '() '()) - '()) + (test-equal? "fold left direction independent function applied to non-empty list" + (my-foldl + 5 '(1 2 3 4)) + 15) - (test-equal? "append of empty and non-empty list" - (my-append '() '(1 2 3 4)) - '(1 2 3 4)) + (test-equal? "fold left direction dependent function applied to non-empty list" + (my-foldl / 24 '(1 2 3 4)) + 64) - (test-equal? "append of non-empty and empty list" - (my-append '(1 2 3 4) '()) - '(1 2 3 4)) + (test-equal? "fold right empty list" + (my-foldr * 2 '()) + 2) - (test-equal? "append of non-empty lists" - (my-append '(1 2 3) '(4 5)) - '(1 2 3 4 5)) + (test-equal? "fold right direction independent function applied to non-empty list" + (my-foldr + 5 '(1 2 3 4)) + 15) - (test-equal? "append of huge lists" - (my-append (build-list 1000000 values) - (build-list 1000000 (lambda (x) (+ x 1000000)))) - (build-list 2000000 values)) + (test-equal? "fold right direction dependent function applied to non-empty list" + (my-foldr / 24 '(1 2 3 4)) + 9) - (test-equal? "concatenate of empty list of lists" - (my-concatenate '()) + (test-equal? "reverse empty list" + (my-reverse '()) '()) - (test-equal? "concatenate of normal list of lists" - (my-concatenate '((1 2) (3) () (4 5 6))) - '(1 2 3 4 5 6)) - - (test-equal? "concatenate of huge list of small lists" - (my-concatenate (build-list 1000000 list)) - (build-list 1000000 values)) + (test-equal? "reverse non-empty list" + (my-reverse '(1 3 5 7)) + '(7 5 3 1)) - (test-equal? "concatenate of small list of huge lists" - (my-concatenate - (build-list 10 (lambda (i) - (build-list 100000 (lambda (j) - (+ (* 100000 i) j)))))) - (build-list 1000000 values)))) + (test-equal? "reverse list of lists is not flattened" + (my-reverse '((1 2) (3) () (4 5 6))) + '((4 5 6) () (3) (1 2))) - (run-tests suite)) +(run-tests suite)) diff --git a/exercises/practice/list-ops/list-ops.rkt b/exercises/practice/list-ops/list-ops.rkt index d8d1ded5..dac8c8e3 100644 --- a/exercises/practice/list-ops/list-ops.rkt +++ b/exercises/practice/list-ops/list-ops.rkt @@ -1,30 +1,34 @@ #lang racket -(provide my-length - my-reverse - my-map +(provide my-append + my-concatenate my-filter - my-fold - my-append - my-concatenate) + my-length + my-map + my-foldl + my-foldr + my-reverse) + +(define (my-append sequence1 sequence2) + (error "Please implement 'my-append'")) + +(define (my-concatenate sequence-of-sequences) + (error "Please implement 'my-concatenate'")) + +(define (my-filter operation? sequence) + (error "Please implement 'my-filter'")) (define (my-length sequence) (error "Please implement 'my-length'")) -(define (my-reverse sequence) - (error "Please implement 'my-reverse'")) - (define (my-map operation sequence) (error "Please implement 'my-map'")) -(define (my-filter operation? sequence) - (error "Please implement 'my-filter'")) +(define (my-foldl operation accumulator sequence) + (error "Please implement 'my-foldl'")) -(define (my-fold operation accumulator sequence) - (error "Please implement 'my-fold'")) +(define (my-foldr operation accumulator sequence) + (error "Please implement 'my-foldr'")) -(define (my-append sequence1 sequence2) - (error "Please implement 'my-append'")) - -(define (my-concatenate sequence-of-sequences) - (error "Please implement 'my-concatenate'")) +(define (my-reverse sequence) + (error "Please implement 'my-reverse'"))