Added Typed Racket.
WTF this language actually sucks.
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
;; 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))
|
||||
(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)))
|
||||
|
||||
; 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)
|
||||
(check-expect (bst? deeply-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)
|
||||
@@ -0,0 +1,66 @@
|
||||
;; 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)))
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
;; 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? '()) '())
|
||||
@@ -0,0 +1,44 @@
|
||||
#lang pl
|
||||
|
||||
; I'm keeping my own type declarations bc the racket ones are literally unreadable.
|
||||
; gcd2: a: Int, b: Int → Int
|
||||
(: gcd2 : (Integer Integer -> Integer))
|
||||
; Given two non-negative integers, determine their greatest common divisor.
|
||||
(define (gcd2 a b)
|
||||
(cond
|
||||
[(or (negative? a) (negative? b)) (error 'neg "Given negative number.")]
|
||||
[(= a 0) b]
|
||||
[(= b 0) a]
|
||||
[(and (even? a) (even? b)) (* 2 (gcd2 (floor (/ a 2)) (floor (/ b 2))))]
|
||||
[(even? b) (gcd2 a (floor (/ b 2)))]
|
||||
[(even? a) (gcd2 (floor (/ a 2)) b)]
|
||||
[else
|
||||
(if (<= a b)
|
||||
(gcd2 a (- b a))
|
||||
(gcd2 b (- a b)))]))
|
||||
|
||||
(test (gcd2 0 0) => 0)
|
||||
(test (gcd2 288 64) => 32)
|
||||
; What's the point of the symbol in the error definition if it isn't used to check errors?
|
||||
(test (gcd2 2 -1) =error> "Given negative number.")
|
||||
|
||||
; out-of-bounds?: start: Number,
|
||||
; lower: Number,
|
||||
; upper: Number,
|
||||
; l: [Number] → Bool
|
||||
(: out-of-bounds? : (Number Number Number (Listof Number) -> Boolean))
|
||||
; Determines if an object that begins at the starting location and then moves delta by delta ever ever steps outside of the bounds (inclusive).
|
||||
(define (out-of-bounds? start lower upper l)
|
||||
(if (or (< start lower) (> start upper))
|
||||
#t
|
||||
(match l
|
||||
['() #f]
|
||||
[(cons frst rst) (out-of-bounds? frst lower upper rst)])))
|
||||
|
||||
(test (out-of-bounds? 0 -1 2 '(0 -2 3 -4 6)) => #t)
|
||||
(test (out-of-bounds? 0 -1 1 '(1)) => #f)
|
||||
(test (out-of-bounds? 0 -1 1 '()) => #f)
|
||||
(test (out-of-bounds? 0 1 2 '()) => #t)
|
||||
(test (out-of-bounds? 0 0 0 '()) => #f)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user