Data update
This commit is contained in:
parent
0df55f9f24
commit
aec8ed51b6
1045 changed files with 18889 additions and 2777 deletions
|
|
@ -1,66 +1,57 @@
|
|||
MODULE RosettaMergeSort;
|
||||
|
||||
|
||||
|
||||
TYPE Template* = ABSTRACT RECORD END;
|
||||
|
||||
(* Abstract Procedures: *)
|
||||
|
||||
(* Return TRUE if `front` comes before `rear` in the sorted order, FALSE otherwise *)
|
||||
(* Return TRUE if list item`front` comes before list item `rear` in the sorted order, FALSE otherwise *)
|
||||
(* For the sort to be stable `front` comes before `rear` if they are equal *)
|
||||
PROCEDURE (IN t: Template) Pre- (front, rear: ANYPTR): BOOLEAN, NEW, ABSTRACT;
|
||||
PROCEDURE (IN t: Template) Before- (front, rear: ANYPTR): BOOLEAN, NEW, ABSTRACT;
|
||||
|
||||
(* Return the next element in the list after `s` *)
|
||||
PROCEDURE (IN t: Template) Suc- (s: ANYPTR): ANYPTR, NEW, ABSTRACT;
|
||||
(* Return the next item in the list after `s` *)
|
||||
PROCEDURE (IN t: Template) Next- (s: ANYPTR): ANYPTR, NEW, ABSTRACT;
|
||||
|
||||
(* Update the next pointer of `s` to the value of `next` - Return the modified `s` *)
|
||||
(* Update the next pointer of list item `s` to the value of list `next` - Return the modified `s` *)
|
||||
PROCEDURE (IN t: Template) Set- (s, next: ANYPTR): ANYPTR, NEW, ABSTRACT;
|
||||
|
||||
(* Return the total number of elements in the list starting from `s` *)
|
||||
PROCEDURE (IN t: Template) Length* (s: ANYPTR): INTEGER, NEW;
|
||||
VAR n: INTEGER;
|
||||
BEGIN
|
||||
n := 0;
|
||||
WHILE s # NIL DO
|
||||
INC(n);
|
||||
s := t.Suc(s)
|
||||
END;
|
||||
RETURN n
|
||||
END Length;
|
||||
|
||||
(* Merge sorted lists `front` and `rear` - Return the merged sorted list *)
|
||||
PROCEDURE (IN t: Template) Merge (front, rear: ANYPTR): ANYPTR, NEW;
|
||||
BEGIN
|
||||
IF front = NIL THEN RETURN rear END;
|
||||
IF rear = NIL THEN RETURN front END;
|
||||
IF t.Pre(front, rear) THEN
|
||||
RETURN t.Set(front, t.Merge(t.Suc(front), rear))
|
||||
IF t.Before(front, rear) THEN
|
||||
RETURN t.Set(front, t.Merge(t.Next(front), rear))
|
||||
ELSE
|
||||
RETURN t.Set(rear, t.Merge(front, t.Suc(rear)))
|
||||
RETURN t.Set(rear, t.Merge(front, t.Next(rear)))
|
||||
END
|
||||
END Merge;
|
||||
|
||||
(* Sort the first `n` items in the list `s` and drop them from `s` *)
|
||||
(* Return the sorted `n` items *)
|
||||
PROCEDURE (IN t: Template) TakeSort (n: INTEGER; VAR s: ANYPTR): ANYPTR, NEW;
|
||||
VAR k: INTEGER; front, rear: ANYPTR;
|
||||
BEGIN
|
||||
IF n = 1 THEN (* base case: if `n` is 1, return the head of `s` *)
|
||||
front := s; s := t.Next(s); RETURN t.Set(front, NIL)
|
||||
END;
|
||||
(* Divide the first `n` items of `s` into two sorted parts *)
|
||||
k := n DIV 2;
|
||||
front := t.TakeSort(k, s);
|
||||
rear := t.TakeSort(n - k, s);
|
||||
RETURN t.Merge(front, rear) (* Return the merged parts *)
|
||||
END TakeSort;
|
||||
|
||||
(* Perform a merge sort on `s` - Return the sorted list *)
|
||||
PROCEDURE (IN t: Template) Sort* (s: ANYPTR): ANYPTR, NEW;
|
||||
|
||||
(* Take a positive integer `n` and an occupied list `s` *)
|
||||
(* Sort the initial segment of `s` of length `n` and return the result *)
|
||||
(* Update `s` to the list which remain when the first `n` elements are removed *)
|
||||
PROCEDURE TakeSort (n: INTEGER; VAR s: ANYPTR): ANYPTR;
|
||||
VAR k: INTEGER; h, front, rear: ANYPTR;
|
||||
BEGIN
|
||||
IF n = 1 THEN (* base case: if n = 1, return the head of `s` *)
|
||||
h := s; s := t.Suc(s); RETURN t.Set(h, NIL)
|
||||
END;
|
||||
(* Divide the first n elements of the list into two sorted halves *)
|
||||
k := n DIV 2;
|
||||
front := TakeSort(k, s);
|
||||
rear := TakeSort(n - k, s);
|
||||
RETURN t.Merge(front, rear) (* Merge and return the halves *)
|
||||
END TakeSort;
|
||||
|
||||
VAR n: INTEGER; r: ANYPTR;
|
||||
BEGIN
|
||||
IF s = NIL THEN RETURN NIL END; (* If `s` in empty, return `s` *)
|
||||
(* Calculate the length of the list and call TakeSort *)
|
||||
RETURN TakeSort(t.Length(s), s) (* Return the sorted list *)
|
||||
IF s = NIL THEN RETURN s END; (* If `s` is empty, return `s` *)
|
||||
(* Count of items in `s` *)
|
||||
n := 0; r := s; (* Initialize the item to be counted to `s` *)
|
||||
WHILE r # NIL DO INC(n); r := t.Next(r) END;
|
||||
RETURN t.TakeSort(n, s) (* Return the sorted list *)
|
||||
END Sort;
|
||||
|
||||
END RosettaMergeSort.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ DEFINITION RosettaMergeSort;
|
|||
TYPE
|
||||
Template = ABSTRACT RECORD
|
||||
(IN t: Template) Before- (front, rear: ANYPTR): BOOLEAN, NEW, ABSTRACT;
|
||||
(IN t: Template) Length (s: ANYPTR): INTEGER, NEW;
|
||||
(IN t: Template) Next- (s: ANYPTR): ANYPTR, NEW, ABSTRACT;
|
||||
(IN t: Template) Set- (s, next: ANYPTR): ANYPTR, NEW, ABSTRACT;
|
||||
(IN t: Template) Sort (s: ANYPTR): ANYPTR, NEW
|
||||
|
|
|
|||
|
|
@ -1,87 +1,93 @@
|
|||
MODULE RosettaMergeSortUse;
|
||||
|
||||
(* Import Modules: *)
|
||||
|
||||
|
||||
IMPORT Sort := RosettaMergeSort, Out;
|
||||
|
||||
(* Type Definitions: *)
|
||||
TYPE
|
||||
(* a linked list node containing an integer and a pointer to the next node *)
|
||||
(* a character list *)
|
||||
List = POINTER TO RECORD
|
||||
value: INTEGER;
|
||||
value: CHAR;
|
||||
next: List
|
||||
END;
|
||||
|
||||
(* Implement the abstract record type Sort.Template *)
|
||||
Template = RECORD (Sort.Template) END;
|
||||
Order = ABSTRACT RECORD (Sort.Template) END;
|
||||
Asc = RECORD (Order) END;
|
||||
Bad = RECORD (Order) END;
|
||||
Desc = RECORD (Order) END;
|
||||
|
||||
(* Abstract Procedure Implementations: *)
|
||||
|
||||
(* Compare integers in the list nodes to determine their order in the sorted list *)
|
||||
(* For the sort to be stable `front` comes before `rear` if they are equal *)
|
||||
PROCEDURE (IN t: Template) Before (front, rear: ANYPTR): BOOLEAN;
|
||||
BEGIN RETURN front(List).value <= rear(List).value END Before;
|
||||
|
||||
(* Return the next node in the linked list *)
|
||||
PROCEDURE (IN t: Template) Next (s: ANYPTR): ANYPTR;
|
||||
PROCEDURE (IN t: Order) Next (s: ANYPTR): ANYPTR;
|
||||
BEGIN RETURN s(List).next END Next;
|
||||
|
||||
(* Set the next pointer of a list node *)
|
||||
PROCEDURE (IN t: Template) Set (s, next: ANYPTR): ANYPTR;
|
||||
(* Set the next pointer of list item `s` to `next` - Return the updated `s` *)
|
||||
PROCEDURE (IN t: Order) Set (s, next: ANYPTR): ANYPTR;
|
||||
BEGIN
|
||||
IF next = NIL THEN
|
||||
s(List).next := NIL
|
||||
ELSE
|
||||
s(List).next := next(List)
|
||||
END;
|
||||
IF next = NIL THEN s(List).next := NIL
|
||||
ELSE s(List).next := next(List) END;
|
||||
RETURN s
|
||||
END Set;
|
||||
|
||||
(* Ignoring case, compare characters to determine ascending order in the sorted list *)
|
||||
(* For the sort to be stable `front` comes before `rear` if they are equal *)
|
||||
PROCEDURE (IN t: Asc) Before (front, rear: ANYPTR): BOOLEAN;
|
||||
BEGIN
|
||||
RETURN CAP(front(List).value) <= CAP(rear(List).value)
|
||||
END Before;
|
||||
|
||||
(* Unstable sort!!! *)
|
||||
PROCEDURE (IN t: Bad) Before (front, rear: ANYPTR): BOOLEAN;
|
||||
BEGIN
|
||||
RETURN CAP(front(List).value) < CAP(rear(List).value)
|
||||
END Before;
|
||||
|
||||
(* Ignoring case, compare characters to determine descending order in the sorted list *)
|
||||
(* For the sort to be stable `front` comes before `rear` if they are equal *)
|
||||
PROCEDURE (IN t: Desc) Before (front, rear: ANYPTR): BOOLEAN;
|
||||
BEGIN
|
||||
RETURN CAP(front(List).value) >= CAP(rear(List).value)
|
||||
END Before;
|
||||
|
||||
(* Helper Procedures: *)
|
||||
|
||||
(* Prefix a node to a list *)
|
||||
PROCEDURE Prefix (value: INTEGER; s: List): List;
|
||||
VAR new: List;
|
||||
(* Takes a string and converts it into a linked list of characters *)
|
||||
PROCEDURE Explode (str: ARRAY OF CHAR): List;
|
||||
VAR i: INTEGER; h, t: List;
|
||||
BEGIN
|
||||
NEW(new); new.value := value; new.next := s; RETURN new
|
||||
END Prefix;
|
||||
i := LEN(str$);
|
||||
WHILE i # 0 DO
|
||||
t := h; NEW(h);
|
||||
DEC(i); h.value := str[i];
|
||||
h.next := t
|
||||
END;
|
||||
RETURN h
|
||||
END Explode;
|
||||
|
||||
(* Write a list *)
|
||||
(* Outputs the characters in a linked list as a string in quotes *)
|
||||
PROCEDURE Show (s: List);
|
||||
VAR count: INTEGER;
|
||||
VAR i: INTEGER;
|
||||
BEGIN
|
||||
count := 0;
|
||||
WHILE s # NIL DO
|
||||
IF count = 10 THEN
|
||||
Out.Ln; (* Insert a newline after displaying 10 numbers *)
|
||||
count := 0
|
||||
END;
|
||||
Out.Int(s.value, 4);
|
||||
s := s.next;
|
||||
INC(count)
|
||||
END
|
||||
Out.Char('"');
|
||||
WHILE s # NIL DO Out.Char(s.value); s := s.next END;
|
||||
Out.Char('"')
|
||||
END Show;
|
||||
|
||||
(* Main Procedure: *)
|
||||
PROCEDURE Use*;
|
||||
VAR t: Template; s: List;
|
||||
(* Calls Prefix to add integers to the beginning of the list `s` *)
|
||||
PROCEDURE b (value: INTEGER); BEGIN s := Prefix(value, s) END b;
|
||||
VAR a: Asc; b: Bad; d: Desc; s: List;
|
||||
BEGIN
|
||||
(* Use the `b` procedure to add the integers to the list `s` *)
|
||||
b(663); b(085); b(534); b(066); b(038); b(323); b(727); b(651);
|
||||
b(625); b(706); b(149); b(956); b(804); b(626); b(106); b(230);
|
||||
b(314); b(249); b(758); b(236); b(775); b(399); b(701); b(296);
|
||||
b(770); b(380); b(403); b(760); b(159); b(551); b(153); b(297);
|
||||
b(130); b(866); b(937); b(226); b(298); b(029); b(149); b(381);
|
||||
b(590); b(255); b(101); b(485); b(801); b(223); b(645); b(458);
|
||||
b(068); b(683);
|
||||
Out.String("Before:"); Out.Ln;
|
||||
Show(s); Out.Ln;
|
||||
s := t.Sort(s)(List);
|
||||
Out.String("After:"); Out.Ln;
|
||||
Show(s); Out.Ln
|
||||
s := Explode("A quick brown fox jumps over the lazy dog");
|
||||
Out.String("Before:"); Out.Ln; Show(s); Out.Ln;
|
||||
s := a.Sort(s)(List); (* Ascending stable sort *)
|
||||
Out.String("After Asc:"); Out.Ln; Show(s); Out.Ln;
|
||||
s := b.Sort(s)(List); (* Ascending unstable sort *)
|
||||
Out.String("After Bad:"); Out.Ln; Show(s); Out.Ln;
|
||||
s := d.Sort(s)(List); (* Descending stable sort *)
|
||||
Out.String("After Desc:"); Out.Ln; Show(s); Out.Ln
|
||||
END Use;
|
||||
|
||||
END RosettaMergeSortUse.Use
|
||||
|
||||
END RosettaMergeSortUse.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue