Merge pull request #262 from mkfifo/heapsort

Issue #252 Heapsort
This commit is contained in:
Erik Svedäng 2018-06-26 10:11:38 +02:00 committed by GitHub
commit b4225d41a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 677 additions and 41 deletions

View File

@ -137,10 +137,6 @@
(set! e (+ e step))))
x))
(doc sort "Sort an array (the elements must support cmp).")
(defn sort [a]
(sort-with a cmp))
(doc repeat "Repeat function f n times and store the results in an array.")
(defn repeat [n f]
(let-do [a (allocate n)]

View File

@ -2,6 +2,8 @@
(defmodule Char
(register = (Fn [Char Char] Bool))
(register < (Fn [Char Char] Bool))
(register > (Fn [Char Char] Bool))
(register to-int (Fn [Char] Int))
(register from-int (Fn [Int] Char))
(register copy (Fn [&Char] Char))
@ -27,7 +29,14 @@
(defmodule CharRef
(defn = [a b]
(Char.= @a @b)))
(Char.= @a @b))
(defn /= [a b]
(Char./= @a @b))
(defn < [a b]
(Char.< @a @b))
(defn > [a b]
(Char.> @a @b))
)
(defmodule PtrChar
(register str (Fn [(Ptr Char)] String)))

View File

@ -18,3 +18,5 @@
(load "Format.carp")
(load "Random.carp")
(load "Map.carp")
(load "Heap.carp")
(load "Sort.carp")

178
core/Heap.carp Normal file
View File

@ -0,0 +1,178 @@
; Abstract heap with user-supplied ordering function
; an ordering function is a binary relation
; `<` will create a MinHeap, `>` will create a MaxHeap
;
; for any two items `a` and `b`,
; `a` will be higher in the Heap then `b` if `(ord a b)`
(defmodule Heap
(hidden lchild)
(defn lchild [i]
(+ 1 (* 2 i)))
(hidden rchild)
(defn rchild [i]
(+ 2 (* 2 i)))
(hidden parent)
(defn parent [i]
(/ i 2))
(hidden max-of-three-until)
(doc max-of-three-until! "Get the index for the largest (by ord) of an element and its two children.")
(defn max-of-three-until! [heap i len ord]
(let-do [lchild-i (lchild i)
rchild-i (rchild i)]
(when (and (< lchild-i len) (ord (Array.nth heap lchild-i) (Array.nth heap i)))
(set! i lchild-i))
(when (and (< rchild-i len) (ord (Array.nth heap rchild-i) (Array.nth heap i)))
(set! i rchild-i))
i))
; push-down-until!, push-down!, and push-up! are intended for use only by
; those performing internal mutation to the heap who want to restore order.
(defn push-down-until! [heap i len ord]
(while true
(let [challenger (max-of-three-until! heap i len ord)]
(if (= challenger i)
(break)
(do
(Array.swap! heap i challenger)
(set! i challenger))))))
(defn push-down! [heap i ord]
(push-down-until! heap i (Array.length heap) ord))
(defn push-up! [heap i ord]
(while (/= i 0)
(let [elem (Array.nth heap i)
parent-i (Heap.parent i)
parent-elem (Array.nth heap parent-i)]
(if (not (ord elem parent-elem))
(break)
(do (Array.swap! heap i parent-i)
(set! i parent-i))))))
(doc peek "Returns first item on heap.")
(defn peek [heap]
(Array.first heap))
(doc heapify! "Convert array to a heap in place")
(defn heapify! [arr ord]
(let [len (Array.length arr)]
(for [i 1 len]
(push-up! arr i ord))))
(doc push! "Insert a new item onto the heap.")
(defn push! [heap item ord]
(do
(Array.push-back! heap item)
(push-up! heap (- (Array.length heap) 1) ord)))
(doc pop! "Remove and return the first item in the heap.")
(defn pop! [heap ord]
(do
; swap 0 with tail
(Array.swap! heap 0 (- (Array.length heap) 1))
; restore heap excluding tail
(push-down-until! heap 0 (- (Array.length heap) 1) ord)
; pop off tail, returning it
(Array.pop-back! heap)))
)
(defmodule MinHeap
(hidden ord)
(defn ord [a b]
(< a b))
(defn push-down! [heap i]
(Heap.push-down! heap i ord))
(defn push-down-until! [heap i len]
(Heap.push-down-until! heap i len ord))
(defn push-up! [heap i]
(Heap.push-up! heap i ord))
(doc peek "Returns minimum item on min-heap.")
(defn peek [heap]
(Array.first heap))
(doc heapify! "Convert array to a min-heap in place")
(defn heapify! [arr]
(Heap.heapify! arr ord))
(doc push! "Insert a new element onto the min-heap.")
(defn push! [heap item]
(Heap.push! heap item ord))
(doc pop! "Remove and return the first item in the min-heap.")
(defn pop! [heap]
(Heap.pop! heap ord))
)
(defmodule MaxHeap
(hidden ord)
(defn ord [a b]
(> a b))
(defn push-down! [heap i]
(Heap.push-down! heap i ord))
(defn push-down-until! [heap i len]
(Heap.push-down-until! heap i len ord))
(defn push-up! [heap i]
(Heap.push-up! heap i ord))
(doc peek "Returns maximum first item on max-heap.")
(defn peek [heap]
(Array.first heap))
(doc heapify! "Convert array to a max-heap in place")
(defn heapify! [arr]
(Heap.heapify! arr ord))
(doc push! "Insert a new element onto the max-heap.")
(defn push! [heap item]
(Heap.push! heap item ord))
(doc pop! "Remove and return the first item in the max-heap.")
(defn pop! [heap]
(Heap.pop! heap ord))
)
(defmodule HeapSort
(doc sort! "Perform an in-place heapsort of a given array.")
(defn sort! [arr]
(do
(MaxHeap.heapify! arr)
; now we walk through the array, at all times 0..tail is a max heap
; and tail..len is the sorted output
; we slowly grow the tail while shrinking the head
; once tail == 0, then we have finished sorting
(let [tail (- (Array.length arr) 1)]
(while (> tail 0)
(do
; swap values of [0] and [tail]
; this makes our heap temporarily invalid
(Array.swap! arr 0 tail)
; keep pushing down 0 until heap property is satisfied
(MaxHeap.push-down-until! arr 0 tail)
; grow our tail, shrinking our head
(set! tail (- tail 1)))))))
(doc sorted "Perform a heapsort in a new copy of given array.")
(defn sorted [arr]
(let-do [narr (Array.copy arr)]
(sort! &narr)
narr))
(doc sort "Perform an in-place heapsort of a given owned array.")
(defn sort [arr]
(do
(sort! &arr)
arr))
)

13
core/Sort.carp Normal file
View File

@ -0,0 +1,13 @@
(defmodule Array
(doc sort! "Perform an in-place heapsort of a given array.")
(defn sort! [arr]
(HeapSort.sort! arr))
(doc sorted "Perform a heapsort in a new copy of given array.")
(defn sorted [arr]
(HeapSort.sorted arr))
(doc sort "Perform an in-place heapsort of a given owned array.")
(defn sort [arr]
(HeapSort.sort arr))
)

View File

@ -1,5 +1,6 @@
(use Int)
(use Double)
(use Array)
(defmodule Statistics
(deftype Summary [
@ -49,7 +50,7 @@
(doc median "Compute the median of the samples data.")
(defn median [data]
(let [n (Array.length data)
sorted (Array.sort @data)]
sorted (Array.sorted data)]
(cond (= n 0) 0.0
(= (mod n 2) 1) @(Array.nth data (/ n 2))
(let [mid (/ n 2)] ; else
@ -60,7 +61,7 @@
(doc low-median "Compute the low median of the samples data.")
(defn low-median [data]
(let [n (Array.length data)
sorted (Array.sort @data)]
sorted (Array.sorted data)]
(cond (= n 0) 0.0
(= (mod n 2) 1) @(Array.nth data (/ n 2))
@(Array.nth data (dec (/ n 2)))))) ; else
@ -68,7 +69,7 @@
(doc high-median "Compute the high median of the samples data.")
(defn high-median [data]
(let [n (Array.length data)
sorted (Array.sort @data)]
sorted (Array.sorted data)]
(if (= n 0)
0.0
@(Array.nth data (/ n 2)))))
@ -76,7 +77,7 @@
(doc grouped-median "Compute the grouped median of the samples data.")
(defn grouped-median [data interval]
(let [n (Array.length data)
sorted (Array.sort @data)]
sorted (Array.sorted data)]
(cond (= n 0) 0.0
(= n 1) @(Array.nth data 0)
(let [x @(Array.nth data (/ n 2)) ; else
@ -144,7 +145,7 @@
(doc quartiles "Compute the quartiles of the samples data.")
(defn quartiles [data]
(let [tmp (Array.sort @data)
(let [tmp (Array.sorted data)
first 25.0
second 50.0
third 75.0
@ -160,7 +161,7 @@
(hidden winsorize)
(defn winsorize [samples pct]
(let [tmp &(Array.sort @samples)
(let [tmp &(Array.sorted samples)
lo (Statistics.percentile-of-sorted tmp pct)
hi (Statistics.percentile-of-sorted tmp (Double.- 100.0 pct))]
(do

View File

@ -3,6 +3,8 @@
(defmodule String
(register = (Fn [&String &String] Bool))
(register > (Fn [&String &String] Bool))
(register < (Fn [&String &String] Bool))
(register append (Fn [&String &String] String))
(register delete (Fn [String] ()))
(register copy (Fn [&String] String))
@ -156,6 +158,12 @@
(defn /= [a b]
(String./= &a &b))
(defn < [a b]
(String.< &a &b))
(defn > [a b]
(String.> &a &b))
)
(defmodule Bool

View File

@ -4,6 +4,14 @@ bool Char__EQ_(char a, char b) {
return a == b;
}
bool Char__LT_(char a, char b) {
return a < b;
}
bool Char__GT_(char a, char b) {
return a > b;
}
int Char_to_MINUS_int(char c) {
return (int)c;
}

View File

@ -88,6 +88,14 @@ bool String__EQ_(String *a, String *b) {
return strcmp(*a, *b) == 0;
}
bool String__GT_(String *a, String *b) {
return strcmp(*a, *b) > 0;
}
bool String__LT_(String *a, String *b) {
return strcmp(*a, *b) < 0;
}
String String_append(String *a, String *b) {
int la = strlen(*a);
int lb = strlen(*b);

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<html><head><meta charset="UTF-8"><meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"><link href="carp_style.css" rel="stylesheet"></head><body><div class="content"><div class="logo"><a href="http://github.com/carp-lang/Carp"><img src="logo.png"></a><div class="title">core</div><div class="index"><ul><li><a href="Dynamic.html">Dynamic</a></li><li><a href="Int.html">Int</a></li><li><a href="Long.html">Long</a></li><li><a href="Bool.html">Bool</a></li><li><a href="Float.html">Float</a></li><li><a href="Double.html">Double</a></li><li><a href="Vector2.html">Vector2</a></li><li><a href="V2.html">V2</a></li><li><a href="Vector3.html">Vector3</a></li><li><a href="V3.html">V3</a></li><li><a href="VectorN.html">VectorN</a></li><li><a href="VN.html">VN</a></li><li><a href="Geometry.html">Geometry</a></li><li><a href="Statistics.html">Statistics</a></li><li><a href="String.html">String</a></li><li><a href="Char.html">Char</a></li><li><a href="Pattern.html">Pattern</a></li><li><a href="Array.html">Array</a></li><li><a href="IO.html">IO</a></li><li><a href="System.html">System</a></li><li><a href="Debug.html">Debug</a></li><li><a href="Test.html">Test</a></li><li><a href="Bench.html">Bench</a></li><li><a href="Map.html">Map</a></li></ul></div></div><h1>Char</h1><div class="binder"><a href="#/=" class="anchor"><h3 id="/=">/=</h3></a><div class="description">defn</div><p class="sig">(λ [Char, Char] Bool)</p><p class="doc"></p></div><div class="binder"><a href="#=" class="anchor"><h3 id="=">=</h3></a><div class="description">external</div><p class="sig">(λ [Char, Char] Bool)</p><p class="doc"></p></div><div class="binder"><a href="#copy" class="anchor"><h3 id="copy">copy</h3></a><div class="description">external</div><p class="sig">(λ [&amp;Char] Char)</p><p class="doc"></p></div><div class="binder"><a href="#format" class="anchor"><h3 id="format">format</h3></a><div class="description">external</div><p class="sig">(λ [&amp;String, Char] String)</p><p class="doc"></p></div><div class="binder"><a href="#from-int" class="anchor"><h3 id="from-int">from-int</h3></a><div class="description">external</div><p class="sig">(λ [Int] Char)</p><p class="doc"></p></div><div class="binder"><a href="#hash" class="anchor"><h3 id="hash">hash</h3></a><div class="description">defn</div><p class="sig">(λ [&amp;Char] Int)</p><p class="doc"></p></div><div class="binder"><a href="#meaning" class="anchor"><h3 id="meaning">meaning</h3></a><div class="description">defn</div><p class="sig">(λ [&amp;Char] Int)</p><p class="doc">Convert a numerical char into the appropriate number.</p></div><div class="binder"><a href="#prn" class="anchor"><h3 id="prn">prn</h3></a><div class="description">external</div><p class="sig">(λ [Char] String)</p><p class="doc"></p></div><div class="binder"><a href="#random" class="anchor"><h3 id="random">random</h3></a><div class="description">defn</div><p class="sig">(λ [] Char)</p><p class="doc"></p></div><div class="binder"><a href="#random-between" class="anchor"><h3 id="random-between">random-between</h3></a><div class="description">defn</div><p class="sig">(λ [Char, Char] Char)</p><p class="doc"></p></div><div class="binder"><a href="#str" class="anchor"><h3 id="str">str</h3></a><div class="description">external</div><p class="sig">(λ [Char] String)</p><p class="doc"></p></div><div class="binder"><a href="#to-int" class="anchor"><h3 id="to-int">to-int</h3></a><div class="description">external</div><p class="sig">(λ [Char] Int)</p><p class="doc"></p></div></div></body></html>
<html><head><meta charset="UTF-8"><meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"><link href="carp_style.css" rel="stylesheet"></head><body><div class="content"><div class="logo"><a href="http://github.com/carp-lang/Carp"><img src="logo.png"></a><div class="title">core</div><div class="index"><ul><li><a href="Dynamic.html">Dynamic</a></li><li><a href="Int.html">Int</a></li><li><a href="Long.html">Long</a></li><li><a href="Bool.html">Bool</a></li><li><a href="Float.html">Float</a></li><li><a href="Double.html">Double</a></li><li><a href="Vector2.html">Vector2</a></li><li><a href="V2.html">V2</a></li><li><a href="Vector3.html">Vector3</a></li><li><a href="V3.html">V3</a></li><li><a href="VectorN.html">VectorN</a></li><li><a href="VN.html">VN</a></li><li><a href="Geometry.html">Geometry</a></li><li><a href="Statistics.html">Statistics</a></li><li><a href="String.html">String</a></li><li><a href="Char.html">Char</a></li><li><a href="Pattern.html">Pattern</a></li><li><a href="Array.html">Array</a></li><li><a href="IO.html">IO</a></li><li><a href="System.html">System</a></li><li><a href="Debug.html">Debug</a></li><li><a href="Test.html">Test</a></li><li><a href="Bench.html">Bench</a></li><li><a href="Map.html">Map</a></li></ul></div></div><h1>Char</h1><div class="binder"><a href="#/=" class="anchor"><h3 id="/=">/=</h3></a><div class="description">defn</div><p class="sig">(λ [Char, Char] Bool)</p><p class="doc"></p></div><div class="binder"><a href="#&lt;" class="anchor"><h3 id="&lt;">&lt;</h3></a><div class="description">external</div><p class="sig">(λ [Char, Char] Bool)</p><p class="doc"></p></div><div class="binder"><a href="#=" class="anchor"><h3 id="=">=</h3></a><div class="description">external</div><p class="sig">(λ [Char, Char] Bool)</p><p class="doc"></p></div><div class="binder"><a href="#&gt;" class="anchor"><h3 id="&gt;">&gt;</h3></a><div class="description">external</div><p class="sig">(λ [Char, Char] Bool)</p><p class="doc"></p></div><div class="binder"><a href="#copy" class="anchor"><h3 id="copy">copy</h3></a><div class="description">external</div><p class="sig">(λ [&amp;Char] Char)</p><p class="doc"></p></div><div class="binder"><a href="#format" class="anchor"><h3 id="format">format</h3></a><div class="description">external</div><p class="sig">(λ [&amp;String, Char] String)</p><p class="doc"></p></div><div class="binder"><a href="#from-int" class="anchor"><h3 id="from-int">from-int</h3></a><div class="description">external</div><p class="sig">(λ [Int] Char)</p><p class="doc"></p></div><div class="binder"><a href="#hash" class="anchor"><h3 id="hash">hash</h3></a><div class="description">defn</div><p class="sig">(λ [&amp;Char] Int)</p><p class="doc"></p></div><div class="binder"><a href="#meaning" class="anchor"><h3 id="meaning">meaning</h3></a><div class="description">defn</div><p class="sig">(λ [&amp;Char] Int)</p><p class="doc">Convert a numerical char into the appropriate number.</p></div><div class="binder"><a href="#prn" class="anchor"><h3 id="prn">prn</h3></a><div class="description">external</div><p class="sig">(λ [Char] String)</p><p class="doc"></p></div><div class="binder"><a href="#random" class="anchor"><h3 id="random">random</h3></a><div class="description">defn</div><p class="sig">(λ [] Char)</p><p class="doc"></p></div><div class="binder"><a href="#random-between" class="anchor"><h3 id="random-between">random-between</h3></a><div class="description">defn</div><p class="sig">(λ [Char, Char] Char)</p><p class="doc"></p></div><div class="binder"><a href="#str" class="anchor"><h3 id="str">str</h3></a><div class="description">external</div><p class="sig">(λ [Char] String)</p><p class="doc"></p></div><div class="binder"><a href="#to-int" class="anchor"><h3 id="to-int">to-int</h3></a><div class="description">external</div><p class="sig">(λ [Char] Int)</p><p class="doc"></p></div></div></body></html>

File diff suppressed because one or more lines are too long

View File

@ -13,7 +13,7 @@
(Int.< @(Age.x a) @(Age.x b))))
(defn main []
(let-do [ints (sort [10 3 75 40])
ages (sort [(Age.init 10) (Age.init 3) (Age.init 75) (Age.init 40)])]
(let-do [ints (Array.sort [10 3 75 40])
ages (Array.sort [(Age.init 10) (Age.init 3) (Age.init 75) (Age.init 40)])]
(IO.println &(Array.str &ints))
(IO.println &(Array.str &ages))))

View File

@ -93,6 +93,26 @@ templatePushBack =
])
(\(FuncTy [arrayType, _] _) -> [])
templatePushBackBang :: (String, Binder)
templatePushBackBang =
let aTy = RefTy (StructTy "Array" [VarTy "a"])
valTy = VarTy "a"
in defineTemplate
(SymPath ["Array"] "push-back!")
(FuncTy [aTy, valTy] UnitTy)
(toTemplate "void $NAME(Array *aRef, $a value)")
(toTemplate $ unlines
["$DECL { "
," aRef->len++;"
," if(aRef->len > aRef->capacity) {"
," aRef->capacity = aRef->len * 2;"
," aRef->data = realloc(aRef->data, sizeof($a) * aRef->capacity);"
," }"
," (($a*)aRef->data)[aRef->len - 1] = value;"
,"}"
])
(\(FuncTy [arrayType, _] _) -> [])
templatePopBack :: (String, Binder)
templatePopBack = defineTypeParameterizedTemplate templateCreator path t
where path = SymPath ["Array"] "pop-back"
@ -128,6 +148,28 @@ templatePopBack = defineTypeParameterizedTemplate templateCreator path t
depsForCopyFunc typeEnv env insideTy
)
templatePopBackBang :: (String, Binder)
templatePopBackBang =
let aTy = RefTy (StructTy "Array" [VarTy "a"])
valTy = VarTy "a"
in defineTemplate
(SymPath ["Array"] "pop-back!")
(FuncTy [aTy] (VarTy "a"))
(toTemplate "$a $NAME(Array *aRef)")
(toTemplate $ unlines
["$DECL { "
," $a ret;"
," #ifndef OPTIMIZE"
," assert(aRef->len > 0);"
," #endif"
," ret = (($a*)aRef->data)[aRef->len - 1];"
," aRef->len--;"
," return ret;"
,"}"
])
(\(FuncTy [arrayType] _) -> [])
templateNth :: (String, Binder)
templateNth =
let t = VarTy "t"
@ -146,24 +188,6 @@ templateNth =
(\(FuncTy [(RefTy arrayType), _] _) ->
[])
templateSort :: (String, Binder)
templateSort = defineTypeParameterizedTemplate templateCreator path t
where path = (SymPath ["Array"] "sort-with")
vt = VarTy "t"
t = (FuncTy [StructTy "Array" [vt], FuncTy [RefTy vt, RefTy vt] IntTy] (StructTy "Array" [vt]))
templateCreator = TemplateCreator $
\typeEnv env ->
Template
t
(const (toTemplate "Array $NAME (Array a, $(Fn [(Ref t), (Ref t)] Int) f)"))
(const (toTemplate $ unlines ["$DECL {"
," qsort(a.data, a.len, sizeof($t), (int(*)(const void*, const void*))f);"
," return a;"
,"}"]))
(\(FuncTy [arrayType, sortType] _) ->
defineFunctionTypeAlias sortType :
depsForDeleteFunc typeEnv env arrayType)
templateRaw :: (String, Binder)
templateRaw = defineTemplate
(SymPath ["Array"] "raw")

View File

@ -29,11 +29,12 @@ arrayModule = Env { envBindings = bindings, envParent = Nothing, envModuleName =
, templateAsetUninitializedBang
, templateLength
, templatePushBack
, templatePushBackBang
, templatePopBack
, templatePopBackBang
, templateDeleteArray
, templateCopyArray
, templateStrArray
, templateSort
]
-- | The Pointer module contains functions for dealing with pointers.

View File

@ -101,10 +101,6 @@
&[10 8 6 4 2]
&(range 10 1 -2)
"range backwards works as expected if we dont exactly hit")
(assert-equal test
&[1 2 3 4 5 6 7 8 9]
&(sort (range 9 1 -1))
"sort works as expected")
(assert-equal test
&[@"Hi!" @"Hi!" @"Hi!" @"Hi!" @"Hi!"]
&(copy-map excl-ref &b)
@ -133,4 +129,63 @@
"[(Pair 0 @\"a\") (Pair 1 @\"b\") (Pair 2 @\"c\")]"
&(str &(Array.enumerated &[@"a" @"b" @"c"]))
"enumerated works as expected")
(let-do [arr [1 2 3 4 5 6]
exp [1 2 3 4 5 6 7]
new (Array.push-back arr 7)]
(assert-equal test
&exp
&new
"Array.push-back works as expected"))
(let-do [arr [1 2 3]
exp [1 2 3 4 5 6 7 8 9 10 11 12 13 14]]
(Array.push-back! &arr 4)
(Array.push-back! &arr 5)
(Array.push-back! &arr 6)
(Array.push-back! &arr 7)
(Array.push-back! &arr 8)
(Array.push-back! &arr 9)
(Array.push-back! &arr 10)
(Array.push-back! &arr 11)
(Array.push-back! &arr 12)
(Array.push-back! &arr 13)
(Array.push-back! &arr 14)
(assert-equal test
&exp
&arr
"Array.push-back! works as expected"))
(let-do [a [1 2 3 4 5 6]
b (Array.pop-back a)
c (Array.pop-back b)
d (Array.pop-back c)
exp [1 2 3]]
(assert-equal test
&exp
&d
"Array.pop-back works as expected"))
(let-do [arr [1 2 3 4 5 6]
exp [1 2 3]
six (Array.pop-back! &arr)
five (Array.pop-back! &arr)
four (Array.pop-back! &arr)]
(assert-true test
(and* (= &exp &arr)
(= six 6)
(= five 5)
(= four 4))
"Array.pop-back! works as expected"))
(assert-equal test
&[1 2 3 4 5 6 7 8 9]
&(sort (range 9 1 -1))
"sort works as expected")
(let-do [arr [3 2 5]
exp [2 3 5]]
(sort! &arr)
(assert-equal test
&exp
&arr
"sort! works as expected"))
(assert-equal test
&[1 2 3 4 5 6 7 8 9]
&(sorted &[9 2 1 3 7 8 6 5 4])
"sorted works as expected")
(print-test-results test))))

42
test/char.carp Normal file
View File

@ -0,0 +1,42 @@
(use Char)
(load "Test.carp")
(use Test)
(defn main []
(with-test test
(assert-true test
(= \a \a)
"char = works as expected I")
(assert-true test
(= &\a &\a)
"char = works as expected II")
(assert-true test
(/= \a \b)
"char /= works as expected I")
(assert-true test
(/= &\a &\b)
"char /= works as expected II")
(assert-true test
(< \a \b)
"char < works as expected I")
(assert-true test
(< &\a &\b)
"char < works as expected II")
(assert-true test
(> \b \a)
"char > works as expected I")
(assert-true test
(> &\b &\a)
"char > works as expected II")
(assert-equal test
0
(meaning &\0)
"meaning works as expected 0")
(assert-equal test
9
(meaning &\9)
"meaning works as expected 9")
(print-test-results test)
)
)

171
test/heap.carp Normal file
View File

@ -0,0 +1,171 @@
(use Heap)
(load "Test.carp")
(use Test)
(defn main []
(with-test test
(let-do [arr [1 3 4 2 6 1]
exp [1 1 2 3 6 4]]
(MinHeap.heapify! &arr)
(assert-equal test
&exp
&arr
"MinHeap.heapify! works"))
(let-do [arr [1 1 2 3 6 4]
exp [1 1 2 3 6 4 4]]
(MinHeap.push! &arr 4)
(assert-equal test
&exp
&arr
"MinHeap.push! works I"))
(let-do [arr [1 1 2 3 6 4]
exp [0 1 2 1 6 4 3]]
(MinHeap.push! &arr 0)
(assert-equal test
&exp
&arr
"MinHeap.push! works II"))
(let-do [arr [1 1 2 3 6 4]
exp []
one (MinHeap.pop! &arr)
one2 (MinHeap.pop! &arr)
two (MinHeap.pop! &arr)
three (MinHeap.pop! &arr)
four (MinHeap.pop! &arr)
six (MinHeap.pop! &arr)]
(assert-equal test
&exp
&arr
"MinHeap.pop! works as expected"))
(let-do [arr [1 3 4 2 6 1]
exp [6 4 3 2 1 1]]
(MaxHeap.heapify! &arr)
(assert-equal test
&exp
&arr
"MaxHeap.heapify! works"))
; check that push-down-until! ignored the trailing elements (100, 200, 300)
; and considers both children (right child max)
(let-do [arr [3 4 6 2 1 1 100 200 300]
exp [6 4 3 2 1 1 100 200 300]]
(MaxHeap.push-down-until! &arr 0 5)
(assert-equal test
&exp
&arr
"MaxHeap.push-down-until! works I (right)"))
; check that push-down-until! ignored the trailing elements (100, 200, 300)
; and considers both children (left child max)
(let-do [arr [3 6 4 2 1 1 100 200 300]
exp [6 3 4 2 1 1 100 200 300]]
(MaxHeap.push-down-until! &arr 0 5)
(assert-equal test
&exp
&arr
"MaxHeap.push-down-until! works II (left)"))
(let-do [arr [1 3 4 2 6 1]
exp [1 1 2 3 4 6]]
(HeapSort.sort! &arr)
(assert-equal test
&exp
&arr
"HeapSort.sort! works"))
(let-do [res (HeapSort.sort [1 3 4 2 6 1])
exp [1 1 2 3 4 6]]
(assert-equal test
&exp
&res
"HeapSort.sort works"))
(let-do [arr [1 3 4 2 6 1]
exp [1 1 2 3 4 6]
res (HeapSort.sorted &arr)]
(assert-equal test
&exp
&res
"HeapSort.sorted works"))
; Check that HeapSort.sorted does not modify input array
(let-do [arr [1 3 4 2 6 1]
exp [1 1 2 3 4 6]
_ (HeapSort.sorted &arr)]
(assert-equal test
&arr
&[1 3 4 2 6 1]
"HeapSort.sorted does not modify array"))
; walk through HeapSort.sort! step by step
(let-do [arr [1 3 4 2 6 1]
exp [6 4 3 2 1 1]]
(MaxHeap.heapify! &arr)
(assert-equal test
&exp
&arr
"MinHeap.heapify! works"))
(let-do [arr [6 4 3 2 1 1]
exp [1 4 3 2 1 6]]
(Array.swap! &arr 0 (- (Array.length &arr) 1))
(assert-equal test
&exp
&arr
"swap works"))
(let-do [arr [1 4 3 2 1 6]
exp [4 2 3 1 1 6]]
(MaxHeap.push-down-until! &arr 0 (- (Array.length &arr) 1))
(assert-equal test
&exp
&arr
"push down until works"))
(let-do [arr [4 2 3 1 1 6]
exp [1 2 3 1 4 6]]
(Array.swap! &arr 0 (- (Array.length &arr) 2))
(assert-equal test
&exp
&arr
"swap 2 works"))
(let-do [arr [1 2 3 1 4 6]
exp [3 2 1 1 4 6]]
(MaxHeap.push-down-until! &arr 0 (- (Array.length &arr) 2))
(assert-equal test
&exp
&arr
"push down until 2 works"))
(let-do [arr [3 2 1 1 4 6]
exp [1 2 1 3 4 6]]
(Array.swap! &arr 0 (- (Array.length &arr) 3))
(assert-equal test
&exp
&arr
"swap 3 works"))
(let-do [arr [1 2 1 3 4 6]
exp [2 1 1 3 4 6]]
(MaxHeap.push-down-until! &arr 0 (- (Array.length &arr) 3))
(assert-equal test
&exp
&arr
"push down 3 works"))
(let-do [arr [2 1 1 3 4 6]
exp [1 1 2 3 4 6]]
(Array.swap! &arr 0 (- (Array.length &arr) 4))
(assert-equal test
&exp
&arr
"swap 4 works"))
(print-test-results test)))

View File

@ -1,5 +1,6 @@
(load "Test.carp")
(use Array)
(use IO)
(use Int)
(use Float)

101
test/sort.carp Normal file
View File

@ -0,0 +1,101 @@
(use Array)
(load "Test.carp")
(use Test)
(defn main []
(with-test test
(let-do [arr [1 3 4 2 6 1]
exp [1 1 2 3 4 6]]
(Array.sort! &arr)
(assert-equal test
&exp
&arr
"Array.sort! works with integers"))
(let-do [arr [1 3 4 2 6 1]
exp [1 1 2 3 4 6]
res (Array.sorted &arr)]
(assert-equal test
&exp
&res
"Array.sorted works with integers"))
(let-do [res (Array.sort [1 3 4 2 6 1])
exp [1 1 2 3 4 6]]
(assert-equal test
&exp
&res
"Array.sort works with integers"))
(let-do [arr [1.0 0.8 12.4 3.2]
exp [0.8 1.0 3.2 12.4]]
(Array.sort! &arr)
(assert-equal test
&exp
&arr
"Array.sort! works with floats"))
(let-do [arr [1.0 0.8 12.4 3.2]
exp [0.8 1.0 3.2 12.4]
res (Array.sorted &arr)]
(assert-equal test
&exp
&res
"Array.sorted works with floats"))
(let-do [res (Array.sort [1.0 0.8 12.4 3.2])
exp [0.8 1.0 3.2 12.4]]
(assert-equal test
&exp
&res
"Array.sort works with floats"))
(let-do [arr [@"aaac" @"aaaa" @"aaab" @"aaad"]
exp [@"aaaa" @"aaab" @"aaac" @"aaad"]]
(Array.sort! &arr)
(assert-equal test
&exp
&arr
"Array.sort! works with strings"))
(let-do [arr [@"aaac" @"aaaa" @"aaab" @"aaad"]
exp [@"aaaa" @"aaab" @"aaac" @"aaad"]
res (Array.sorted &arr)]
(assert-equal test
&exp
&res
"Array.sorted works with strings"))
(let-do [res (Array.sort [@"aaac" @"aaaa" @"aaab" @"aaad"])
exp [@"aaaa" @"aaab" @"aaac" @"aaad"]]
(assert-equal test
&exp
&res
"Array.sort works with strings"))
(let-do [arr [\d \a \c \b]
exp [\a \b \c \d]]
(Array.sort! &arr)
(assert-equal test
&exp
&arr
"Array.sort! works with chars"))
(let-do [arr [\d \a \c \b]
exp [\a \b \c \d]
res (Array.sorted &arr)]
(assert-equal test
&exp
&res
"Array.sorted works with chars"))
(let-do [res (Array.sort [\d \a \c \b])
exp [\a \b \c \d]]
(assert-equal test
&exp
&res
"Array.sort works with chars"))
(print-test-results test)))

View File

@ -7,10 +7,28 @@
(with-test test
(assert-true test
(= @"hello world" @"hello world")
"string = works as expected")
"string = works as expected I")
(assert-true test
(= "hello world" "hello world")
"string = works as expected II")
(assert-true test
(/= @"hello world" @"bob")
"string /= works as expected")
"string /= works as expected I")
(assert-true test
(/= "hello world" "bob")
"string /= works as expected II")
(assert-true test
(< @"aaaa" @"aaab")
"string < works as expected I")
(assert-true test
(< "aaaa" "aaab")
"string < works as expected II")
(assert-true test
(> @"aaab" @"aaaa")
"string > works as expected I")
(assert-true test
(> "aaab" "aaaa")
"string > works as expected II")
(assert-equal test
"true"
&(str true)