This commit is contained in:
2025-10-10 01:06:59 -04:00
parent 49c69a495f
commit 3fb80bd5e0
6 changed files with 39 additions and 173 deletions
+2
View File
@@ -0,0 +1,2 @@
# DrRacket.
*.rkt~
-3
View File
@@ -1,3 +0,0 @@
;; 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-beginner-reader.ss" "lang")((modname main) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f () #f)))
+37 -31
View File
@@ -13,30 +13,28 @@
(make-tree 12 'end 'end)))
(define good-tree (make-tree 50 sapling (make-tree 100 'end 'end)))
(define broke-tree (make-tree 5 good-tree good-tree))
(define deeply-broke-tree (make-tree 5 (make-tree 3 (make-tree 2 sprout sprout) 'end) (make-tree 10 (make-tree 7 'end 'end) 'end)))
(define deeply-broke-tree
(make-tree 10
(make-tree 6 'end (make-tree 11 'end 'end))
(make-tree 12 'end 'end)))
; Tree t -> Bool
; Determines whether a Tree is a binary search tree.
(define (bst? t)
(local [; Tree t -> Bool
; Recursively checks left and right.
(define (recurse t)
(or (and (symbol? t) (symbol=? t 'end))
(and (acc-right (tree-right t) (tree-n t))
(acc-left (tree-left t) (tree-n t)))))
(local [; Convenient form of greater than.
(define (<2 a b c)
(cond [(and (symbol? a) (symbol? c)) #t]
[(symbol? a) (< (- b 1) b c)]
[(symbol? c) (< a b (+ b 1))]
[else (< a b c)]))
; Tree t, Number n -> Bool
; Accumulates the current number to check left.
(define (acc-left t n)
(or (and (symbol? t) (symbol=? t 'end))
(and (< (tree-n t) n) (recurse t))))
; Tree t, Number n -> Bool
; Accumulates the current number to check right.
(define (acc-right t n)
(or (and (symbol? t) (symbol=? t 'end))
(and (> (tree-n t) n) (recurse t))))]
(recurse t)))
; Recursively checks left & right with lower & upper bounds.
(define (recurse t lower upper)
(cond [(symbol? t) (symbol=? t 'end)]
[else (and (<2 lower (tree-n t) upper)
(recurse (tree-left t) lower (tree-n t))
(recurse (tree-right t) (tree-n t) upper))]))]
(recurse t 'quite-little 'very-big)))
(check-expect (bst? sprout) #t)
(check-expect (bst? sapling) #t)
@@ -63,20 +61,27 @@
; String w, Trie t -> Boolean
; Determines whether the given word is in the given Trie.
(define (in-trie? w t)
(local [; [Node] l, String wsf -> Boolean
; Basically ormap of in?h on list of nodes but no lambda so this exists.
(define (childs? l wsf)
(and (not (empty? l))
(or (in?h (first l) wsf) (childs? (rest l) wsf))))
(local [(define ln (string-length w))
; Node n, String wsf -> Boolean
; Helper for in?. Accumulates word so far.
(define (in?h n wsf)
(or (and (string=? (string-append wsf (node-c n)) w) (node-e n)) (childs? (node-l n) (string-append wsf (node-c n)))))
; undernode?: l: [Node], i: [Index] → Bool
; Whether it's in the node's list of nodes.
(define (undernode? l i)
(cond [(empty? l) #f]
[else (or (atnode? (first l) i)
(undernode? (rest l) i))]))
; Node n -> Boolean
; Determines whether word is in the node or child nodes.
(define (in? n) (in?h n ""))] (ormap in? t)))
; atnode?: n: Node, i: Index → Bool
; Check if node has the character at index i in the word, and continue down if it does.
(define (atnode? n i)
(if (>= i ln)
#f
(if (string=? (node-c n) (substring w i (+ i 1)))
(if (= (+ i 1) ln) ; If we've hit the end of the word.
(node-e n)
(undernode? (node-l n) (+ i 1)))
#f)))]
(undernode? t 0)))
(check-expect (in-trie? "cat" example-trie) #t)
(check-expect (in-trie? "ca" example-trie) #f)
@@ -84,6 +89,7 @@
(check-expect (in-trie? "better" example-trie) #t)
(check-expect (in-trie? "bee" example-trie) #t)
(check-expect (in-trie? "beee" example-trie) #f)
(check-expect (in-trie? "" example-trie) #f)
; [String] l -> Trie
; Generates the trie for a list of strings.
-114
View File
@@ -1,114 +0,0 @@
;; 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-reader.ss" "lang")((modname main) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f () #f)))
; A MaybeTree is one of
; - (make-tree [Number MaybeTree MaybeTree])
(define-struct tree [n left right])
; - 'end
(define sprout (make-tree 0 'end 'end))
(define seedling (make-tree 5 sprout (make-tree 6 'end 'end)))
(define sapling (make-tree 10
(make-tree 6 sprout 'end)
(make-tree 12 'end 'end)))
(define good-tree (make-tree 50 sapling (make-tree 100 'end 'end)))
(define broke-tree (make-tree 5 good-tree good-tree))
; Tree t -> Bool
; Determines whether a Tree is a binary search tree.
(define (bst? t)
(local [; Tree t -> Bool
; Recursively checks left and right.
(define (recurse t)
(or (and (symbol? t) (symbol=? t 'end))
(and (acc-right (tree-right t) (tree-n t))
(acc-left (tree-left t) (tree-n t)))))
; Tree t, Number n -> Bool
; Accumulates the current number to check left.
(define (acc-left t n)
(or (and (symbol? t) (symbol=? t 'end))
(and (< (tree-n t) n) (recurse t))))
; Tree t, Number n -> Bool
; Accumulates the current number to check right.
(define (acc-right t n)
(or (and (symbol? t) (symbol=? t 'end))
(and (> (tree-n t) n) (recurse t))))]
(recurse t)))
(check-expect (bst? sprout) #t)
(check-expect (bst? sapling) #t)
(check-expect (bst? good-tree) #t)
(check-expect (bst? broke-tree) #f)
; A Trie is a [Node]
; A Node is a
; (make-node [String c Boolean e [Node] l])
; and represents a prefix tree. 'c' represents the node character, 'e' is a
; flag for if the node marks the end of a word in the tree, and 'l' is the list
; of child nodes.
(define-struct node [c e l])
(define example-trie
(list (make-node "a" #t
(list (make-node "n" #t (list (make-node "d" #t '()) (make-node "t" #t '())))))
(make-node "b" #f
(list (make-node "e" #t (list (make-node "e" #t '()) (make-node "t" #t (list (make-node "t" #f (list (make-node "e" #f (list (make-node "r" #t '())))))))))))
(make-node "c" #f (list (make-node "a" #f (list (make-node "t" #t '())))))))
; String w, Trie t -> Boolean
; Determines whether the given word is in the given Trie.
(define (in-trie? w t)
(local [; [Node] l, String wsf -> Boolean
; Basically ormap of in?h on list of nodes but no lambda so this exists.
(define (childs? l wsf)
(and (not (empty? l))
(or (in?h (first l) wsf) (childs? (rest l) wsf))))
; Node n, String wsf -> Boolean
; Helper for in?. Accumulates word so far.
(define (in?h n wsf)
(or (and (string=? (string-append wsf (node-c n)) w) (node-e n)) (childs? (node-l n) (string-append wsf (node-c n)))))
; Node n -> Boolean
; Determines whether word is in the node or child nodes.
(define (in? n) (in?h n ""))] (ormap in? t)))
(check-expect (in-trie? "cat" example-trie) #t)
(check-expect (in-trie? "ca" example-trie) #f)
(check-expect (in-trie? "catch" example-trie) #f)
(check-expect (in-trie? "better" example-trie) #t)
(check-expect (in-trie? "bee" example-trie) #t)
(check-expect (in-trie? "beee" example-trie) #f)
; [String] l -> Trie
; Generates the trie for a list of strings.
(define (strie l)
(local [; String w, Trie t -> Trie
; Adds word w to a Trie.
(define (triadd w t)
(local [; String c, String wrest, Trie t -> Trie
; Helper function to insert a chacater (and the rest of the word) to the Trie.
(define (insert-char c wrest t)
(cond [(empty? t)
(list (make-node c ; Node character.
(string=? wrest "") ; Mark whether Node's a word end.
(if (string=? wrest "") ; If more left in the word, recurse.
'()
(triadd wrest '()))))]
[(string=? (node-c (first t)) c) ; Character matches -- return existing Trie Node + whatever added if necessary.
(cons (make-node c
(or (node-e (first t))
(string=? wrest ""))
(if (string=? wrest "")
(node-l (first t))
(triadd wrest (node-l (first t))))) ; Recurse.
(rest t))]
[else
(cons (first t) (insert-char c wrest (rest t)))]))]
(insert-char (substring w 0 1) (substring w 1) t)))]
(foldl triadd '() l)))
(check-expect (strie '("and" "bee" "cat" "an" "a" "ant" "better" "bet" "be")) example-trie)
-22
View File
@@ -1,22 +0,0 @@
;; 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: (good?: A → Boolean, l :[A], i: Int, 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? '()) '())
-3
View File
@@ -1,3 +0,0 @@
;; 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-reader.ss" "lang")((modname main) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f () #f)))