Data update

This commit is contained in:
Ingy döt Net 2023-12-16 21:33:55 -08:00
parent 35bcdeebf8
commit 74c69a0df6
2427 changed files with 31826 additions and 3468 deletions

View file

@ -0,0 +1,66 @@
MODULE RosettaMergeSort;
TYPE Template* = ABSTRACT RECORD END;
(* Abstract Procedures: *)
(* Return TRUE if `front` comes before `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) Before- (front, rear: ANYPTR): BOOLEAN, NEW, ABSTRACT;
(* Return the next element 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` *)
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; (* Initialize the count of elements to 0 *)
WHILE s # NIL DO (* While not at the end of the list *)
INC(n); (* Increment the count of elements *)
s := t.Next(s) (* Move to the next element in the linked list *)
END;
RETURN n (* Return the total number of elements in the linked list *)
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.Before(front, rear) THEN
RETURN t.Set(front, t.Merge(t.Next(front), rear))
ELSE
RETURN t.Set(rear, t.Merge(front, t.Next(rear)))
END
END Merge;
(* 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.Next(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;
BEGIN
IF s = NIL THEN RETURN s 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 *)
END Sort;
END RosettaMergeSort.

View file

@ -0,0 +1,12 @@
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
END;
END RosettaMergeSort.

View file

@ -0,0 +1,85 @@
MODULE RosettaMergeSortUse;
(* Import Modules: *)
IMPORT Sort := RosettaMergeSort, Log := StdLog;
(* Type Definitions: *)
TYPE
(* a linked list node containing an integer and a pointer to the next node *)
List = POINTER TO RECORD
value: INTEGER;
next: List
END;
(* Implement the abstract record type Sort.Template *)
Template = RECORD (Sort.Template) 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;
BEGIN RETURN s(List).next END Next;
(* Set the next pointer of a list node *)
PROCEDURE (IN t: Template) Set (s, next: ANYPTR): ANYPTR;
BEGIN
IF next = NIL THEN
s(List).next := NIL
ELSE
s(List).next := next(List)
END;
RETURN s
END Set;
(* Helper Procedures: *)
(* Prefix a node to a list *)
PROCEDURE Prefix (value: INTEGER; s: List): List;
VAR new: List;
BEGIN
NEW(new); new.value := value; new.next := s; RETURN new
END Prefix;
(* Write a list *)
PROCEDURE Show (s: List);
VAR count: INTEGER;
BEGIN
count := 0;
WHILE s # NIL DO
IF count = 10 THEN
Log.Ln; (* Insert a newline after displaying 10 numbers *)
count := 0
END;
Log.IntForm(s.value, Log.decimal, 4, ' ', Log.hideBase);
s := s.next;
INC(count)
END
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;
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);
Log.String("Before:"); Log.Ln;
Show(s); Log.Ln;
s := t.Sort(s)(List);
Log.String("After:"); Log.Ln;
Show(s); Log.Ln
END Use;
END RosettaMergeSortUse.